`
jackyhongvip
  • 浏览: 158243 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Merkle Tree

 
阅读更多

 

 

A Merkle tree is a hash tree where leaves are hashes of the values of individual keys. Parent nodes higher in the tree are hashes of their respective children. The principal advantage of Merkle tree is that each branch of the tre can be checked independently without requiring nodes to download the entire tree or the entire data set.

叶子节点是存储数据的hash值,内部节点是子节点hash值的hash。如果所有叶子节点相同,其根节点必相同;如果有叶子节点不同,其根节点必不同,而且可以顺藤摸瓜,从上至下,快速定位不同的叶子节点.

 

MerkleTree的构建

和BeanDB中不一样的是,cassandra中的merkle tree的叶子节点是某个key range的所有data的hash值(BeansDB是单条数据的hash值)。如下图,假设key的取值范围是1-64,下面mt中有四个叶子节点,三个内部节点。其中第一个叶子节点是由key值在[1,16]的数据生成一个hash值。假如[1,16]有三条数据,则该叶子节点是三条数目生成一个hash。(每个叶子节点包含一个key range,每个内部节点包含一个中间值)

 

单条数据的hash值: SHA-256

 

  1. //AntiEntropyService.Validator   
  2.    private MerkleTree.RowHash rowHash(CompactedRow row)  
  3.         {  
  4.             validated++;  
  5.             // MerkleTree uses XOR internally, so we want lots of output bits here   
  6.             byte[] rowhash = FBUtilities.hash("SHA-256", row.key.key.getBytes(), row.buffer.getData());  
  7.             return new MerkleTree.RowHash(row.key.token, rowhash);  
  8.         }  

 

 

叶子节点的hash值: 所有添加到此叶子节点的数据hash值的异或

 

  1. //MerkleTree.Leaf extends Hashable   
  2.   void addHash(byte[] righthash)  
  3.         {  
  4.             if (hash == null)  
  5.                 hash = righthash;  
  6.             else  
  7.                 hash = binaryHash(hash, righthash);  
  8.         }  
  9.   static byte[] binaryHash(final byte[] left, final byte[] right)  
  10.         {  
  11.             return FBUtilities.xor(left, right);  
  12.         }  

 

 

Inner node的hash值: 两个子节点hash值的异或

 

  1. //MerkleTree.hash() -> hashHelper()   
  2.    byte[] lhash = hashHelper(node.lchild(), leftactive, range);  
  3.             byte[] rhash = hashHelper(node.rchild(), rightactive, range);  
  4.             // cache the computed value (even if it is null)   
  5.             node.hash(lhash, rhash);  
  6.             return node.hash();  

 

 

merkle tree的生成

 

 

 

 

 

  1. //AntiEntropyService.Validator.prepare()   
  2.  while (true)  
  3.                 {  
  4.                     DecoratedKey dk = keys.get(random.nextInt(numkeys));  
  5.                     if (!tree.split(dk.token))  
  6.                         break;  
  7.                 }  
  8. //MerkleTree.split()   
  9.  public boolean split(Token t)  
  10.     {  
  11.         if (!(size < maxsize))  
  12.             return false;  
  13.         Token mintoken = partitioner.getMinimumToken();  
  14.         try  
  15.         {  
  16.             root = splitHelper(root, mintoken, mintoken, (byte)0, t);  
  17.         }  
  18.         catch (StopRecursion.TooDeep e)  
  19.         {  
  20.             return false;  
  21.         }  
  22.         return true;  
  23.     }  
  24.     private Hashable splitHelper(Hashable hashable, Token pleft, Token pright, byte depth, Token t) throws StopRecursion.TooDeep  
  25.     {  
  26.         if (depth >= hashdepth)  
  27.             throw new StopRecursion.TooDeep();  
  28.         if (hashable instanceof Leaf)  
  29.         {  
  30.             // split   
  31.             size++;  
  32.             Token midpoint = partitioner.midpoint(pleft, pright);  
  33.             return new Inner(midpoint, new Leaf(), new Leaf());  
  34.         }  
  35.         // else: node.   
  36.         // recurse on the matching child   
  37.         Inner node = (Inner)hashable;  
  38.         if (Range.contains(pleft, node.token, t))  
  39.             // left child contains token   
  40.             node.lchild(splitHelper(node.lchild, pleft, node.token, inc(depth), t));  
  41.         else  
  42.             // else: right child contains token   
  43.             node.rchild(splitHelper(node.rchild, node.token, pright, inc(depth), t));  
  44.         return node;  
  45.     }  

 

 

  • 将所有数据条目添加到叶子节点,生成所有叶子节点的hash值。上述一步,生成了树的形状;这一步仅仅将叶子节点的hash值填充。有个技巧:key的添加从小到大有序添加;中序(深度优先)遍历上一步生成的树,得到待添加的叶子节点。仍然借用前面的例子,比如key值为1, 2, 5, 6, 8,10, 15, 30,而已有的Leaf节点为[1,16], [17,24], [25,32],[33-64]
    • 添加1,2,5,6,8,10,15到第一个叶子节点
    • 添加30,第一个节点range不包含该30,next;第二个节点,仍不包含,next...,直至最后一个叶子节点(range),添加到最后一个叶子节点.

 

  1. //CompactionManager.doCompaction()   
  2. Iterator<CompactionIterator.CompactedRow> nni = new FilterIterator(ci, PredicateUtils.notNullPredicate());  
  3. while (nni.hasNext())  
  4. {  
  5. validator.add(row);  
  6. }  
  7. //AntiEntropyService.Validator.add()   
  8.  while (!range.contains(row.key.token))  
  9.             {  
  10.                 // add the empty hash, and move to the next range   
  11.                 range.addHash(EMPTY_ROW);  
  12.                 range = ranges.next();  
  13.             }  
  14.             // case 3 must be true: mix in the hashed row   
  15.             range.addHash(rowHash(row));  
  16. //MerkleTree.TreeRangeIterator.computeNext()   
  17. public TreeRange computeNext()  
  18.         {  
  19.             while (!tovisit.isEmpty())  
  20.             {  
  21.                 TreeRange active = tovisit.pop();  
  22.                 if (active.hashable.hash() != null)  
  23.                     // skip valid ranges   
  24.                     continue;  
  25.                 if (active.hashable instanceof Leaf)  
  26.                     // found a leaf invalid range   
  27.                     return active;  
  28.                 Inner node = (Inner)active.hashable;  
  29.                 // push intersecting children onto the stack   
  30.                 TreeRange left = new TreeRange(tree, active.left, node.token, inc(active.depth), node.lchild);  
  31.                 TreeRange right = new TreeRange(tree, node.token, active.right, inc(active.depth), node.rchild);  
  32.                 if (right.intersects(range))  
  33.                     tovisit.push(right);  
  34.                 if (left.intersects(range))  
  35.                     tovisit.push(left);  
  36.                       
  37.             }  
  38.             return endOfData();  
  39.         }  

 

 

  • Inner节点hash值的生成. Inner节点的hash值是lazy calculate,在使用时递归生成,具体见下一步,两个MerkleTree的比较

两颗MerkleTree的遍历比较

  • 首先生成一颗叶子节点<2^15的树。生成过程:随机挑选一个key,然后将包含这个key的叶子节点(key range)切分成两个节点。当叶子节点数目为2^15时或者深度为127时停止。比如,整个key range为[1, 64],已有key值为1, 8, 30。
    • 初始化时,根据点为Leaf,range为[1,64],
    • 切分包含1的叶子节点,即根节点生成两个Leaf [1, 32], [33, 64],
    • 切分包含8的叶子节点,[1,32]生成两个Leaf[1,16],[17,32]
    • 切分包含30的叶子节点,[17, 32]生成两个Leaf [17, 24] [25, 32],生成如上文图中所示的merkle tree
分享到:
评论

相关推荐

    merkletree.rar

    java 实现 merkle tree while (true) { Event event = receiveEvent(); String hash = computeHash(event); // ...... sendToDownstreamQueue(hash, event);... MerkleTree mtree = new MerkleTree

    merkle-tree:Kotlin中的Merkle Tree和Merkle证明实现

    Kotlin中的Merkle Tree和Merkle证明实现MerkleTree是使用Kotlin kotlin-platform-common插件在Kotlin中实现的,该插件可将代码编译为JavaScript。 实现的方法: MerkleTree (input : List , hash : ( ByteArray ) -&gt;...

    solidity-mt-vs-mmr:比较Merkle Tree和Merkle Mountain Range树木气体使用量的Solidity示例

    团结默克尔树vs默克尔山脉树 比较Merkle Tree和树的气体使用量的Solidity示例。 建造 npm run build 测试 npm test 输出: ... ✓ MerkleTree (2279ms) append gas used: 0 161462 append gas use

    Merkle tree

    merkle tree是一种区块链的基础数据结构,本文是整理的网上资料

    timber:从以太坊日志构建Merkle Tree数据库

    根据以太坊日志构建Merkle Tree数据库。 发起人: 启动配置 docker-compose.&lt;...&gt;.yml选项 CONTRACT_ORIGIN default remote mongodb compile HASH_TYPE 配置 contracts treeId TREE_HEIGHT 原料药 ...

    Merkle Tree构造及存在性证明,QT实现UI

    采用qt编写,适用于区块链初学者学习参考

    1_merkle-tree-master.rar

    merkle tree merkle tree merkle tree merkle tree merkle tree merkle tree merkle tree merkle tree merkle tree

    基于改进Merkle-Tree认证方法的可验证多关键词搜索方案.docx

    基于改进Merkle-Tree认证方法的可验证多关键词搜索方案 本文旨在解决云存储条件下密文的高效搜索问题,提出了一种基于改进Merkle-Tree认证方法的可验证多关键词搜索方案。该方案旨在解决搜索结果的可验证性问题,...

    MerkleTree:使用c ++二进制Merkle树

    制作简单的MerkleTree 例如)string item =“ Hello”; string * arr =新字符串; arr = MakeTree(item); PrintAll(arr); 结果)您好-&gt; 30efdfb52ff67f80dab7cb89dcfe0eec8412966cfe58324993674b4616d6bd11-&gt; ...

    开源项目-keybase-go-merkle-tree.zip

    《深入解析开源项目 Keybase Go-Merkle-Tree》 在信息技术领域,开源项目一直扮演着推动创新和技术进步的重要角色。Keybase 是一个知名的开源安全平台,它提供了一种安全的方式来管理和验证数字身份。其中,`...

    merkle_tree:纯Elixir中的Merkle Tree实现

    **Merkle Tree**,又称为哈希树或默克尔树,是一种数据结构,尤其在区块链、分布式存储和网络安全领域中广泛应用。它通过将数据的哈希值组织成树形结构,使得数据的完整性检查变得高效且可靠。Elixir 是一种基于 ...

    c++实现merkle_tree

    c++代码实现merkle_tree树..............

    MerkleTree.dev:MerkleTree.dev网站

    MerkleTree.dev 网站

    PyPI 官网下载 | merkle-tree-stream-0.0.1a4.tar.gz

    标题中的“PyPI 官网下载 | merkle-tree-stream-0.0.1a4.tar.gz”表明这是一个从Python Package Index(PyPI)官方下载的软件包,名为“merkle-tree-stream”,版本号为0.0.1a4,其打包格式是tar.gz。PyPI是Python...

    merkle:Go中的Merkle Tree实现

    默克尔 通过自己的作品, ,用法package mainimport ("crypto/sha256""log""os""github.com/wilfreddenton/merkle")func main() {// create a hash function// it's ok to resuse this in merkle calls because it ...

    merkletreejs::seedling:构造Merkle树并在JavaScript中验证证明

    MerkleTree.js 构造并使用JavaScript验证证明。 内容 安装 从 : npm install merkletreejs CDN 在 CDN上可用: &lt; script src =" https://cdn.jsdelivr.net/npm/merkletreejs@latest/merkletree.js " &gt; &...

    PHP中的Merkle树的实现-PHP开发

    将以下内容放入您的package.json中:{“ require”:{“ pleonasm / merkle-tree”:“ *”}}然后运行composer install。 固定大小树的用法散列树的用法要求用户提供一个散列函数,每个节点都将使用该函数进行散列。...

    前端开源库-merkle-tree-stream.zip

    "前端开源库-merkle-tree-stream.zip" 提供了一个用于前端开发的开源库,专注于处理Merkle Tree和Stream数据结构。这个压缩包可能包含了实现这一功能的源代码、文档和示例。 **Merkle Tree** 是一种哈希树数据结构...

    merkle-tree:Java中的简单Merkle树实现

    在提供的`merkle-tree-master`压缩包中,可能包含了实现这些功能的源代码,包括Merkle树的构建、哈希计算、证明验证等方法。通过阅读和分析这些代码,可以深入理解Merkle树的原理和Java实现细节。对于学习和实践...

    merkle是Merkle树的轻量级Rust实现。-Rust开发

    merkletree-具有SPV支持和不可知的merkle的轻型merkle树实现merkle merkle是Merkle树的轻量级Rust实现。 具有与外部依赖性无关的std :: hash ::: Hasher兼容性标准类型的哈希器实现#[derive(Hashable)]支持简单的...

Global site tag (gtag.js) - Google Analytics