首页 > 其他分享 >03 ETH-状态树

03 ETH-状态树

时间:2023-05-02 14:44:32浏览次数:36  
标签:03 hash 状态 以太 tree Merkle ETH 区块 节点

03 ETH-状态树

目录

地址到状态(balance、nonce、code、storage)的映射。

以太坊地址一般160bits,一般表示为40个16进制的数。


那么如何设计映射?像是 key:value pair?那么,能不能只用一个hash表来实现?(如果不考虑hash碰撞的话),那这样是不是太简单了?

用hash表的话,如果需要提供Merkle Proof,如何提供?

比如:一个人要签合同,需要别人证明一下,他有这么多钱,这个如何提供证明?

一个简单的方法,把hash表中的元素,组织成一颗Merkle tree,算出一个根hash值,根hash值需要保存在block header中,公布出去,根hash值只要是正确的,就能保证数据不被篡改。这个有什么问题吗?

不要一开始就看什么数据结构,而是一步步思考,想想数据结构是如何设计出来的。(多想想别人是为什么这样设计?)

新区块中包含有新的交易,执行交易必然会使hash表的内容发生变化,我们发布下一给区块的时候,难道要把hash表中的数据再重新组织成Merkle tree吗?那这个代价是不是太大了?

实际上,真正发生账户状态变化的只是一小部分。只有新区块中交易所关联的账户才会发生变化,大多数账户的状态是不变的。每次构建一次Merkle tree,代价是很大的。

比特币中不是每出一个区块,也要构建一颗Merkle tree吗,那个为什么没有这个问题?

比特币中的Merkle tree构建完之后,是不会再改了,下次发布新的区块,再重新构建Merkle tree。比特币中构建Merkle tree也仅仅是几百到几千比交易而已,以太坊中如果采用,会是什么结果?

是要把所有的以太坊账户一起构建成一个Merkle tree,这个数目比之前的比特币的交易数目高出好几个数量级。


除了验证账户的数据之外,Merkle tree还有更重要的特性,维护全节点之间数据的一致性。各个全节点之间要保持状态的一致才行。这也是比特币中为什么要把根hash值写在块头中的原因,对于当前区块的状态,所有全节点要有一个共识。

所以,如果每个全节点简单在本地维护一个hash表,然后构建出一个Merkle tree来,这种方法是不行的。(hash表本身查找、更新效率很好,但是构建Merkle tree,效率太低)


我们能不能不要hash表,然后直接构建一个账户的Merkle tree,修改数据直接在Merkle tree中修改(每次只需要改Merkle tree中的一小部分),该方法可行吗?

问题:Merkle tree没有提供一个快速查找、更新的方法。

如果我们把所有的账户放在Merkle tree中,这个Merkle tree要不要排序?Sorted Merkle tree

不排序没有办法证明non-membership。

如果不规定叶结点中的排列顺序,这样构建出来的Merkle tree不是唯一的。相应的,根hash值也是不一样的。

比特币当中不也是不排序吗?比特币中每个全节点收到的交易顺序也是不一样的,但是最后是获得记账权的节点说了算。

希望能够设计出自己的加密货币,设计出更好的数据结构。

如果以太坊中这样做,需要将全节点维护的Merkle tree中发布到区块中,但是包含的发布的是所有账户的状态,不是仅仅是交易的状态。数量级差距。

所以,不排序的Merkle tree是不行的。


如果用Sorted Merkle tree,是不是就没有问题了?

以太坊账户也是随机产生的,如果新产生的账户,刚好在树叶子结点的中间位置,后面的叶子节点数目也会发生改变。又变成了每次产生一个Merkle tree。这样代价也太大了了。

插入和删除代价都太大了。


以太坊采用MPT结构,

数据结构trie(来自retrieval)字典树、前缀树。

特点:

1 trie 中每个节点的分支数目取决于 key 值中每个元素的取值范围。

以太坊地址是40个16进制的树,分叉数目叫做 branding factor,0~f + 1(结束标识符),共17个。

2 trie的查找效率取决于 key 的长度,key的值越长,查找需要访问的内存次数就越多。

以太坊中的地址的键值都是一样长的。(比特币和以太坊的地址是不通用的,格式是不一样的)

3 如果用hash表来进行账户的存储,从理论上说,有可能存在hash碰撞,trie中是不会出现碰撞。

4 不论输入怎么打乱顺序,最后构成的 trie 是同一棵树。

