一棵叫默克尔的神奇之树

上次的文章我们直接拆解了一个区块数据,用最朴素的手术刀把它赤裸裸地剥开窥探。虽然说的是区块数据,但从更高层面上说,这也是计算机保存数据的方式。

我们了解了区块数据是怎么存储的,它都有哪些数据项,看到了那个coinbase交易 —— 矿工自己给自己发币,看到了普通的交易——所谓的UTXO(Unspent Transaction Output),如何用输入输出的方式实现了海量交易帐本的记帐方式。

其实上次的文章,文章内容写得不是那么普及。但让我感动是,有好几位同学,前来说想要收藏那张图片。还有一位传统行业年龄较长的大哥,他说看了好多遍,似乎看懂了。为他们的精神点赞。这也增加了我继续写下去的动力。

还有几个数据项,如 “mrkl_root”, ” scriptPubKey”, “scriptSig”等,它们也是比特币工作的重要部分,很有必要说一下。本文先说一下mrkl_root、mrkl_tree , 默克尔树。

这个词看起来很晦涩,但千万不要被吓到。计算机其实是一门工程学科,工程学我认为是一门关于如何做事的学科,即如何更好地做事,使之达到最优。很多知识都没有看起来的那么难懂,看起来难懂的,只要换种说法,很快就能明白。
这个 merkle root 也是这样,它的含义简单的很。

所以从这个层面来理解,我们不禁要问,它是用来干什么的,解决了什么?弄懂了这个问题,就明白了大半。

一句话,mrkl_tree 是一种倒置的树形数据结构,父节点可以代表它的子节点,而根就代表了整棵树中所有的节点。对应到区块链里,mrkl_root代表了该块所有的交易。

打个比方,就相当于人们的族谱,最上面的老祖宗,代表了整个家族

mrkl_tree的存在使的轻钱包成为可能,只需要同步区块的头信息(即我们上篇文章图示的80字节),不需要同步所有的交易数据,就能验证数据的完整性。

好的,作为一篇普及文,本篇文章核心讲完了~~


那它是如何起作用的呢? 关键还是hash, 即映射,把一个大空间映射到小空间,把一个大数据计算出一个小数据,一个简短的ID。就好比,人可以有很大不同,长相、身高、血型、性格,每个变量不同就是不同的人,我们可以用所有的这些数据来代表一个人。但是我们可以给每人一个唯一的名字(或身份证号)代表他。但这里有个不同,人的名字是人为定的,跟这个人的身高、长相、性格没什么关系,而hash出来的ID, 却是真实地通过身高、长相、性格等数据计算出来的 —— 把一段任意的数据(人),通过运算产生一个定长的数据(名字)。

也许你会问,不同的人,不同的身高、长相、性格,会不会最终计算出相同的ID,就像现实中不同的人出现重名。这就是所谓的哈希碰撞。确实,理论上是可能的,但工程学就是这样,* 差不多就行 *。只要出现相同的概率可以低到忽略,数学上也没有有效的办法伪造数据实现碰撞,理论上并不需要绝对完美。

区块数据头里的 merkle root ,就是把当下所有的交易层层合并起来,映射成一个短数据,代表的所有的交易。


交易L1 算出hash(L1) , 交易 L2算出hash(L2), 算出的这两个hash 合并起来进一步计算hash, 最终就可以得到最上层的hash值了。

下面的这张图更形象地展示了区块间关系,还有merkle root 如何关联到所有交易 。

图中,Prev Hash 是上一个区块的hash,它是依据上一个区块的头哈希+数据块哈希+随机数生成 。区块中每一笔交易对应一个哈希,呈树装结构,生成的最终值(merkle根),而它就可以代表了该区块中的交易。

这种结构导致了不可能改变历史数据或交易。比如改了某个区块中的交易,必须依次修改以下相应的数据才可以,修改某个交易tx -> 交易对应的hash -> 顶层 的 merkle root -> 下一个区块的prev hash -> 之后所有的块都要更改直到当前最新的块,而当前最新的块是所有比特币节点共识的基础。
只要有篡改,别的节点就会发现,不会接受这份数据,这也是为什么区块链具有不可篡改性

光说不练,还不够深刻,让我们用简单的python代码来验证一下,就以上篇文章拆解的block为例。

#!/usr/bin/python

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

def dhash256(s):  #hash值计算
    return hash256(hash256(s))

tx1="b1fea52486ce0c62bb442b530a3f0132b826c74e473d1f2c220bfa78111c5082".decode('hex')[::-1]
tx2="f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16".decode('hex')[::-1]

mrkl_tree = dhash256(tx1+tx2)  #两个交易的hash值合并 计算mrkl_root
result=mrkl_tree[::-1].encode('hex')

print result
#result: 7dac2c5666815c17a3b36427de37bb9d2e2c5ccec3f8633eb91a4205cb4c10ff

“b1fea52486ce0c62bb442b530a3f0132b826c74e473d1f2c220bfa78111c5082” 是第一笔coinbase的交易, “f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16”是第二笔交易,运算得到的结果正是block头里的merkle_tree, “f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16“”。

这下清楚了吗,这棵叫默克尔树是不是已经种在了你心里?~~


本公众号是活动“每周一新”第11周的践行产物。主要分享成长感悟、旅游经历、通用技术、IT趣闻、编程知识等,真诚欢迎你关注公众号。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值