这个系列主要结合neo的源码,和大家分享一下区块链的那些事.
这篇文章和大家家聊聊梅克尔树.

1. 梅克尔树是区块中所有交易记录的数据指纹

梅克尔树是一种二叉树,由于它能快速检查和归纳大量数据,被用在区块中记录交易记录的完整性.下面是neo中Block的属性,是区块的头信息组成:

        public uint Version; //区块版本public UInt256 PrevHash; //前一个区块的散列值public UInt256 MerkleRoot;// 该区块中所有交易的Merkle树的根public uint Timestamp; // 时间戳public uint Index; // 区块高度public ulong ConsensusData;  //一致性数据  不知道是什么,这个字段以后再说public UInt160 NextConsensus; // 下一个区块的记账合约的散列值public Witness Script;// 用于验证该区块的脚本
复制代码

可见区块由区块版本、前一个哈希值、梅克尔树根节点、时间戳、区块高度、下一个区块的记账合约散列、验证脚本组成,今天主要聊一下Block中的Merkle Tree Root.
区块头了解了,那么区块的数据区包含什么了,来了:public Transaction[] Transactions,这就是neo中区块的数据区,一个Transaction的数组.正如大家所知道的:区块链中流通的信息就是交易数据了,在neo中就是Transaction.
将这个的原因是想让大家意识到:梅克尔树在neo中存在于区块头部的根节点,数据区是交易的数组,并不是交易数据的梅克尔树.neo中梅克尔树的价值通过根节点体现.

2. neo生成区块头中的梅克尔根

neo区块中,所有的交易的哈希值构成梅克尔树的叶子节点,叶子节点两两组合做双SHA-256运算得到父节点,以此类推等到最后的根节点,同时根节点被记入区块头部.

    //双SHA-256运算public byte[] Hash256(byte[] message){return message.Sha256().Sha256();}//左右孩子组合求父节点的哈希值//concat:组合 a.concat(b) = abparents[i].Hash = new UInt256(Crypto.Default.Hash256(parents[i].LeftChild.Hash.ToArray()
.Concat(parents[i].RightChild.Hash.ToArray()).ToArray()));
复制代码

代码毕竟是一个程序员友好型的东西,那么下面来一波图解,相信聪明的你就get了.

梅克尔树

叶子节点是一个交易的哈希值,父节点的哈希值是左右孩子的哈希值联合进行双哈希运算的来的.大家会看到最后面那个叶子节点和倒数第二个相同.这是因为当缺少一个叶子节点时,梅克尔树会将最后的那个节点复制,然后两两组成他们的父节点,形成了一个完整的树形结构.

neo建树的过程就是通过两两子节点计算父节点的过程.话不多说,源码贴上先