5 更新的局部性(每次一笔交易,只有绝少数账户的信息会发生变化,所以,更新操作的局部性很重要)(注:上图中只画出来key,没有画出value)

缺点:

直观上可以看到,树结构深。

将单个节点进行合并,可以降低存储和查找的开销。


Patricia tree / Paticia trie

经过了路径压缩的前缀树。

访问内存的次数大大减少,效率提高。

但是,如果新插入一个单词,原来的路径可能需要拓展出来。

路径压缩在什么情况下效果比较明显?

键值分布比较稀疏的情况下,效果比较好。

以太坊中键值是地址,以太坊的地址是160位,为 $2^{160}$。

hash碰撞是可能存在的,地址的分布要足够长,分布足够稀疏,这样才不会产生碰撞,这是去中心化系统防止碰撞的唯一办法。

标签:03,hash,状态,以太,tree,Merkle,ETH,区块,节点
From: https://www.cnblogs.com/yangyi215/p/17367677.html

相关文章

  • CF1034D Intervals of Intervals 题解
    传送门CF1034DIntervalsofIntervals题目大意有\(n\)个线段,第\(i\)个是\([a_i,b_i]\)。定义区间\([l,r]\)的价值是第\(l\)个线段到第\(r\)个线段的并的长度。找出\(k\)个不同的区间,使得总价值最大。输出最大总价值。\(1\len\le3\times10^5,1\lek\le......
  • 2、go程序接入prometheus
    参考:https://prometheus.io/docs/guides/go-application/go默认基础指标packagemainimport( "net/http" "github.com/prometheus/client_golang/prometheus/promhttp")funcmain(){ http.Handle("/metrics",promhttp.Handler()) http.......
  • 03 BTC-协议
    《区块链技术与应用》课程链接:https://www.bilibili.com/video/BV1Vt411X7JF/?spm_id_from=333.337.search-card.all.click03BTC-协议目录03BTC-协议数字货币的需要解决的两个主要问题共识机制如果央行(中心化)发行数字货币,使用央行的私钥进行签名,大家交易的时候使用央行......
  • echarts 5.x 如果legend设置selected时,legend需要单击两次才能切换状态
    在第一组的selected里面先进行声明,在当前组再进行一次声明就可以了。 legend:[    {     show:true,     x:'center',     y:'0',     data:['日平均气温(℃)','日平均室温(℃)'],     textStyle:{......
  • 03 Docker高级实践
    第三章Docker高级实践目录第三章Docker高级实践一、Dockerfile1Dockerfile简介2Dockerfile快速入门3基础指令详解4运行时指令详解一、Dockerfile在这一部分我们来介绍一些Docker的高级内容:Dockerfile和Dockercompose。1Dockerfile简介什么是Dockerfile?类似于我......
  • MFC-GetHeaderCtrl获取列头指针
     CHeaderCtrl*phead=mylist4.GetHeaderCtrl();   ......
  • CSP2023-03
    第一题 直接满分了:#include<iostream>usingnamespacestd;constintN=1e6;intn,a,b;intpanduan(intx1,inty1,intx2,inty2,inta,intb){intc,k;if(x2<0||y2<0||x1>a||y1>b)return0;//在外侧else{......
  • 当前标识(IIS APPPOOL\XX)没有对“C:\Windows\Microsoft.NET\Framework64\4.0.30
    当前标识(IISAPPPOOL\WMS.APP)没有对“C:\Windows\Microsoft.NET\Framework64\v4.0.30319\TemporaryASP.NETFiles”的写访问权限。解决此问题为在使用Windows的IIS搭建服务器时,遇到的问题。在网上尝试了各种解决方法后,终于找到了一个可以解决问题的方法,以管理员身份运行命令......
  • Pod常见状态分析
    常见状态和原因kube-schedulerPending:调度不成功kubeletImagePullBackOff:镜像拉取失败Running:容器已创建并且启动Ready:容器可以提供服务CrashLoopBackOff:容器退出后kubelet拉起新容器如果没有配置livenessProbe或者readinessProbe,那么对应的检查默认成功。通过livenessProbe和r......
  • Elasticsearch专题精讲——What's new in 8.7?
    What'snewin8.7?https://www.elastic.co/guide/en/elasticsearch/reference/8.7/release-highlights.html,ortherversions:8.6 | 8.5 | 8.4 | 8.3 | 8.2 | 8.1 | 8.0Timeseries(TSDS)GA(时间序列)TimeSeriesDataStream(TSDS)isafeatureforoptimi......