当前位置: 首页> 移动互联

区块链数据结构介绍(Trie树) 发布时间:2020-03-22

树这种数据结构,在区块链中扮演着重要的角色,交易的数据,账号的管理,交易的收据信息等都是一树为基础。本文主要介绍三种树,也是在以太坊的中运用最多的三种树结构:Trie树, Patricia Trie和Merkle树。

Trie树

Trie树,又称字典树,单词查找树或者前缀树,是一种用于快速检索的多叉树@结构●,如英文字母的字典树是一个26叉树,数字的字典树是一个10叉树。举个例子,用trie树保存10个节点的6个字符串:tea☼,ten,to,in,inn,int。具体图如下:

可以看到字符串in,inn和int的公共前缀是₪큐“in”,这样的效果就是压缩了数据,减少空ν间的存储。那么如果没有公共的前缀,那么问题就来了,占用大量的空间,这样的检索的速度将会减慢。

Patricia Trie树

Patricia Trie树的〨不同之处在于Tr←ie树给每一个字符串分配一个节点,这样将使那些很长但又没有公共节点的字符串的Trie树退化←成数组。在〓以太坊里面会由黑客构造很多这种节点造成拒绝服务攻击。前缀树的不同之处在于如果节点公共前缀,那么┌就使用公共前缀■,否则就把剩下的所有节点插入同一个节点。Patricia相对Tire的优化正如下图:


我们可以举个例子来总结Pa○tricia Trie树,如下图:

最终的8个key对应的Value 如下表:

Merkle Tree

称作Hash Tree,顾名思义,就是存储hash值的一棵树。Merkle树的叶子是数据块(例如,文件或者文件的集合)的hash值。非叶节点是其对应子节点串联字符串的hash。这个树结构是比特币采用Е的数据结构。Merkle Tree的主要作用是当我拿到Top Hash的时候,这个hash值代表了整颗树的信息摘要,当树里面任何一个数据发Д生了变动,都会导致Top Hash的值发生变化。而Top Hash的值是会存储到区块链的区块头里面去的, 区块头是必须经过工作量证明。这也就是说我只要拿到一个区块头,就可以对区块信息进行验证。


EЮTH◥ Merkle Patricia Tries↖ 树

以太坊的每个区块头包含★三个重要的树:

1.$交易树
2.收据树(交易执行过程中的一些数据)
3.状κ态树(账号信息, 合约账户和用户账户)

如下通过例子来介绍,例如,两个区块头,其中state root,tx root re‖|ceipt root分别存储了这三棵树的树根,第二个区块显示了当账号 175的数据变更(27 -> 45)的时候,只需要存储跟这个账号相关的部分数据,而且老的区块中的数据还是可以正常访问。如下图:


算法解释

假设输入值J,包含Key Value对的集合Ψ(Ke⺌y Value都是字Ⅺ节数组):


当使用这个集合的时候,我们将集合表示如下:

对应特定字节,我们表示为对应的半字节(nibble),其中Y集合在Hex-Prefix Encodi↹ng中有说明,意为半字节(4bit)集合(之所以采用半字节,其与后续ō说明的分支节点branch node结构以及key中编码flag有关),公式如下:

在Tries树中有三种节点:

1.叶子节点(Leaf): 叶子节点包含两个字段, 第一个字段是剩下的Key的半字节编码¨,而且半字节编码方法的第二个参数为true, 第二个字段是Value

2.扩展节点︱︳(Extention): 扩展节点也包含两个字段, 第一个字段是剩下的Key的可以至少被两个剩下节点共享的部分的』半字节编码,第『二个字段是n(J,j)

3.分支节点г(♦Branch): 分支节点包含了17个字段,⊙其前Ф16个项目对应于这Ё些点在其遍历中的键的十六个可能的半字节值中的每一个。第17个字段是存储那些在当前结υ点结束了的节点(例如, 有三个key,分别是 (abc ,abd, ab)⿰ 第17个字段储存了ab节点的值)

分ы支节点只有在需要的时候使用, 对于一个只有一个非空 key value对的Trie树,可能不存在分支节点。К如果使用公式来定义这三种节点, 那么公式如下:图中的HP函数代表Hex-Prefix Encoding,是一种半字节编码格式,RLP是使用RLP进行序列┖化的函数。


如果当前需要编码的KV集合只剩下一条数据,那么这条数据按照第一条规则进行↗编码〾。
如果当前需要编码的KV集合有公共前۩..缀,那么提取最大公共前缀并使用第二条规则进行处理。

如果不是上面两种情况,那么使用分支节点进行集合切分⊥,因为key※是使用HP♨进行编码的,所以可能的分支只有0-15这16个分支。可以看到u的值由n进行递归定义,而如果有节点刚好在这里完结了,那么第17个元素v就是为这种情况准备的。

对于数据应该如何存储和不应该如何存储, 黄皮书中说明没有显示的ю定义。所以这是一个实现上∝的问题。我们简单的定义了一个函数来把J映射为一个Hash。 我们认为对于任意一个J,只存在唯一一个Hash▒█值。


文章来源:链码Tech

转自:区块网

󰄯 分享
{{wanzhanqun_analysis}} {{website_analysis}} {{website_copyright }}