EIP-140: REVERT 指令
Authors | Alex Beregszaszi (@axic), Nikolai Mushegian <nikolai@nexusdev.us> |
---|---|
Created | 2017-02-06 |
简单总结
REVERT
指令提供了一种停止执行并恢复状态更改的方法,无需消耗所有提供的 gas,并且能够返回原因。
摘要
REVERT
指令将停止执行,回滚到目前为止所做的所有状态更改,并提供一个指向内存区域的指针,该指针可以被解释为错误代码或消息。 在此过程中,它不会消耗所有剩余的 gas。
动机
目前这是不可能的。 从合约内部恢复交易有两种实用的方法:耗尽 gas 或执行无效指令。 这两种选择都会消耗所有剩余的 gas。 此外,恢复 EVM 执行意味着所有更改(包括 LOG)都会丢失,并且无法传达中止 EVM 执行的原因。
规范
在 block.number >= BYZANTIUM_FORK_BLKNUM
的区块上,REVERT
指令在 0xfd
处引入。 它需要两个堆栈项,顶部项是 memory_offset
,后跟 memory_length
。 它不会产生任何堆栈元素,因为它会停止执行。
REVERT
在内存和内存成本方面的语义与 RETURN
的语义相同。 memory_offset
和 memory_length
给出的字节序列在下文中称为“错误消息”。
REVERT
的效果是执行中止,被视为失败,并且状态更改被回滚。 错误消息将在 returndata 缓冲区中提供给调用者,并且也会被复制到输出区域,即它以与处理常规返回数据相同的方式进行处理。
REVERT
指令的成本等于 RETURN
指令的成本,即回滚本身不会消耗所有 gas,合约只需支付内存费用。
如果剩余的 gas 不足以支付 REVERT
的成本,或者存在堆栈下溢,则 REVERT
指令的效果将等于常规的 out of gas 异常,即它将消耗所有 gas。
与所有其他失败一样,调用操作码在被调用者中的 REVERT
操作码之后,在堆栈上返回 0
。
如果在 CREATE
或 CREATE2
调用的上下文中使用了 REVERT
,则不会部署任何代码,0
会被放置在堆栈上,并且错误消息可以在 returndata 缓冲区中使用。
此 EIP 未定义可选提供的内存部分的内容,但它是另一个信息性 EIP 的候选对象。
向后兼容性
此更改对过去创建的合约没有影响,除非它们包含 0xfd
作为指令。
测试用例
6c726576657274656420646174616000557f726576657274206d657373616765000000000000000000000000000000000000600052600e6000fd
应该:
- 返回
0x726576657274206d657373616765
作为REVERT
数据, - 键
0x0
处的存储应保持未设置状态,并且 - 总共使用 20024 gas。
版权
版权及相关权利通过 CC0 放弃。
Citation
Please cite this document as:
Alex Beregszaszi (@axic), Nikolai Mushegian <nikolai@nexusdev.us>, "EIP-140: REVERT 指令," Ethereum Improvement Proposals, no. 140, February 2017. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-140.