bitcoin: 计算 Block Hash

文章来自简书

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_a...
http://www.righto.com/2014/02/bitcoin-mini...
https://en.bitcoin.it/wiki/Difficulty
https://bitcoin.org/en/developer-guide#ter...

本作品采用《CC 协议》,转载必须注明作者和本文链接
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!