主页 > 冷钱包imtoken > 比特币挖矿算法

比特币挖矿算法

冷钱包imtoken 2023-04-13 06:59:07

之前一直认为挖矿就是把所有的Nonce值都试一遍,然后用SHA256算法计算出来。 后来发现自己把事情看得太简单了,于是试着讲讲比特币挖矿算法的过程。

块头

首先,挖矿算法的目标对象只是区块中的区块头,一共80字节。 我们来看看区块头的字段:

注意:

Target(难度目标):这个区块的工作量证明算法的难度目标其实不包括区块头的Padding+Length部分,只是为了满足SHA256算法的使用条件。 字段的不同颜色代表字段内容的变化频率。 Green:相对于出块速度,Version、Target、Padding+Length(有惯例标准)等内容变化相对较少; 黄色:hashPreBlock、hashMerkleRoot、Timestamp的频率与出块速度几乎一致; 红色:像Nonce这样的变化频率比出块率快很多。 为什么挖矿算法过程需要双重哈希(SHA256(1)后跟SHA256(2))

比特币挖矿的算法_比特币挖矿网站_比特币挖矿算法过程

与使用 Merkle-Damgård 范式构建的所有哈希一样,SHA256 哈希算法容易受到这种攻击。 长度扩展攻击允许知道 SHA256(x) 的攻击者在不知道 x 的情况下计算 SHA256(x||y)。 虽然还不清楚长度扩展攻击如何使比特币协议容易受到伤害,但据信中本聪决定谨慎行事比特币挖矿算法过程,并在他的设计中加入了双重哈希。

对于这种双重散列的另一种解释 [6] 是,如果在遥远的将来发现针对 SHA256 的实际原像或部分原像攻击,则 128 轮 SHA256 可能会保持更长时间的安全。

挖掘算法实现及编码方法

比特币挖矿网站_比特币挖矿的算法_比特币挖矿算法过程

比特币挖矿使用 hashcashproof of work 函数; hashcash 算法需要以下参数:服务字符串、随机数和计数器。 在比特币中,服务字符串被编码在区块头数据结构中,包括版本字段、前一个区块的哈希、区块中所有交易的默克尔树的根哈希、当前时间和难度。 比特币将 nonce 存储在 extraNonce 字段中,该字段是 coinbase 交易的一部分,它存储为 merkle 树中最左边的叶节点(coinbase 是区块中特殊的第一笔交易)。

counter 参数很小,只有 32 位,因此每次它包装 extraNonce 字段时都必须递增(或以其他方式更改)以避免重复工作。 hashcash 算法的基础很容易理解,这里有更详细的描述。 在挖掘比特币时,hashcash 算法在递增 counter 和 extraNonce 字段的同时重复对块头进行哈希处理。 增加 extraNonce 字段需要重新计算 merkle 树,因为 coinbase 交易是最左边的叶节点。 该块也会在您处理它时偶尔更新。

区块头包含以下字段:

比特币挖矿算法过程_比特币挖矿的算法_比特币挖矿网站

FieldPurposeUpdated when...Size (Bytes)VersionBlock version number你升级了软件,它指定了一个新版本4hashPrevBlock256-bit hash of the previous block headerA new block comes in32hashMerkleRoot256-bit hash based on all of the transactions in the block2Timeampptas time is a Curraction seconds自1970-01-01T00:00 UTC每隔几秒4BitsCurrenttargetin compact format难度调整4Nonce32-bit number (starts at 0)A hash is tried (increments)4

块的主体包含交易。 这些仅通过 Merkle 根间接散列。 因为交易不是直接散列的,所以用 1 个交易散列一个块与散列一个包含 10,000 个交易的块所花费的精力完全相同。

target 的紧凑格式是一种特殊的浮点编码,使用 3 个字节的尾数,前导字节作为指数(仅使用最低 5 位),其基数为 256。这些字段中的大多数对于所有人都是相同的用户。 时间戳可能会有一些细微的变化。 随机数通常会有所不同,但它以严格线性的方式增加。 “Nonce”从 0 开始,并针对每个哈希递增。 每当 Nonce 溢出(它经常发生),生成交易的 extraNonce 部分就会增加,这会改变 Merkle 根。

比特币挖矿的算法_比特币挖矿算法过程_比特币挖矿网站

此外,两个人极不可能拥有相同的 Merkle 根,因为您区块中的第一笔交易是一代“发送”到您的唯一比特币地址之一。 由于您的区块与其他人的区块不同,您(几乎)可以保证产生不同的哈希值。 您计算的每个哈希与网络计算的每个其他哈希都有相同的获胜机会。

比特币使用:SHA256(SHA256(Block_Header)) 但你必须注意字节顺序。

例如比特币挖矿算法过程,这段 Python 代码将计算截至 2011 年 6 月具有最小哈希值的区块的哈希值,区块 125552。头部由上述六个字段构建,以十六进制表示法连接在一起作为小端值:

比特币挖矿算法过程_比特币挖矿的算法_比特币挖矿网站

>>> import hashlib>>> header_hex = ("01000000" + "81cd02ab7e569e8bcd9317e2fe99f2de44d49ab2b8851ba4a308000000000000" + "e320b6c2fffc8d750423db8b1eb942ae710e951ed797f7affc8892b0f1fc122b" + "c7f5d74d" + "f2b9441a" + "42a14695")>>> header_bin = header_hex.decode('hex')>> > hash = hashlib.sha256(hashlib.sha256(header_bin).digest()).digest() >>> hash.encode('hex_codec')'1dbd981fe6985776b644b173a4d0385ddc1aa2a829688d1e0000000000000000'>>>hash[code(' hex_codec')'000000000000000001e8d6829a8a21adc5d38d0a473b144b6765798e61f98bd1d'字节顺序

请注意,作为 256 位数字的散列在作为大端十六进制常量存储或打印时有很多前导零字节,但在小端存储或打印时它有尾随零字节。 例如,如果解释为字符串并且字符串地址的最低(或开头)保持最低有效字节,则它是小端。

区块浏览器的输出将哈希值显示为大端数字; 数字的符号是常用的(前导数字是从左到右读取的最重要的数字)。

再举一个例子,这是一个纯 C 版本,没有任何优化、线程或错误检查。

这是未进行任何优化的纯 PHP 中的相同示例。

类别:技术