关于无国籍以太坊倡议的注释:
由于所有贡献者都适应了怪异的时间表的生活,因此(可以理解的是)在2020年下半年有所放缓。但是,随着生态系统逐渐接近宁静和ETH1/ETH2合并,无国籍以太坊的工作将变得越来越相关和影响力。预计未来几周的年终无状态以太坊回顾性。
让我们再一次重新审核一次:无国籍以太坊的最终目标是删除 要求 以太坊节点始终保留更新的状态trie的完整副本,而允许状态更改依靠(较小的)数据证明特定交易的数据正在实现有效的更改。这样做可以解决以太坊的主要问题;到目前为止,这个问题只能通过改进的客户端软件进一步推出: 国家增长。
无国籍以太坊所需的默克尔证明称为“证人”,它通过提供所有的国家证明了国家的变化 不变 中间哈希到达新的有效状态根。从理论上讲,证人比完整的以太坊状态(最多需要6个小时才能同步)要小得多,但他们仍然是 大得多 比一个块(需要在短短几秒钟内传播到整个网络)。因此,倾斜证人的规模对于将无国籍以太坊降至最低可行的效果至关重要。
就像以太坊状态本身一样,证人中的许多额外(数字)重量都来自智能合同代码。如果交易拨打了特定合同,则证人将默认情况下需要包括合同字节码 完整 与证人。代码Merkelization是一种一般技术,可以减轻证人中智能合约代码的负担,因此合同电话只需要包括它们“触摸”的代码位以证明其有效性。仅凭这项技术,我们可能会看到证人的大幅减少,但是将智能合同代码分解为字节大小的块时,有很多细节需要考虑。
什么是字节码?
在分开合同字节码时,需要考虑一些权衡。我们最终需要问的问题是“代码块有多大?” – 但是,就目前而言,让我们看一些非常简单的智能合约中的一些真实字体,以了解它是什么:
pragma solidity >=0.4.22 0.7.0; contract Storage { uint256 number; function store(uint256 num) public { number = num; } function retrieve() public view returns (uint256){ return number; } }
当编译此简单的存储合同时,它将变成旨在运行“内部” EVM的机器代码。在这里,您可以看到上面显示的相同简单存储合同,但符合单个EVM说明(OPCODES):
PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH1 0xF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x4 CALLDATASIZE LT PUSH1 0x32 JUMPI PUSH1 0x0 CALLDATALOAD PUSH1 0xE0 SHR DUP1 PUSH4 0x2E64CEC1 EQ PUSH1 0x37 JUMPI DUP1 PUSH4 0x6057361D EQ PUSH1 0x53 JUMPI JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x3D PUSH1 0x7E JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 DUP3 DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST PUSH1 0x7C PUSH1 0x4 DUP1 CALLDATASIZE SUB PUSH1 0x20 DUP2 LT ISZERO PUSH1 0x67 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 ADD SWAP1 DUP1 DUP1 CALLDATALOAD SWAP1 PUSH1 0x20 ADD SWAP1 SWAP3 SWAP2 SWAP1 POP POP POP PUSH1 0x87 JUMP JUMPDEST STOP JUMPDEST PUSH1 0x0 DUP1 SLOAD SWAP1 POP SWAP1 JUMP JUMPDEST DUP1 PUSH1 0x0 DUP2 SWAP1 SSTORE POP POP JUMP INVALID LOG2 PUSH5 0x6970667358 0x22 SLT KECCAK256 DUP13 PUSH7 0x1368BFFE1FF61A 0x29 0x4C CALLER 0x1F 0x5C DUP8 PUSH18 0xA3F10C9539C716CF2DF6E04FC192E3906473 PUSH16 0x6C634300060600330000000000000000
正如所解释的 上一篇文章,这些OpCode指令是EVM堆栈体系结构的基本操作。他们定义了简单的存储合同及其包含的所有功能。您可以在 混音IDE (请注意,上面的机器代码是存储.sol的示例 部署后,而不是固体编译器的输出,它将具有一些额外的“引导” opcodes)。如果您将眼睛不合时宜,并想象一个物理堆栈机和OpCode卡上的分步计算,那么在移动堆栈的模糊中,您几乎可以看到固体合同中列出的功能轮廓。
每当合同收到消息调用时,此代码都会在每个以太坊节点内运行,验证网络上的新块。为了立即提交以太坊的有效交易,需要一份合同字节码的完整副本,因为从头到尾运行该代码是获得(确定性)输出状态和关联哈希的唯一方法。
记住,无国籍以太坊的目的是改变这一要求。假设您要做的就是调用该功能 取回() 仅此而已。描述该功能的逻辑只是整个合同的一个子集,在这种情况下,EVM仅真正需要两个 基本块 OpCode指令的返回所需值:
PUSH1 0x0 DUP1 SLOAD SWAP1 POP SWAP1 JUMP, JUMPDEST PUSH1 0x40 MLOAD DUP1 DUP3 DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN
在无国籍范式中,就像证人提供了未接触状态的缺失哈希一样,证人还应为未执行的机器代码提供缺失的哈希,以便无状态的客户只需要合同的一部分,它正在执行。 。
代码的证人
以太坊中的智能合约生活在外部账户的同一地点:作为巨大的单重状态Trie中的叶子节点。合同在许多方面与人类使用的外部账户没有什么不同。他们有一个地址,可以提交交易,并保持以太和任何其他令牌的平衡。但是合同帐户很特别,因为它们必须包含自己的程序逻辑(代码)或其哈希。另一个相关的Merkle-Patricia trie,称为 Storagetie 保持主动合同在执行过程中使用其业务的任何变量或持续状态。
这位证人可视化提供了一种很好的理解,即代码对减少证人的规模的重要意义。看到大块的彩色正方形和比Trie中的所有其他元素大得多?这是一份全部智能合同字节码。
旁边,略低于持续状态 Storagetie,例如ERC20平衡映射或ERC721数字项目所有权。由于这是证人的示例,而不是完整的状态快照,因此这些示例主要是由中间哈希制成的,并且仅包括无状态客户端证明下一个块所需的更改。
代码Merkleization旨在将大量代码分开,并替换字段 Codehash 在一个以太坊的帐户中,有另一个默克尔·特里(Merkle Trie)的根源,恰当地命名 Codetrie。
值得在哈希中的重量
让我们看一个例子 这个以太坊工程小组视频,它使用一个 ERC20令牌 合同。由于您听说过的许多令牌都是按照ERC-20标准制作的,因此这是了解代码Merkleization的良好现实环境。
由于字节码很长且不守规矩,所以让我们使用一个简单的速记,用任何一个代替四个字节(8个六二甲体字符) 。 或者 x 字符,后者表示执行特定函数所需的字节码(示例, erc20.transfer() 始终使用功能)。
在ERC20示例中,调用 转移() 功能使用整个智能合约的一半以下:
XXX.XXXXXXXXXXXXXXXXXX.......................................... .....................XXXXXX..................................... ............XXXXXXXXXXXX........................................ ........................XXX.................................XX.. ......................................................XXXXXXXXXX XXXXXXXXXXXXXXXXXX...............XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.................................. .......................................................XXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXX..................................X XXXXXXXX........................................................ ....
如果我们想将该代码分成64个字节的块,那么在41个块中只有19个要执行无状态的块 转移() 交易,其余所需的数据来自证人。
|XXX.XXXXXXXXXXXX|XXXXXX..........|................|................ |................|.....XXXXXX.....|................|................ |............XXXX|XXXXXXXX........|................|................ |................|........XXX.....|................|............XX.. |................|................|................|......XXXXXXXXXX |XXXXXXXXXXXXXXXX|XX..............|.XXXXXXXXXXXXXXX|XXXXXXXXXXXXXXXX |XXXXXXXXXXXXXXXX|XXXXXXXXXXXXXX..|................|................ |................|................|................|.......XXXXXXXXX |XXXXXXXXXXXXXXXX|XXXXXXXXXXXXX...|................|...............X |XXXXXXXX........|................|................|................ |....
比较32个字节块计划中的81个块中的31个:
|XXX.XXXX|XXXXXXXX|XXXXXX..|........|........|........|........|........ |........|........|.....XXX|XXX.....|........|........|........|........ |........|....XXXX|XXXXXXXX|........|........|........|........|........ |........|........|........|XXX.....|........|........|........|....XX.. |........|........|........|........|........|........|......XX|XXXXXXXX |XXXXXXXX|XXXXXXXX|XX......|........|.XXXXXXX|XXXXXXXX|XXXXXXXX|XXXXXXXX |XXXXXXXX|XXXXXXXX|XXXXXXXX|XXXXXX..|........|........|........|........ |........|........|........|........|........|........|.......X|XXXXXXXX |XXXXXXXX|XXXXXXXX|XXXXXXXX|XXXXX...|........|........|........|.......X |XXXXXXXX|........|........|........|........|........|........|........ |....
从表面上看,较小的块比大的块更有效,因为 大部分是空的 块不那么频繁。但是在这里我们需要记住,未使用的代码也有成本:每个未执行的代码块都被一个哈希所取代 固定尺寸。较小的代码块意味着未使用的代码的大量哈希数量,这些哈希可能会大至32个字节(或小至8个字节)。您可能此时可能会惊呼“ hol’up!如果代码块的哈希标准尺寸为32个字节,则如何将32个代码替换为32个字节!
回想一下合同代码是 Merkleized,这意味着所有哈希都链接在一起 Codetrie – 我们需要验证一个块的根哈希。在那个结构中,任何 顺序 未经执行的块只需要一个哈希,无论有多少。也就是说,一个哈希可以站在一个潜在的大肢体上,这些肢体在merkleized code trie上充满了顺序的块hashes,只要无需编码执行即可。
我们必须收集其他数据
我们一直在建立的结论有点像一个反高潮:理论上没有“最佳”代码构建方案。设计选择,例如修复代码块和哈希的大小 取决于收集的有关“现实世界”的数据。每项智能合约都会以不同的方式融合,因此研究人员负担选择为观察到的主网活动提供最大效率增长的格式。那是什么意思?
一件事可能表明代码构建方案的有效效率 开销,哪个回答了一个问题:“在此证人中包含了执行代码以外的多少额外信息?”
我们已经有 一些有希望的结果,使用 专用工具 由Consensys Teamx Research团队的Horacio Mijail开发,该团队的间接数量高达25% – 一点也不糟糕!
简而言之,数据表明,大小较小的块尺寸比较大的块更有效,尤其是使用较小的哈希(8 bytes)。但是这些早期数字绝不是全面的,因为它们仅代表最近的100个块。如果您正在阅读本文并有兴趣通过收集更多实质性的代码Merkleization数据来为无状态以太坊倡议做出贡献,请在Ethresear.ch论坛上介绍自己,或者在ETH1X/2研究Discord上介绍#code-merkleization渠道!
与往常一样,如果您有与“ 1.x文件”以及Twitter上的无状态以太坊,DM或@gichiba有关的问题,反馈或请求。