MPT(Merkle Patricia Tree)树结构示例

MPT(Merkle Patricia Tree):

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

MPT树结构示例1:

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

prefixshared nibblenext node
rootHash16hashA
hashA分支节点
hashB006fhashD
hashD分支节点
hashE17hashF
hashF分支节点
hashG35coin

在这里插入图片描述

MPT树结构示例2:

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

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

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

节点的前缀:

5 MPT树的操作
下面从MPT树的更新,删除和查找过程来说明MPT树的操作。

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 个

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值