Alert Source Discuss
Standards Track: Core

EIP-7480: EOF - 数据段访问指令

用于读取 EOF 容器数据段的指令

Authors Andrei Maiboroda (@gumb0), Alex Beregszaszi (@axic), Paweł Bylica (@chfast)
Created 2023-08-11
Discussion Link https://ethereum-magicians.org/t/eip-7480-eof-data-instructions/15414
Requires EIP-3540, EIP-3670

摘要

引入了四个新的指令,允许读取 EOF 容器的数据段:DATALOAD 将 32 字节的字加载到堆栈,DATALOADN 将 32 字节的字加载到堆栈,其中该字通过静态立即参数寻址,DATASIZE 加载数据段大小,DATACOPY 将数据段的一部分复制到内存。

动机

代码和数据之间的明确分离是 EOF1 的主要特性之一。数据段可以包含任何内容,例如编译器的元数据,但为了使其对智能合约有用,EVM 必须具有允许从数据段读取的指令。先前存在的用于字节码检查的指令(CODECOPYCODESIZE 等)在 EOF1 中已弃用,不能用于此目的。

DATALOADDATASIZEDATACOPY 指令模式遵循用于读取其他类型数据(即返回数据和调用数据)的现有指令的设计。

DATALOADNDATALOAD 的优化版本,其中要读取的数据偏移量在编译时设置,因此无需在运行时进行验证,这使得该指令更便宜。

规范

我们在激活 EIP-3540 的同一区块号上引入四个新指令:

  1. DATALOAD (0xd0)
  2. DATALOADN (0xd1)
  3. DATASIZE (0xd2)
  4. DATACOPY (0xd3)

如果代码是旧版字节码,则所有这些指令都会导致异常停止。(注意:这意味着行为没有改变。

如果代码是有效的 EOF1,则以下执行规则适用:

DATALOAD

  1. 从堆栈中弹出值 offset
  2. 从数据段中读取 [offset:offset+32] 段,并将其作为 32 字节的值推送到堆栈。
  3. 如果 offset + 32 大于数据段大小,则数据段结束后面的字节设置为 0。
  4. 扣除 4 gas。

DATALOADN

  1. 有一个立即参数 offset,编码为 16 位无符号大端值。
  2. 不从堆栈中弹出任何内容。
  3. 从数据段中读取 [offset:offset+32] 段,并将其作为 32 字节的值推送到堆栈。
  4. 扣除 3 gas。

通过代码验证,保证 [offset:offset+32] 在数据边界内。

DATASIZE

  1. 不从堆栈中弹出任何内容。
  2. 将活动容器的数据段的大小推送到堆栈。
  3. 扣除 2 gas。

DATACOPY

  1. 从堆栈中弹出三个值:mem_offsetoffsetsize
  2. 执行内存扩展到 mem_offset + size 并扣除内存扩展成本。
  3. 扣除 3 + 3 * ((size + 31) // 32) gas 用于复制。
  4. 从数据段中读取 [offset:offset+size] 段,并将其写入从偏移量 mem_offset 开始的内存。
  5. 如果 offset + size 大于数据段大小,则对于数据段结束后面的字节,将复制 0 字节。

代码验证

我们扩展了代码段验证规则(如 EIP-3670 中定义的那样)。

  1. 如果任何 DATALOADN 的立即参数 offset 使得 offset + 32 大于数据段大小,则代码段无效,如容器头在部署之前中所示。
  2. RJUMPRJUMPIRJUMPV 立即参数值(跳转目标相对偏移量)验证:如果偏移量指向紧跟在 DATALOADN 指令之后的两个字节之一,则代码段无效。

理由

越界访问时的零填充

用于读取其他类型数据的现有指令在越界访问时隐式地用零填充,唯一的例外是返回数据复制。

避免异常失败是有益的,因为编译器可以采用诸如删除复制数据但之后从不访问此副本的代码之类的优化,但是只有在指令从没有其他副作用(如异常中止)时,这种优化才有可能。

缺少 EXTDATACOPY

EXTCODECOPY 指令在 EOF 合约中已弃用并被拒绝,并且在旧版中以 EOF 合约作为目标调用时,不会复制合约代码。已经考虑了替换指令 EXTDATACOPY,但为了缩小更改范围而决定不采用。

因此,不鼓励以前依赖 EXTCODECOPY 的纯数据合约,但是如果强烈需要,可以通过在未来的升级中引入 EXTDATACOPY 轻松地恢复对它们的支持。

向后兼容性

此更改不会对向后兼容性构成风险,因为它仅针对 EOF1 合约引入,对于这些合约,不允许部署未定义的指令,因此没有使用这些指令的现有合约。新的指令未针对旧版字节码(非 EOF 格式的代码)引入。

安全注意事项

这些新操作码的 Gas 成本与旧版 CODECOPY 指令相当。在 EOF 容器验证算法的实现过程中,必须仔细考虑它们。

版权

Copyright and related rights waived via CC0.

Citation

Please cite this document as:

Andrei Maiboroda (@gumb0), Alex Beregszaszi (@axic), Paweł Bylica (@chfast), "EIP-7480: EOF - 数据段访问指令," Ethereum Improvement Proposals, no. 7480, August 2023. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-7480.