EIP-2327: BEGINDATA 操作码
Authors | Martin Lundfall (@MrChico) |
---|---|
Created | 2019-10-28 |
Discussion Link | https://ethereum-magicians.org/t/new-opcode-begindata/3727 |
简单总结
引入一个新的操作码 BEGINDATA
,它表示合约的剩余字节应被视为数据而不是合约代码,并且不能被执行。
摘要
智能合约通常直接在合约字节码中有效地存储数据。 示例包括构造函数参数、常量变量、编译器元数据以及初始化阶段的合约运行时。 目前,此类数据与普通字节码没有区别,并且 EVM 解释器仍在分析 JUMPDEST
。 此 EIP 在字节 0xb6
处引入了一个新的操作码 BEGINDATA
,它将剩余的字节码标记为数据,向 EVM 解释器、静态分析工具和链浏览器表明剩余的字节不代表操作码。
动机
BEGINDATA
操作码之前已作为 EIP Subroutines and Static Jumps for the EVM
EIP-615 的一部分提出,作为确定合约字节码中跳转表位置的一种方式。 这里它以自己的名义引入,以便将数据从合约的 JUMPDEST
分析中排除,从而不可能跳转到数据。 这使得静态分析工具更容易分析合约,允许反汇编程序、链浏览器和调试器不将数据显示为 INVALID 操作码的混乱,甚至可能对性能产生边际改进。 它还有助于可扩展性,因为它改进了来自其他链的交易的链上评估,因为代码是否符合特定模式的验证不需要进行完整的 jumpdest 分析来查看数据是否未被执行,因此不必符合该模式(由 optimism 项目使用)。 此外,它为诸如 EIP-1712 等建议铺平了道路,以禁止未使用的操作码、跳转表 EIP-615 以及禁止部署具有堆栈使用违规的合约的推测性提案。
规范
在计算合约的有效 JUMPDEST
时,一旦遇到第一个 BEGINDATA
,就停止分析。 换句话说:跳转到任何等于或大于第一个 BEGINDATA
位置的代码位置都会导致 BAD_JUMP_DESTINATION
错误。
如果在合约执行期间遇到 BEGINDATA
,则它具有与 STOP
相同的语义。 它使用 0 gas。
可以通过 CODECOPY
和 EXTCODECOPY
访问 BEGINDATA
之后的字节。 BEGINDATA
不影响 CODESIZE
或 EXTCODESIZE
。
理由
选择字节 0xb6
是为了与 EIP-615 对齐。
如果遇到 BEGINDATA
则 STOP
的选择有些随意。 另一种选择是用 out-of-gas 错误中止执行。
向后兼容性
该提案不会更改任何现有合约,除非它们当前的行为依赖于未使用操作码的使用。
由于合约从一开始就一直在使用数据,因此从某种意义上说,所有合约都在使用未使用的操作码, 但他们必须以在执行期间跳过并跳过的方式使用数据。 Solidity 编译器从未生成过这样的代码。 必须评估以其他方式创建的合约 是否可能具有这样的代码结构。
测试用例
测试用例应包括:
1) 一个合约跳转到目标地址 X
,其中 X
的 pc 值高于 BEGINDATA
操作码,并且 X
处的字节是 0x5b
。 这应该会因 BAD_JUMP_DESTINATION
错误而失败。
2) 一个合约遇到 BEGINDATA
操作码(应停止执行当前调用帧)
实现
暂无。
版权
在 CC0 下放弃版权及相关权利。
Citation
Please cite this document as:
Martin Lundfall (@MrChico), "EIP-2327: BEGINDATA 操作码 [DRAFT]," Ethereum Improvement Proposals, no. 2327, October 2019. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-2327.