当前位置:   article > 正文

以太坊 Trie树_以太坊底层的trie

以太坊底层的trie

Trie树
Trie树,又称字典树,是一种用于快速检索的多叉树结构。
Trie树可以利用字符串的公共前缀来节约存储空间,如果系统中存在大量字符串且这些字符串基本没有公共前缀,则相应的trie树将非常消耗内存,这也是trie树的一个缺点。
Trie树的基本性质可以归纳为:
    根节点不包含字符,除根节点以外每个节点只包含一个字符。
    从根节点到某一个节点,路径上经过的字符连接起来,为该节点对应的字符串。
    每个节点的所有子节点包含的字符串不相同。

如英文字母的字典树是一个26叉树,数字的字典树是一个10叉树。

如下图所示,该trie树用10个节点保存了6个字符串:tea,ten,to,in,inn,int:

Patricia Tries 前缀树
前缀树跟Trie树的不同之处在于Trie树是为每一个字符串分配一个节点,
而前缀树是将那些很长但又没有公共节点的字符串的Trie树退化成数组。

在以太坊里面会由黑客构造很多这种节点造成拒绝服务攻击。
前缀树的不同之处在于如果节点有公共前缀,那么就使用公共前缀,否则就把剩下的所有节点插入同一个节点。

如:


Merkle树
Merkle Tree,通常也被称作Hash Tree,顾名思义,就是存储hash值的一棵树。
Merkle树的叶子是数据块(例如,文件或者文件的集合)的hash值。
非叶节点是其对应子节点串联字符串的hash。

Merkle Tree的主要作用是当我拿到Top Hash的时候,这个hash值代表了整颗树的信息摘要,当树里面任何一个数据发生了变动,都会导致Top Hash的值发生变化。
而Top Hash的值是会存储到区块链的区块头里面去的, 区块头是必须经过工作量证明。
这也就是说我只要拿到一个区块头,就可以对区块信息进行验证。

MPT 以太坊Tries树
Merkle Patricia Trie(MPT) 是 EThereum 中一种非常重要的数据结构,用来存储用户账户的状态及其变更、交易信息、交易的收据信息。
每一个以太坊的区块头包含三颗MPT树,分别是:
1、交易树
2、收据树(交易执行过程中的一些数据)
3、状态树(账号信息,合约账户和用户账户)

MPT树有以下几个作用:
    存储任意长度的key-value键值对数据;
    提供了一种快速计算所维护数据集哈希标识的机制;
    提供了快速状态回滚的机制;
    提供了一种称为默克尔证明的证明方法,进行轻节点的扩展,实现简单支付验证;

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


key                    value

a711355            45.0 ETH
a77d337            1.00 WEI|
a7f9365             1.1 ETH
a77d397            0.12 ETH

prefix 前缀:
0 - 扩展节点,偶数个半字节
1 - 扩展节点,奇数个半字节
2 - 叶子节点,偶数个半字节
3 - 叶子节点,奇数个半字节


MPT 中对 key 的编码
trie/encoding.go 主要处理trie树中的三种编码格式的相互转换的工作。
三种编码格式分别为:
    KEYBYTES 编码:  这种编码格式是原生的key字节数组
    HEX 编码:             这种编码格式是把一字节拆分成两字节,尾部加一字节编码标记(0x10),
    COMPACT 编码:   这种编码格式是把Hex的两字节合并为一字节,在头部加一字节奇偶数据位(0x20或0x30)
                                         
将 keybytes 编码为 Hex:
编码前: 0x12 0x34 0x56
编码后: 0x01 0x02 0x03 0x04 0x03 0x04 0x05 0x06 0x10
0x10 为标记为 表示是Hex编码

  1. package main
  2. import (
  3. "fmt"
  4. )
  5. // 将 keybytes 转化成 Hex
  6. // 1. 将 keybytes 中的1byte信息,高4bit和低4bit分别放在2个byte里。
  7. // 2. 最后在尾部加1字节标记当前属于Hex格式。
  8. func keybytesToHex(str []byte) []byte {
  9. l := len(str)*2 + 1
  10. var nibbles =
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/在线问答5/article/detail/1016809
推荐阅读
相关标签
  

闽ICP备14008679号