在上一篇关于以太坊1.x的文章中,我们对Eth 1.x研究的起源、得失因素以及一些有可能的解决方案做到了详细总结。在上篇文章的结尾我们提及了“无状态”以太坊的概念,而在本文中我们将更进一步详尽阐述无状态客户端。
无状态(stateless)是Eth 1.x研究的新方向,因此我们将展开一次比较了解的探析,以便对未来有可能面对的挑战和可能性了然于胸。如果读者有兴趣更进一步理解,我会尽可能获取涉及资源的链接。
什么是“状态”?要说明无状态以太坊,我们首先必须解读“状态”(state)的概念。当我们提及“状态”时,一般是指“事务的状态”。以太坊的原始“状态”叙述了所有账户和余额的当前状态,以及在EVM中部署和运营的所有智能合约的集体历史。
链上每个最后确认的区块,都有且只有一个状态,这是由网络中的所有参与者联合证实的。每当有新的区块被加到到链上,状态都会随之转变且改版。
在Eth 1.x研究语境中,我们不仅要告诉状态是什么,还要告诉它在协议(据黄皮书中的定义)和大多数客户端构建(如geth、parity、trinity、besu等)中是如何展现出的。什么是Trie?以太坊所用于的数据结构叫做Merkle Patricia Trie。有意思的是,‘Trie’最初撷取自‘retrieval’一词,但大多数人会将其发音为‘try’,以区别于‘tree’。返回正题,关于MPT数据结构,我们必须理解:在trie的一端,是叙述状态(值节点)的所有特定数据片段。
数据可以是特定帐户的余额,也可以是存储在智能合约中的变量(例如某种ERC-20通证的总供应量)。Trie的中间则是分支节点,通过哈希运算将所有值串联在一起。分支节点是包括其子节点哈希的数组(array),每个分支节点随后再度经过哈希并归属于其父节点的数组中。
这一连串的哈希最后不会抵达trie另一端的一个状态根节点。在上面的修改图示中,我们可以看见一些数值,以及获得这些值的路径。
例如,为了获得V-2,我们经历了1,3,3,4的路径。同理,V-3可通过路径3,2,3,3来提供。必须留意的是,本例中的路径长度一直为4个字符,并且要提供某个值只有一条能用路径。
该结构具备确定性和可加密检验的最重要特性:分解状态根的唯一方法就是通过计算出来状态的每个分开数据段,如此一来,通过核对根哈希和前序哈希(Merkle证明),就可以精彩证明两个状态是完全相同的。反之,我们也无法用完全相同的六根哈希创立两个有所不同的状态,任何用于有所不同值改动状态的尝试都将造成有所不同的状态根哈希。以太坊通过引进新的节点类型,拓展节点(extension nodes)和叶节点(leaf nodes)来提高效率,优化trie结构。
通过将路径的一些部分编码为节点,如此一来trie就不会更为灵活。在这种优化后的MPT结构中,每个节点都必须在多个先前节点分享的路径传输部分或数值(若有适当,由路径的其他部分后缀)之间展开自由选择。只不过是完全相同的数据和的组织,但是这个trie结构只必须9个节点而非18个节点。
看上去或许更加有效率,但事后显然,实质上这并不是最理想的。我们将在下一节辩论原因。要提供状态的特定部分(例如账户当前的ETH余额),必须从状态根开始,沿着trie的路径从一个节点到另一个节点,直到超过所需的值。在每个节点上,路径中的字符用来要求下一个目的节点,就看起来一个用作导航系统哈希数据结构的观测棒。
而在以太坊确实用于的版本中,路径是长度为64个字符(256位)的地址哈希,值是RLP编码数据[1]。分支节点是包括17个元素的数组(其中有16个是每个有可能的十六进制字符,剩下一个则为值),而叶节点和拓展节点包括2个元素(一个是部分路径,另一个是下一个子节点的值或哈希)。要理解更加多细节,可以网页以太坊的wiki页面[2],或者,如果你讨厌特地钻研,那么这篇文章获取了一个有趣的Python DIY trie锻炼[3](意外的是这篇文章早已过时了)。在数据库中用于Trie写这里我们应当警告自己,trie结构只是一个抽象化的概念。
这是一种将以太坊状态的整体包成统一结构的方法。该结构必须在客户端的代码中构建,并存储在磁盘上(或者产于在全球的数千个磁盘中)。这意味著要使用多维trie结构并将其映射到一个普通的只解读[key,value]对的数据库中。
在大多数以太坊客户端(turbo-geth除外)中,MPT是通过为每个节点创立有所不同的[key, value]对来构建的,其中value是节点本身,key是该节点的哈希。
本文关键词:中欧体育,中欧体育(zoty),zoty中欧体育
本文来源:中欧体育-www.cjsb158.com