Bitcoin: 计算Merkle Tree

计算Block Hash中,接触到一个变量mrkl_root,即Merkle Tree,默克尔树。

Hash_Tree

                   A               A
                  /  \            /   \
                B     C         B       C
               / \    |        / \     / \
              D   E   F       D   E   F   G
             / \ / \ / \     / \ / \ / \ / \
             1 2 3 4 5 6     1 2 3 4 5 6 7 8

我们计算下 Height 100008的mrkl_root.

这个block只有2个tx:

de2c2e8628ab837ceff3de0217083d9d5feb71f758a5d083ada0b33a36e1b30e
89878bfd69fba52876e5217faec126fc6a20b1845865d4038c12f03200793f48

计算

import hashlib

def hash256(s):
  return hashlib.new('sha256', s).digest()

def dhash256(s):
  return hash256(hash256(s))

tx1="de2c2e8628ab837ceff3de0217083d9d5feb71f758a5d083ada0b33a36e1b30e".decode('hex')[::-1]
tx2="89878bfd69fba52876e5217faec126fc6a20b1845865d4038c12f03200793f48".decode('hex')[::-1]

mrkl_tree = dhash256(tx1+tx2)
result=mrkl_tree[::-1].encode('hex')

print result

result 是 7a059188283323a2ef0e02dd9f8ba1ac550f94646290d0a52a586e5426c956c5

而这个block的mrkl_root呢?

curl https://webbtc.com/block/000000000002dfb177c4acd494b3dd73b9abece24df11c62bb614a8c6c5665e2.json

mrkl_tree: [
"de2c2e8628ab837ceff3de0217083d9d5feb71f758a5d083ada0b33a36e1b30e",
"89878bfd69fba52876e5217faec126fc6a20b1845865d4038c12f03200793f48",
"7a059188283323a2ef0e02dd9f8ba1ac550f94646290d0a52a586e5426c956c5"
]

计算正确, 最需要注意的是大小端的数据转换

如何做大小端数据转换 , 请看 https://www.jianshu.com/p/7623cec7620a

一步步计算 merkle Tree

计算block高度 123456的merkle tree

import hashlib
 
def hash256(s):
  return hashlib.new('sha256', s).digest()
 
def dhash256(s):
  return hash256(hash256(s))
 
tx1="5b75086dafeede555fc8f9a810d8b10df57c46f9f176ccc3dd8d2fa20edd685b".decode('hex')[::-1]
tx2="e3d0425ab346dd5b76f44c222a4bb5d16640a4247050ef82462ab17e229c83b4".decode('hex')[::-1]
tx3="137d247eca8b99dee58e1e9232014183a5c5a9e338001a0109df32794cdcc92e".decode('hex')[::-1]
tx4="5fd167f7b8c417e59106ef5acfe181b09d71b8353a61a55a2f01aa266af5412d".decode('hex')[::-1]
tx5="60925f1948b71f429d514ead7ae7391e0edf965bf5a60331398dae24c6964774".decode('hex')[::-1]
tx6="d4d5fc1529487527e9873256934dfb1e4cdcb39f4c0509577ca19bfad6c5d28f".decode('hex')[::-1]
tx7="7b29d65e5018c56a33652085dbb13f2df39a1a9942bfe1f7e78e97919a6bdea2".decode('hex')[::-1]
tx8="0b89e120efd0a4674c127a76ff5f7590ca304e6a064fbc51adffbd7ce3a3deef".decode('hex')[::-1]
tx9="603f2044da9656084174cfb5812feaf510f862d3addcf70cacce3dc55dab446e".decode('hex')[::-1]
tx10="9a4ed892b43a4df916a7a1213b78e83cd83f5695f635d535c94b2b65ffb144d3".decode('hex')[::-1]
tx11="dda726e3dad9504dce5098dfab5064ecd4a7650bfe854bb2606da3152b60e427".decode('hex')[::-1]
tx12="e46ea8b4d68719b65ead930f07f1f3804cb3701014f8e6d76c4bdbc390893b94".decode('hex')[::-1]
tx13="864a102aeedf53dd9b2baab4eeb898c5083fde6141113e0606b664c41fe15e1f".decode('hex')[::-1]
 
mrkl_tree1 = dhash256(tx1+tx2)
mrkl_tree2 = dhash256(tx3+tx4)
mrkl_tree3 = dhash256(tx5+tx6)
mrkl_tree4 = dhash256(tx7+tx8)
mrkl_tree5 = dhash256(tx9+tx10)
mrkl_tree6 = dhash256(tx11+tx12)
mrkl_tree7 = dhash256(tx13+ tx13) #奇数要重复相加
 
