之前,我总以为挖矿就是把Nonce值都试一遍,然后用SHA256算法算一遍。后面发现自己把东西看得太简单,我尝试尝试讲讲比特币的挖矿算法的流程。
区块头
首先挖矿算法的目标对象只是区块中的区块头,共80个字节,我们来看看区块头有哪些字段:
注意:
- Target(难度目标):该区块工作量证明算法的难度目标
- 其实区块头不包括Padding+Length部分,这个部分只是为了满足SHA256算法的使用条件。
- 字段的不同颜色代表该字段内容变化频率。绿色:像Version、Target、以及Padding+Length(有约定俗成的标准)这些内容相对出块的速度来说变化频率很低;黄色:像hashPreBlock、hashMerkleRoot、Timestamp这些几乎与出块的速度一致的频率;红色:像Nonce这个的变化频率远远快与出块速率。
挖矿算法流程
为什么要做双重hash(SHA256(1)后还来个SHA256(2))
The SHA256 hashing algorithm,like all hashes constructed using the Merkle-damgård paradigm,is vulnerable to this attack. The length extension attack allows an attacker who kNows SHA256(x) to calculate SHA256(x||y) without the kNowledge of x. Although it is unclear how length extension attacks may make the Bitcoin protocol susceptible to harm,it is believed that Satoshi Nakamoto decided to play it safe and include the double hashing in his design.
Another explanation [6] for this double hashing is that 128 rounds of SHA256 may remain safe longer if in the far future,a practical pre-image or a partial pre-image attack was found against SHA256.
挖矿算法实现以及编码方式
https://en.bitcoin.it/wiki/Block_hashing_algorithm
Bitcoin mining uses the hashcash proof of work function; the hashcash algorithm requires the following parameters: a service string,a nonce,and a counter. In bitcoin the service string is encoded in the block header data structure,and includes a version field,the hash of the prevIoUs block,the root hash of the merkle tree of all transactions in the block,the current time,and the difficulty. Bitcoin stores the nonce in the extraNonce field which is part of the coinbase transaction,which is stored as the left most leaf node in the merkle tree (the coinbase is the special first transaction in the block). The counter parameter is small at 32-bits so each time it wraps the extraNonce field must be incremented (or otherwise changed) to avoid repeating work. The basics of the hashcash algorithm are quite easy to understand and it is described in more detail here. When mining bitcoin,the hashcash algorithm repeatedly hashes the block header while incrementing the counter & extraNonce fields. Incrementing the extraNonce field entails recomputing the merkle tree,as the coinbase transaction is the left most leaf node. The block is also occasionally updated as you are working on it.
A block header contains these fields:
Field | Purpose | Updated when... | Size (Bytes) | |||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
Version | Block version number | You upgrade the software and it specifies a new version | 4 | |||||||||
hashPrevBlock | 256-bit hash of the prevIoUs block header | A new block comes in | 32 | |||||||||
hashMerkleRoot | 256-bit hash based on all of the transactions in the block | A transaction is accepted | Time | Current timestamp as seconds since 1970-01-01T00:00 UTC | Every few seconds | Bits | Current target in compact format | The difficulty is adjusted | Nonce | 32-bit number (starts at 0) | A hash is tried (increments) | 4 |
The body of the block contains the transactions. These are hashed only indirectly through the Merkle root. Because transactions aren't hashed directly,hashing a block with 1 transaction takes exactly the same amount of effort as hashing a block with 10,000 transactions.
The compact format of target is a special kind of floating-point encoding using 3 bytes mantissa,the leading byte as exponent (where only the 5 lowest bits are used) and its base is 256. Most of these fields will be the same for all users. There might be some minor variation in the timestamps. The nonce will usually be different,but it increases in a strictly linear way. "Nonce" starts at 0 and is incremented for each hash. Whenever Nonce overflows (which it does frequently),the extraNonce portion of the generation transaction is incremented,which changes the Merkle root.
Moreover,it is extremely unlikely for two people to have the same Merkle root because the first transaction in your block is a generation "sent" to one of your unique Bitcoin addresses. Since your block is different from everyone else's blocks,you are (nearly) guaranteed to produce different hashes. Every hash you calculate has the same chance of winning as every other hash calculated by the network.
Bitcoin uses: SHA256(SHA256(Block_Header)) but you have to be careful about byte-order.
For example,this python code will calculate the hash of the block with the smallest hash as of June 2011, Block 125552. The header is built from the six fields described above,concatenated together as little-endian values in hex notation:
>>> 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[::-1].encode('00000000000000001e8d6829a8a21adc5d38d0a473b144b6765798e61f98bd1d'
Endianess
Note that the hash,which is a 256-bit number,has lots of leading zero bytes when stored or printed as a big-endian hexadecimal constant,but it has trailing zero bytes when stored or printed in little-endian. For example,if interpreted as a string and the lowest (or start of) the string address keeps lowest significant byte,it is little-endian.
The output of blockexplorer displays the hash values as big-endian numbers; notation for numbers is usual (leading digits are the most significant digits read from left to right).
For another example, here is a version in plain C without any optimization,threading or error checking.
Here is the same example in plain PHP without any optimization.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。