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.