这个系列主要结合neo的源码,和大家聊聊梅克尔树.
1.梅克尔树是区块中所有交易记录的数据指纹
梅克尔树是一种二叉树,由于它能快速检查和归纳大量数据,被用在区块中记录交易记录的完整性.下面是neo中Block的属性,是区块的头信息组成:
可见区块由区块版本、前一个哈希值、梅克尔树根节点、时间戳、区块高度、下一个区块的记账合约散列、验证脚本组成,今天主要聊一下Block中的Merkle Tree Root.
区块头了解了,那么区块的数据区包含什么了,来了:`public Transaction[] Transactions`,这就是neo中区块的数据区,一个Transaction的数组.正如大家所知道的:区块链中流通的信息就是交易数据了,在neo中就是Transaction.
将这个的原因是想让大家意识到:梅克尔树在neo中存在于区块头部的根节点,数据区是交易的数组,并不是交易数据的梅克尔树.neo中梅克尔树的价值通过根节点体现.
2. neo生成区块头中的梅克尔根
neo区块中,所有的交易的哈希值构成梅克尔树的叶子节点,叶子节点两两组合做双SHA-256运算得到父节点,以此类推等到最后的根节点,同时根节点被记入区块头部.
代码毕竟是一个程序员友好型的东西,那么下面来一波图解,相信聪明的你就get了.
叶子节点是一个交易的哈希值,父节点的哈希值是左右孩子的哈希值联合进行双哈希运算的来的.大家会看到最后面那个叶子节点和倒数第二个相同.这是因为当缺少一个叶子节点时,梅克尔树会将最后的那个节点复制,然后两两组成他们的父节点,形成了一个完整的树形结构.
neo建树的过程就是通过两两子节点计算父节点的过程.话不多说,源码贴上先
上面的递归可以通过下面的图示来加深理解
相邻两个子节点组合,生成父节点.缺失右孩子节点的,用左孩子节点补齐.不存储中间变量,只保存最后计算出来的根节点.
通过梅克尔树,大量交易记录就缩小在256bits的数据指纹里面啦.
如果你是一个节点,那么检查数据是否被修改就只需要计算一下交易记录的梅克尔树的根节点,然后和区块头的梅克尔跟比较就可以得出结果了。
3.梅克尔树又用于SPV的交易验证
这里属于拓展篇了,小编想在这里和大家聊聊梅克尔路径认证.归为拓展的原因是neo中没有应用spv.
3.1 spv简介
spv是比特币的轻量级客户端,它的中文为简单支付验证,主要解决的痛点是比特币共识链太大,使非矿工节点需要拉取过多数据。
spv只会下载共识链的去块头的链条,能节省大约1000倍的存储空间。由于没有获取完整的数据,所以spv客户端不能作为矿工节点。
3.2 spv通过梅克尔路径进行交易验证
spv没有交易数据,所以如果需要进行交易验证的时候,spv就会发送一条广播,让其他非spv节点给它发送验证数据,bitcoin中,这类数据类型为MerkleBlock。
这是比特币区块的一段源码,我们暂且称呼它为梅克尔块.
梅克尔块中包含两个重要的数据,一个是区块头,另外一个是梅克尔树。这里的区块头就是比特币区块的区块头,梅克尔树可以根据它的命名看出是一串交易,它实际上是一条梅克尔认证路径。
收到spv节点请求的完整节点会把目标区块的区块头和一条验证路径的交易串(交易编号和哈希)发送过来。这样节点就可以通过下图所示的方法进行验证了。(黑色区块就是发送过来的交易)
spv验证交易e时,只需要通过和交易f、H(gg)、H(H(ab)+H(cd))的计算来计算ROOT的值,然后和区块头中的梅克尔根进行比对就可以进行简单的验证了。这里的整个过程就是梅克尔交易验证,黑色路径为梅克尔认证路径。
3.3总结
spv可以有效减少非矿工节点对共有链的数据存储,目前neo中并不支持。同时比特币区块数据区存储的是交易的梅克尔树,而neo中则是存放的交易数组。
梅克尔树就讲到这里来,后面还会有很多关于区块链的分享,期待与您共享共赢~
原文地址:https://www.jianshu.com/p/2b082157b3b0
领取专属 10元无门槛券
私享最新 技术干货