Alert Source Discuss
🚧 Stagnant Standards Track: Core

EIP-1051: EVM 的溢出检查

Authors Nick Johnson <arachnid@notdot.net>
Created 2018-05-02
Discussion Link https://ethereum-magicians.org/t/eip-arithmetic-overflow-detection-for-the-evm/261

摘要

本 EIP 为 EVM 算术运算添加了溢出检查,以及两个用于检查和清除溢出标志的新操作码。

动机

如今,许多合约的正确运行依赖于检测和防止算术运算的溢出。由于 EVM 在 mod 2^256 整数上运行,并且不提供内置的溢出检测或预防,因此需要在每个算术运算上手动检查。

为了促进高效且安全的合约,我们提出了新的操作码,允许高效地检测溢出,可以定期检查溢出,而不是在每次操作后都检查。

规范

EVM 状态中添加了两个新标志:溢出 (ovf) 和有符号溢出 (sovf)。

在以下情况下,将设置 ovf 标志:

  • ADD (0x01) 操作码,将两个输入都视为无符号整数时,产生超过 2^256 - 1 的理想输出。
  • SUB (0x03) 操作码,将两个输入都视为无符号整数时,产生小于 0 的理想输出。
  • MUL(0x02) 操作码,将两个输入都视为无符号整数时,产生超过 2^256 - 1 的理想输出。

每当设置 ovf 标志时,也会设置 sovf 标志,此外,在以下情况下也会设置:

  • ADD 操作码的两个输入具有相同的 MSB 时,导致输出具有不同的 MSB(例如,(+a) + (+b) = (-c)(-a) + (-b) = (+c))。
  • SUB 操作码发生,并且结果与减数(第二个参数)具有相同的 MSB 时(例如,(+a) - (-b) = (-c)(-a) - (+b) = (+c))。
  • MUL 操作码的两个输入都为正数时,产生负数输出。
  • MUL 操作码的两个输入都为负数时,产生负数输出。
  • MUL 操作码的一个输入为负数,另一个输入为正数时,产生正数输出。

添加了一个新的操作码 OFV,编号为 0x0c。此操作码从堆栈中获取 0 个参数。执行时,如果设置了 ovf 标志,则压入 1,否则压入 0。然后将 ovf 标志设置为 false。

添加了一个新的操作码 SOVF,编号为 0x0d。此操作码从堆栈中获取 0 个参数。执行时,如果设置了 sovf 标志,则压入 1,否则压入 0。然后将 sovf 标志设置为 false。

理由

任何实施溢出保护的更改都需要保留现有合约的行为,这排除了对算术运算本身进行的许多更改。一种选择是提供一个启用溢出保护的操作码,如果在发生溢出时导致抛出或回退。但是,这限制了处理溢出的方式。

相反,我们复制了现实世界 CPU 的功能,它们通常实现“进位”和“溢出”标志。

由于有符号溢出可能不会导致无符号溢出,因此有必要为有符号和无符号溢出设置单独的标志。

向后兼容性

此 EIP 不会引入向后兼容性问题。

测试用例

待定

实施

待定

版权

CC0 下放弃版权及相关权利。

Citation

Please cite this document as:

Nick Johnson <arachnid@notdot.net>, "EIP-1051: EVM 的溢出检查 [DRAFT]," Ethereum Improvement Proposals, no. 1051, May 2018. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-1051.