2025年MPT(Merkle Patricia Tree)树结构示例

MPT(Merkle Patricia Tree)树结构示例MPT Merkle Patricia Tree 参考深入浅出以太坊 MPT Merkle Patricia Tree MPT 树结构示例 1 rootHash 扩展节点 prefix 0 prefix shared nibble next node rootHash 1 6 hashA

大家好,我是讯享网,很高兴认识大家。

MPT(Merkle Patricia Tree):

参考深入浅出以太坊MPT(Merkle Patricia Tree)

MPT树结构示例1:

在这里插入图片描述
讯享网
rootHash扩展节点 prefix 0

prefix shared nibble next node
rootHash 1 6 hashA
hashA 分支节点
hashB 00 6f hashD
hashD 分支节点
hashE 1 7 hashF
hashF 分支节点
hashG 3 5 coin

在这里插入图片描述

MPT树结构示例2:

在这里插入图片描述
如图所示:

总共有2个扩展节点,2个分支节点,4个叶子节点。

其中叶子结点的键值情况为:

节点的前缀:

1 更新

函数_update_and_delete_storage(self, node, key, value)

i. 如果node是空节点,直接返回[pack_nibbles(with_terminator(key)), value],即对key加上终止符,然后进行HP编码。

ii. 如果node是分支节点,如果key为空,则说明更新的是分支节点的value,直接将node[-1]设置成value就行了。如果key不为空,则递归更新以key[0]位置为根的子树,即沿着key往下找,即调用_update_and_delete_storage(self._decode_to_node(node[key[0]]),key[1:], value)。

iii. 如果node是kv节点(叶子节点或者扩展节点),调用_update_kv_node(self, node, key, value),见步骤iv

iv. curr_key是node的key,找到curr_key和key的最长公共前缀,长度为prefix_length。Key剩余的部分为remain_key,curr_key剩余的部分为remain_curr_key。

a) 如果remain_key==[]== remain_curr_key,即key和curr_key相等,那么如果node是叶子节点,直接返回[node[0], value]。如果node是扩展节点,那么递归更新node所链接的子节点,即调用_update_and_delete_storage(self._decode_to_node(node[1]),remain_key, value)

b) 如果remain_curr_key == [],即curr_key是key的一部分。如果node是扩展节点,递归更新node所链接的子节点,即调用_update_and_delete_storage(self._decode_to_node(node[1]),remain_key, value);如果node是叶子节点,那么创建一个分支节点,分支节点的value是当前node的value,分支节点的remain_key[0]位置指向一个叶子节点,这个叶子节点是[pack_nibbles(with_terminator(remain_key[1:])),value]

c) 否则,创建一个分支节点。如果curr_key只剩下了一个字符,并且node是扩展节点,那么这个分支节点的remain_curr_key[0]的分支是node[1],即存储node的value。否则,这个分支节点的remain_curr_key[0]的分支指向一个新的节点,这个新的节点的key是remain_curr_key[1:]的HP编码,value是node[1]。如果remain_key为空,那么新的分支节点的value是要参数中的value,否则,新的分支节点的remain_key[0]的分支指向一个新的节点,这个新的节点是[pack_nibbles(with_terminator(remain_key[1:])),value]

d) 如果key和curr_key有公共部分,为公共部分创建一个扩展节点,此扩展节点的value链接到上面步骤创建的新节点,返回这个扩展节点;否则直接返回上面步骤创建的新节点

v. 删除老的node,返回新的node

l 删除

删除的过程和更新的过程类似,而且很简单,函数名:_delete_and_delete_storage(self, key)

i. 如果node为空节点,直接返回空节点

ii. 如果node为分支节点。如果key为空,表示删除分支节点的值,直接另node[-1]=‘’, 返回node的正规化的结果。如果key不为空,递归查找node的子节点,然后删除对应的value,即调用self._delete_and_delete_storage(self._decode_to_node(node[key[0]]),key[1:])。返回新节点

iii. 如果node为kv节点,curr_key是当前node的key。

a) 如果key不是以curr_key开头,说明key不在node为根的子树内,直接返回node。

b) 否则,如果node是叶节点,返回BLANK_NODE if key == curr_key else node。

c)如果node是扩展节点,递归删除node的子节点,即调用_delete_and_delete_storage(self._decode_to_node(node[1]),key[len(curr_key):])。如果新的子节点和node[-1]相等直接返回node。否则,如果新的子节点是kv节点,将curr_key与新子节点的可以串联当做key,新子节点的value当做vlaue,返回。如果新子节点是branch节点,node的value指向这个新子节点,返回。

l 查找

查找操作更简单,是一个递归查找的过程函数名为:_get(self, node, key)

i. 如果node是空节点,返回空节点

ii. 如果node是分支节点,如果key为空,返回分支节点的value;否则递归查找node的子节点,即调用_get(self._decode_to_node(node[key[0]]), key[1:])

iii. 如果node是叶子节点,返回node[1] if key == curr_key else ‘’

iv. 如果node是扩展节点,如果key以curr_key开头,递归查找node的子节点,即调用_get(self._decode_to_node(node[1]),key[len(curr_key):]);否则,说明key不在以node为根的子树里,返回空

学习时间:

提示:这里可以添加计划学习的时间
例如:
1、 周一至周五晚上 7 点—晚上9点
2、 周六上午 9 点-上午 11 点
3、 周日下午 3 点-下午 6 点


学习产出:

提示:这里统计学习计划的总量
例如:
1、 技术笔记 2 遍
2、CSDN 技术博客 3 篇
3、 学习的 vlog 视频 1 个

小讯
上一篇 2025-03-30 19:42
下一篇 2025-02-18 17:11

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/37282.html