EIP663: SWAPN、DUPN 和 EXCHANGE 指令

本文介绍了在以太坊虚拟机(EVM)中引入三条新的指令 SWAPNDUPNEXCHANGE 以提升栈操作的灵活性,这三条指令允许访问深达256个项的栈,简化了编译器的设计,并支持更复杂的函数调用。文章详细阐述了这些新指令的规范、执行规则、兼容性及安全性考虑。

摘要

目前,SWAP*DUP* 指令的堆栈深度限制为 16。引入三条新指令,SWAPNDUPNEXCHANGE,以消除此限制并允许在更高的深度访问堆栈。

动机

虽然堆栈深度为 1024 项,但只能轻松访问顶部 16 项。通过手动将更多局部变量保留在内存中或通过编译器的“堆栈到内存提升”功能,可以支持更多局部变量。这可能导致复杂且低效的代码。

此外,在 EVM 上实现更高级的构造(例如函数)将导致输入和输出参数列表,以及返回的指令偏移量。

这些参数(或堆栈项)的数量可能轻易超过 16,因此可能需要编译器额外小心以确保它们都能被访问。

最后,交换堆栈中除第一个和第 N 项以外的项对实施堆栈调度算法的编译器非常重要(堆栈机器的寄存器分配类比),该算法在给定变量和使用分析的情况下试图最小化堆栈流量。

引入 SWAPNDUPNEXCHANGE 将为编译器提供简化访问深层堆栈项的选项。

规范

我们引入三条新指令:

  1. DUPN (0xe6)
  2. SWAPN (0xe7)
  3. EXCHANGE (0xe8)

如果代码是遗留字节码,这些指令中的任何一条都会导致 异常中止。 (注意:这意味着行为不变。)

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

  1. 指令后跟一个 8 位立即数值,我们称之为 imm,其值可以为 0 到 255。
    1. DUPNSWAPN 的情况下,引入变量 n 等于 imm + 1
    2. EXCHANGE 的情况下,引入变量 n 等于 imm >> 4 + 1,以及变量 m 等于 imm & 0x0F + 1(即 imm 的前两个半字节,转换为一索引)。
  2. 代码验证扩大以检查没有相对跳转指令 (RJUMP/RJUMPI/RJUMPV) 指向 DUPNSWAPNEXCHANGE 的立即数值。
  3. EIP-5450 的堆栈验证算法得到扩展:
    1. DUPN 前,如果当前堆栈高度小于 n,则代码无效。在 DUPN 后,堆栈高度增加。
    2. SWAPN 前,如果当前堆栈高度小于 n + 1,则代码无效。在 SWAPN 后,堆栈高度不变。
    3. EXCHANGE 前,如果当前堆栈高度小于 n + m + 1,则代码无效。在 EXCHANGE 后,堆栈高度不变。
  4. 执行规则:
    1. DUPN:第 n 项堆栈项被复制到堆栈顶部。(注意:这里使用的是 1 基索引。)
    2. SWAPN:第 n + 1 项堆栈项与堆栈顶部交换。
    3. EXCHANGE:第 n + 1 项堆栈项与第 n + m + 1 项堆栈项交换。

所有三条指令的 gas 成本设定为 3。

原因

使用立即数参数

允许动态选择要交换、复制或交换的参数可能会阻止对堆栈内容的静态分析。由于静态分析是安全审计人员的重要工具,我们希望尽可能简化他们的工作。因此,操作数需要一个不是动态性质的立即数参数。

仅限 EOF

由于该指令依赖于立即数参数编码,因此只能在 EOF 内启用。在遗留字节码中,该编码可能会与跳转目标分析相矛盾。

立即数参数的大小

对于 DUPNSWAPN,考虑使用 16 位大小以适应堆栈空间的 1024 项,但是:

  1. 这将需要一个额外的限制/检查(n < 1024)。
  2. 256 的深度相比当前的 16 是一个很大的改进,而额外字节的开销会使它的使用价值降低。

EXCHANGE 同样,提议的方案允许寻址 32 项。

gas 成本

这些操作的 gas 成本与现有的 DUP*SWAP* 指令相同,因为它们仅作为指针交换实现。

EXCHANGESWAPN

如前所述,EXCHANGE 对实现堆栈调度算法的编译器非常重要。具体而言,在堆栈项计划在堆栈更深处被消耗的情况下(例如,堆栈中的第 3 项需要移至第 2 个位置以供下一个操作使用),目前需要三条指令 SWAP2 SWAP3 SWAP2。然而,在 EVM 实现中,该实现仅是一个指针交换,因此可以在没有额外运行时成本的情况下以一条指令实现。

向后兼容性

这对向后兼容性没有影响,因为操作码之前未被分配,并且该功能仅在 EOF 中启用。

测试用例

给定 stack[] 是一个以 0 为基础的数据结构,nmimm 根据规范定义:

  • DUPN immstack_height < n 的情况下验证失败。
  • SWAPN immstack_height < n + 1 的情况下验证失败。
  • EXCHANGE immstack_height < n + m + 1 的情况下验证失败。
  • DUPN imm 应增加函数的最大堆栈高度。如果最大堆栈高度超过 1023 的限制,则验证失败。
  • DUPN immSWAPN immEXCHANGE imm 在运行时如果可用的 gas 少于 3 则失败。
  • DUPN imm 应复制 stack[n - 1] 项并将其推送到堆栈
  • SWAPN imm 应交换 stack[n]stack[stack.top()]
  • EXCHANGE imm 应交换 stack[n]stack[n + m]

安全考虑

作者未发现此处引入的任何附加风险。EVM 堆栈固定为 1024 项,大多数实现始终将其保存在内存中。这一变化将增加通过单一指令可访问的堆栈项数量。

版权

由于 CC0,版权和相关权利已放弃。

  • 原文链接: github.com/ethereum/EIPs...
  • 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
ethereum
ethereum
江湖只有他的大名,没有他的介绍。