mrkl_tree1_1 = dhash256(mrkl_tree1 + mrkl_tree2)
mrkl_tree2_2 = dhash256(mrkl_tree3 + mrkl_tree4)
mrkl_tree3_3 = dhash256(mrkl_tree5 + mrkl_tree6)
mrkl_tree4_4 = dhash256(mrkl_tree7 + mrkl_tree7)  #奇数个
 
 
mrkl_tree1_1_1 = dhash256(mrkl_tree1_1 + mrkl_tree2_2 )
mrkl_tree2_2_2 = dhash256(mrkl_tree3_3 + mrkl_tree4_4 )
 
result = dhash256(mrkl_tree1_1_1 + mrkl_tree2_2_2 )
 
print("0e60651a9934e8f0decd1c5fde39309e48fca0cd1c84a21ddfde95033762d86c", "ok")
print result[::-1].encode('hex')

通用代码

#coding: utf-8

import hashlib

def merkle(hashList):
    if len(hashList) == 1:
        return hashList[0]

    newHashList = []

    # Process pairs. For odd length, the last is skipped

    for i in range(0, len(hashList) - 1, 2):
        newHashList.append(dhash256(hashList[i], hashList[i + 1]))

    if len(hashList) % 2 == 1:  # odd, hash last item twice
        newHashList.append(dhash256(hashList[-1], hashList[-1]))
    return merkle(newHashList)


def dhash256(a, b): # a/b 大小端转换后的数据
    # due to big-endian / little-endian nonsense
    concat = a + b
    temp = hashlib.sha256(concat).digest()
    h = hashlib.sha256(temp).digest()
    return h


#高度 123456
#https://btc.com/0000000000002917ed80650c6174aac8dfc46f5fe36480aaef682ff6cd83c3ca
txHashes = [
    '5b75086dafeede555fc8f9a810d8b10df57c46f9f176ccc3dd8d2fa20edd685b'.decode('hex')[::-1],
    'e3d0425ab346dd5b76f44c222a4bb5d16640a4247050ef82462ab17e229c83b4'.decode('hex')[::-1],
    '137d247eca8b99dee58e1e9232014183a5c5a9e338001a0109df32794cdcc92e'.decode('hex')[::-1],
    '5fd167f7b8c417e59106ef5acfe181b09d71b8353a61a55a2f01aa266af5412d'.decode('hex')[::-1],
    '60925f1948b71f429d514ead7ae7391e0edf965bf5a60331398dae24c6964774'.decode('hex')[::-1],
    'd4d5fc1529487527e9873256934dfb1e4cdcb39f4c0509577ca19bfad6c5d28f'.decode('hex')[::-1],
    '7b29d65e5018c56a33652085dbb13f2df39a1a9942bfe1f7e78e97919a6bdea2'.decode('hex')[::-1],
    '0b89e120efd0a4674c127a76ff5f7590ca304e6a064fbc51adffbd7ce3a3deef'.decode('hex')[::-1],
    '603f2044da9656084174cfb5812feaf510f862d3addcf70cacce3dc55dab446e'.decode('hex')[::-1],
    '9a4ed892b43a4df916a7a1213b78e83cd83f5695f635d535c94b2b65ffb144d3'.decode('hex')[::-1],
    'dda726e3dad9504dce5098dfab5064ecd4a7650bfe854bb2606da3152b60e427'.decode('hex')[::-1],
    'e46ea8b4d68719b65ead930f07f1f3804cb3701014f8e6d76c4bdbc390893b94'.decode('hex')[::-1],
    '864a102aeedf53dd9b2baab4eeb898c5083fde6141113e0606b664c41fe15e1f'.decode('hex')[::-1],
    ]

result = merkle(txHashes)
print(result[::-1].encode('hex'))


参考:
merkle-root-bitcoin-step-by-step
https://gist.github.com/shirriff/c9fb5d98e6da79d9a772
http://pythonfiddle.com/merkle-root-bitcoin/
http://www.cnblogs.com/fengzhiwu/p/5524324.html
https://en.wikipedia.org/wiki/Merkle_tree
http://bittorrent.org/beps/bep_0030.html

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,847评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,208评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,587评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,942评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,332评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,587评论 1 218
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,853评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,568评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,273评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,542评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,033评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,373评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,031评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,073评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,830评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,628评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,537评论 2 269

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,100评论 18 139
  • 【中文版】以太坊白皮书 翻译:少平、 Seven当中本聪在 2009 年 1 月启动比特币区块链时,他同时向世界引...
    __Seven__阅读 4,049评论 0 10
  • 大部分的后端会很很鄙视前端。我也不知道为什么,可能大部分人都会觉得脚本语言根本不算语言。 大多人 会叫我们切图仔,...
    小黑的眼阅读 3,253评论 0 15
  • 转自网络 哈佛推荐20个快乐的习惯,与君共勉! 2016年2月26日创想者学院全栈UI 设计师新班开课 1/20 ...
    张安松阅读 337评论 0 1
  • 每个爱到骨子里的人,想必都有自己的快乐和伤悲。 爱上一个人,我想每一个人都是会愿意为他放下所有的防备!不...
    小馨馨的小世界阅读 1,068评论 2 8