美文网首页漫谈区块链
bitcoin:计算Block Hash

bitcoin:计算Block Hash

作者: 已不再更新_转移到qiita | 来源:发表于2017-10-26 12:07 被阅读5790次

    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都要重新计算.

    字节序

    python处理字节序


    参考:

    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

    相关文章

      网友评论

        本文标题:bitcoin:计算Block Hash

        本文链接:https://www.haomeiwen.com/subject/kouvlxtx.html