bitcoin的创世块的数据是已 hard code的形式写在源码里,
之后的block hash都是通过固定的方式计算出来的. 怎么计算出来呢?
每一个block都有:
version
即网络节点的版本号
prev_block
前一个块的hash,创世块没有,以后的块都有
mrkl_root
, 是 Merkle tree, 即默克尔树
time
即时间戳,当前时间
bits
网络的难度
nonce
随机数
这个 nonce 就是 Pow 要计算的随机量, 区别是要计算2次hash.
先把 version prev_block mrkl_root time bits nonce
当做字符串合并到一起, 得到结果 result
. 得到 result
后, 做2次 sha256运算, 得到 hash
, 再然后hash
做大小端转换, 最后的结果就是这个block的hash.
不过 version time bits nonce
要转换为 unsigned long型小字端,
prev_block mrkl_root
要转换为16进制并大小端转换, 这一步确实很麻烦.
测试下 height=1
的 block hash值
curl https://blockchain.info/rawblock/00000000839a8e6886ab5951d76f411475428afc90947ee320161bbf18eb6048
{
hash: "00000000839a8e6886ab5951d76f411475428afc90947ee320161bbf18eb6048",
ver: 1,
prev_block: "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f",
mrkl_root: "0e3e2357e806b6cdb1f70b54c3a3a17b6714ee1f0e68bebb44a74b1efd512098",
time: 1231469665,
bits: 486604799,
fee: 0,
nonce: 2573394689,
n_tx: 1,
size: 215,
block_index: 14850,
main_chain: true,
height: 1
......
}
python script
import hashlib
import struct
ver = 1
prev_block = "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f"
mrkl_root = "0e3e2357e806b6cdb1f70b54c3a3a17b6714ee1f0e68bebb44a74b1efd512098"
time = 1231469665
bits = 486604799
nonce = 2573394689
hex_str = struct.pack("<L", ver) + prev_block.decode('hex')[::-1] +\
mrkl_root.decode('hex')[::-1] + struct.pack("<LLL", time, bits, nonce)
hash_str = hashlib.sha256(hashlib.sha256(hex_str).digest()).digest()
# 这就是bitcoin矿机的工作 , 找到一个合适的nonce
# 使得做2次sha256运算的结果符合某个条件
block_hash = hash_str[::-1].encode('hex_codec')
挖矿做的工作
在一个block的结构中, version prev_block mrkl_root time bits
都是很容易计算的. 只有 nonce
这个随机数不确定.
bitcoin的 pow 就是 找到一个合适的 nonce
, 使得 version prev_block mrkl_root time bits nonce
合并的结果 reuslt
,再经过2次sha256计算, 达到一个符合bitcoin网络难度的数值. bitcoin的网络难度通过 bits计算, 难度即最后计算的hash的前n位是零.
每一个block hash的计算, 都包含了prev_block_hash,这也是链的体现, 增加了攻击bitcoin的难度. 如果有人改了一个block的hash, 这个块之后的所有的块hash都要重新计算.
字节序
参考:
https://en.bitcoin.it/wiki/Block_hashing_algorithm
http://www.righto.com/2014/02/bitcoin-mining-hard-way-algorithms.html
https://en.bitcoin.it/wiki/Difficulty
https://bitcoin.org/en/developer-guide#term-merkle-tree