兄弟连Go语言区块链培训教程之以太坊源码详解4

兄弟连Go语言区块链培训教程之以太坊源码详解4
兄弟连Go语言区块链培训教程之以太坊源码详解4

很多人喜欢Go语言,其实是因为Go语言有其独特的语言属性在支撑着其在编程语言界的发展,今天兄弟连Go语言+区块链培训老师给大家介绍一下关于以太坊源码详解4,下面我们一起来看一下吧。

MPT(实现快速查找以节省存储空间)

**背景**

- Trie:用于快速检索的多叉树,查找速度快、但是需要耗费大量的存储空间 - Patricia Trie:耗费的空间更小

- Merkle Tree:Merkle树是一种用于快速验证内容完整性的数据结构,其基本原理是分别计算树的叶?结点的hash值,然后把叶?结点的hash值拼接在?起,再计算?次hash作为其?结点的hash值,依次向上直到根结点,根结点的hash值称为Merkle Root。可以看出,如果想要获得相同的Merkle Root,所有?结点的内容都必须相同,这样就可以?来验证树的内容有没有被篡改

**概念**

- MPT:MPT融合了了上?面3种数据结构,但是?又有?一些细微的差别。 - MPT是?用来检索字节数据的,因此是16叉树,分别代表0x0~0xF。

**结构**

MPT定义4种结点类型:

1. 空结点(NULL)

2. 分?支结点(branch node):包含16个分?支,以及1个value

3. 扩展结点(extension node):只有1个子结点

4. 叶子结点(leaf node):没有?子结点,包含?一个value

**HP编码**

- MPT树中另外一个重要的概念是一个特殊的十六进制前缀(hex-prefix,

HP)编码,用来对key进行编码。因为字母表是16进制的,所以每个节点可能有16个孩子。因为有两种[key,value]节点(叶节点和扩展节点),引进一种特殊的终止符标识来标识key所对应的是值是真实的值,还是其他节点的hash。如果终止符标记被打开,那么key对应的是叶节点,对应的值是真实的value。如果终止符标记被关闭,那么值就是用于在数据块中查询对应的节点的hash。无论key奇数长度还是偶数长度,HP都可以对其进行编码。最后我们注意到一个单独的hex字符或者4bit二进制数字,即一个nibble。

- HP编码很简单。一个nibble被加到key前(下图中的prefix),对终止符的状态和奇偶性进行编码。最低位表示奇偶性,第二低位编码终止符状态。如果key是偶数长度,那么加上另外一个nibble,值为0来保持整体的偶特性。

**源码分析**

- 以太坊中的MPT的实现源代码:trie/trie.go以及trie/node.go。trie.go 主要实现struct

Trie以及MPT树的各种操作:查询,添加,删除。node.go实现了四种节点以及从持久化数据库中解析node。理解了Node的实现,Trie的实现很容易理解。有关MPT中的四种节点,node.go的实现如下:

```

type (

// 分支节点

fullNode struct {

Children [17]node // Actual trie node data to encode/ decode (needs custom encoder)

flags nodeFlag

}

// 实现叶子节点和扩展节点

shortNode struct {

Key []byte

Val node

flags nodeFlag

}

hashNode []byte

valueNode []byte

)

// 每个节点的哈希信息

type nodeFlag struct {

hash hashNode // cached hash of the node (may be nil)

gen uint16 // cache generation counter

dirty bool // whether the node has changes that must be w ritten to the database

}

```

**总结**

- MPT是以太坊用来存储“状态”的数据结构,综合了Trie,Patrica Trie以及Merkletree的优点

- MPT的key是用HEX编码,在持久化存储时,会转换为HP编码。以太坊的g o语言实现中,用fullNode表达分支节点,用shortNode表示叶子节点和扩展节点。

相关主题
相关文档
最新文档