//梅克尔树节点
internal class MerkleTreeNode{public UInt256 Hash; //节点哈希值public MerkleTreeNode Parent; //父节点public MerkleTreeNode LeftChild; //左孩子节点public MerkleTreeNode RightChild;//右孩子节点public bool IsLeaf => LeftChild == null && RightChild == null;public bool IsRoot => Parent == null;}
//通过建立梅克尔树获取梅克尔树根节点
private static MerkleTreeNode Build(MerkleTreeNode[] leaves){//没有数据,无法建树if (leaves.Length == 0) throw new ArgumentException();//只有一个数据,那么根节点就是它了if (leaves.Length == 1) return leaves[0];//父节点数组,new出来的不会保存前面的值MerkleTreeNode[] parents = new MerkleTreeNode[(leaves.Length + 1) / 2];for (int i = 0; i < parents.Length; i++){parents[i] = new MerkleTreeNode();//父节点有左右孩子节点parents[i].LeftChild = leaves[i * 2];leaves[i * 2].Parent = parents[i];if (i * 2 + 1 == leaves.Length){//如果叶子节点是奇数,那么最后的叶子节点做复制,两两组成父节点parents[i].RightChild = parents[i].LeftChild;}else{parents[i].RightChild = leaves[i * 2 + 1];leaves[i * 2 + 1].Parent = parents[i];}//父节点的哈希值为孩子节点哈希值的联合求双SHA256.parents[i].Hash = new UInt256(Crypto.Default.Hash256(parents[i].LeftChild.Hash.ToArray().Concat(parents[i].RightChild.Hash.ToArray()).ToArray()));}//递归计算return Build(parents); //TailCall}
复制代码

上面的递归可以通过下面的图示来加深理解

Neo Markle Tree Build
相邻两个子节点组合,生成父节点.缺失右孩子节点的,用左孩子节点补齐.不存储中间变量,只保存最后计算出来的根节点.
通过梅克尔树,大量交易记录就缩小在256bits的数据指纹里面啦.
如果你是一个节点,那么检查数据是否被修改就只需要计算一下交易记录的梅克尔树的根节点,然后和区块头的梅克尔跟比较就可以得出结果了

3. 梅克尔树又用于SPV的交易验证

这里属于拓展篇了,小编想在这里和大家聊聊梅克尔路径认证.归为拓展的原因是neo中没有应用spv.

3.1 spv简介

spv是比特币的轻量级客户端,它的中文为简单支付验证,主要解决的痛点是比特币共识链太大,使非矿工节点需要拉取过多数据。
spv只会下载共识链的去块头的链条,能节省大约1000倍的存储空间。由于没有获取完整的数据,所以spv客户端不能作为矿工节点

3.2 spv通过梅克尔路径进行交易验证

spv没有交易数据,所以如果需要进行交易验证的时候,spv就会发送一条广播,让其他非spv节点给它发送验证数据,bitcoin中,这类数据类型为MerkleBlock。

class CMerkleBlock
{public:/** Public only for unit testing */CBlockHeader header;CPartialMerkleTree txn;.......
}
复制代码

这是比特币区块的一段源码,我们暂且称呼它为梅克尔块.
梅克尔块中包含两个重要的数据,一个是区块头,另外一个是梅克尔树。这里的区块头就是比特币区块的区块头,梅克尔树可以根据它的命名看出是一串交易,它实际上是一条梅克尔认证路径。

class CPartialMerkleTree
{
protected:/** the total number of transactions in the block */unsigned int nTransactions;/** node-is-parent-of-matched-txid bits */std::vector<bool> vBits;/** txids and internal hashes */std::vector<uint256> vHash;/** flag set when encountering invalid data */bool fBad;......
复制代码

收到spv节点请求的完整节点会把目标区块的区块头和一条验证路径的交易串(交易编号和哈希)发送过来。这样节点就可以通过下图所示的方法进行验证了。(黑色区块就是发送过来的交易)

梅克尔路径证明

spv验证交易e时,只需要通过和交易f、H(gg)、H(H(ab)+H(cd))的计算来计算ROOT的值,然后和区块头中的梅克尔根进行比对就可以进行简单的验证了。这里的整个过程就是梅克尔交易验证,黑色路径为梅克尔认证路径。

3.3 总结

spv可以有效减少非矿工节点对共有链的数据存储,目前neo中并不支持。同时比特币区块数据区存储的是交易的梅克尔树,而neo中则是存放的交易数组。

梅克尔树就讲到这里来,后面还会有很多关于区块链的分享,期待与您共享共赢~

csdn地址:blog.csdn.net/little_prog…

作者:谢益文_2f26
链接:www.jianshu.com/p/2b082157b…

进群讨论:795681763

大话Neo系列:Merkle Tree相关推荐

  1. Polygon zkEVM中的Merkle tree

    1. 引言 前序博客有: Merkle tree及其在区块链等领域的应用 以https://github.com/0xPolygonHermez/pil-stark为例,Polygon zkEVM中实 ...

  2. 二、哈希算法和Merkle Tree

    章节系列目录:点击跳转 文章目录 哈希算法 哈希函数的定义 可靠哈希函数需满足的要求 哈希函数的主要作用 哈希实际例子 Merkle Tree默克尔树 完整性校验的方法 哈希列表 Hash List ...

  3. Merkle Tree(梅克尔树)算法解析

    Merkle Tree概念   Merkle Tree,通常也被称作Hash Tree,顾名思义,就是存储hash值的一棵树.Merkle树的叶子是数据块(例如,文件或者文件的集合)的hash值.非叶 ...

  4. 基于Java语言构建区块链(六)—— 交易(Merkle Tree)

    基于Java语言构建区块链(六)-- 交易(Merkle Tree) 2018年04月16日 10:21:35 wangwei_hz 阅读数:480更多 个人分类: 区块链比特币bitcoin 最终内 ...

  5. 大话ion系列(五)

    点击上方"LiveVideoStack"关注我们 作者 | 王朋闯 本文为王朋闯老师创作的系列ion文章,LiveVideoStack已获得授权发布,未来将持续更新. 大话ion系 ...

  6. 大话ion系列(四)

    点击上方"LiveVideoStack"关注我们 作者 | 王朋闯 本文为王朋闯老师创作的系列ion文章,LiveVideoStack已获得授权发布,未来将持续更新. 大话ion系 ...

  7. 大话ion系列(三)

    点击上方"LiveVideoStack"关注我们 作者 | 王朋闯 本文为王朋闯老师创作的系列ion文章,LiveVideoStack已获得授权发布,未来将持续更新. 大话ion系 ...

  8. 大话ion系列(二)

    点击上方"LiveVideoStack"关注我们 作者 | 王朋闯 本文为王朋闯老师创作的系列ion文章,LiveVideoStack已获得授权发布,未来将持续更新. 大话ion系 ...

  9. 七、区块链如何运用merkle tree验证交易真实性

    转载自:https://www.tangshuang.net/4117.html 本文假设你已经知道区块链中merkle tree的原理,现在搞明白具体怎么来实现交易真实性验证. Merkle Tre ...

  10. 区块链六-Merkle Tree

    2019独角兽企业重金招聘Python工程师标准>>> 基于Java语言构建区块链(六)-- 交易(Merkle Tree) Posted on 2018-03-26 |  In b ...

最新文章

  1. ERROR: from PIL import Image ImportError: No module named PIL
  2. phpstrom中让volt高亮显示
  3. linux覆盖文件如何还原_大数据笔试真题集锦-——第十九章Linux面试题
  4. 【实战】用机器学习来提升你的用户增长
  5. php中args,PHP中的重载,即__call($name , $args)的使用
  6. 前端学习(3173):react-hello-react之todoList教程
  7. 使用rpm包安装mysql_centos下利用rpm包安装mysql
  8. 创建oracle 数据库表空间,角色,用户的sql语句
  9. 非阻塞 php,PHP异步非阻塞之路
  10. NoSQL Manager for MongoDB 破解
  11. Linux内核分析考试试题,linux内核分析第二周作业
  12. Raspberry Pi with Node.js and Arduino
  13. 如何制作ISO镜像文件
  14. [vmware]解析单一GHO文件如何安装操作系统
  15. Python第九章 文件系统
  16. 星空粒子登录页面 jsp
  17. 南大通用GBase8s 常用SQL语句(150)
  18. 【华为OD机试真题 python】连续出牌数量【2022 Q4 | 200分】
  19. 计算机科学速成课 Crash Course Computer Science 笔记(摘要形式)
  20. python向量计算库教程_python中numpy基础学习及进行数组和矢量计算

热门文章

  1. Unable to start a VM due to insufficient capacity
  2. 支持“***Context”上下文的模型已在数据库创建后发生更改
  3. bag of word C++图像批量读写
  4. 什么是互联网思维?给你最全面的解释
  5. 令人失望的vb 的范型
  6. 【三支火把】--- 关于UEFIPCD的总结介绍
  7. 启动与关闭VMware Workstation的BAT批处理脚本
  8. VML 编程之--------《VML极道教程》原著:沐缘华
  9. 電郵泛濫成災 電話再成新寵
  10. (第三场) C Shuffle Cards 【STL_rope || splay】