本文介绍了在合约创建时对EOF格式(EIP-3540)合约代码进行验证的新特性,以确保代码的正确性,拒绝包含不完整PUSH数据或未定义指令的合约。该项更改旨在将代码有效性纳入共识,同时提供向前兼容性,允许未来新指令的定义,并简化EVM的执行路径。
在合约创建时引入代码验证,以支持EOF格式(EIP-3540)的合约。拒绝包含被截断的 PUSH
数据或未定义指令的合约。遗留字节码(即不符合EOF格式的代码)不受此更改影响。
当前现有合约不需要正确性的验证,EVM实现可以决定如何处理截断的字节码或未定义指令。此更改旨在将代码有效性纳入共识,使有关字节码的推理变得更加简单。此外,EVM实现可能需要更少的路径来决定哪个指令在当前执行上下文中是有效的。
如果希望在不提升EOF版本的情况下引入新指令,已经部署的未定义指令可能会破坏此类合约,因为某些指令的行为可能会改变。拒绝部署未定义指令允许以提升或不提升EOF版本的方式引入新指令。
EOF1格式提供以下向前兼容性特性:
此功能在启用EIP-3540的同一区块中引入,因此每个符合EOF1的字节码必须根据这些规则进行验证。
CALLCODE
(0xf2) 和 SELFDESTRUCT
(0xff),以及在EIP-3540中弃用的指令,被认为无效,其操作码未定义。(注意 还有更多已在EOF中弃用和拒绝的指令,具体由单独的EIP规定)INVALID
(0xfe) 被视为已定义。允许 PUSH
指令的隐式零立即数据会为EVM实现带来低效率,而没有任何实际用例(EVM无法观察到代码末尾的 PUSH
指令的值)。此EIP要求所有立即字节必须明确定义在代码中。
弃用的指令 CALLCODE
(0xf2) 和 SELFDESTRUCT
(0xff) 已从 valid_opcodes
列表中删除,以防止将来使用。
BLOCKHASH
指令被EIP-2935中引入的系统合约良好替代。然而,尽管引入了替代方案,该操作码仍未被弃用。此操作码将在EOF中保持有效,以避免与遗留字节码区别。
此更改对向后兼容性没有风险,因为它与EIP-3540同时引入。验证不涵盖遗留字节码(即不符合EOF格式的代码)。
每个案例应通过提交EOF容器进行EOF合约创建测试(具体规范在另一个EIP中)。每个案例应测试在不同索引处放置的代码部分。
INVALID
的EOF代码PUSH
指令结束的EOF代码## 以下范围是由上海执行规范指定的。
## 注意:range(s, e) 不包括 e,因此 +1
shanghai_opcodes = [
*range(0x00, 0x0b + 1),
*range(0x10, 0x1d + 1),
0x20,
*range(0x30, 0x3f + 1),
*range(0x40, 0x48 + 1),
*range(0x50, 0x5b + 1),
0x5f,
*range(0x60, 0x6f + 1),
*range(0x70, 0x7f + 1),
*range(0x80, 0x8f + 1),
*range(0x90, 0x9f + 1),
*range(0xa0, 0xa4 + 1),
# 注意:0xfe 被视为已分配。
0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xfa, 0xfd, 0xfe, 0xff
]
## 删除在此和EIP-3540中被弃用和拒绝的操作码
rejected_in_eof = [
0x38, 0x39, 0x3b, 0x3c, 0x3f, 0x5a, 0xf1, 0xf2, 0xf4, 0xfa, 0xff
]
valid_opcodes = [op for op in shanghai_opcodes not in rejected_in_eof]
immediate_sizes = 256 * [0]
immediate_sizes[0x60:0x7f + 1] = range(1, 32 + 1) # PUSH1..PUSH32
## 在无效代码上引发 ValidationException
def validate_instructions(code: bytes):
# 注意,EOF1已经通过代码部分要求进行了断言
assert len(code) > 0
pos = 0
while pos < len(code):
# 确保操作码有效
opcode = code[pos]
if opcode not in valid_opcodes:
raise ValidationException("未定义的操作码")
# 跳过立即数据
pos += 1 + immediate_sizes[opcode]
# 确保最后一条指令的立即数不超过代码末尾
if pos != len(code):
raise ValidationException("截断的立即数")
参见 EIP-3540 的安全考虑。
版权及相关权利通过 CC0 放弃。
- 原文链接: github.com/ethereum/EIPs...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!