EIP-5920: PAY 操作码
引入一个新的操作码 PAY,用于将以太币发送到一个地址,而不调用该地址的任何函数
Authors | Gavin John (@Pandapip1), Zainan Victor Zhou (@xinbenlv), Sam Wilson (@SamWilsn), Jochem Brouwer (@jochem-brouwer), Charles Cooper (@charles-cooper) |
---|---|
Created | 2022-03-14 |
Requires | EIP-214, EIP-2929, EIP-7523 |
摘要
本 EIP 引入一个新的操作码 PAY
,它接受两个堆栈参数 addr
和 val
,并将 val
wei 转移到地址 addr
,而不调用它的任何函数。
动机
目前,要将以太币发送到一个地址,需要调用该地址,这会将执行上下文转移到该地址,从而产生以下几个问题:
- 首先,它打开了一个重入攻击向量,因为接收者可以回调发送者。更一般地说,接收者可以单方面执行任意状态更改,仅受转发的 gas 限制,这从发送者的角度来看是不希望的。
- 其次,它打开了一个 DoS 向量。想要发送以太币的合约必须意识到接收者可能会耗尽 gas 或 revert。
- 未来潜在的类调用操作码可能无法提供限制转发给接收者的 gas 数量的方法,因此目前使用的针对意外副作用的微薄缓解措施(gas 限制)无法保证可用。
CALL
和EXTCALL
操作码将在接收者上执行代码,这在想要发送以太币时是无意的,并且可能导致无意的操作。代码执行也必须用 gas 支付,即使意图只是发送以太币,这也是不必要的 gas 浪费。- 最后,EIP-7702 允许将外部拥有账户 (EOA) 委托给其他账户,这打破了 EOA 不能包含代码的不变性。因此,调用这样的 EOA 以发送以太币也将执行代码并花费不必要的 gas。
拥有一个专门用于以太币转移的操作码可以解决所有这些问题,并且将是对 EVM 的一个有用的补充。
规范
常量
常量 | 定义 |
---|---|
WARM_STORAGE_READ_COST |
EIP-2929 |
COLD_ACCOUNT_ACCESS_COST |
EIP-2929 |
GAS_NEW_ACCOUNT |
EELS |
GAS_CALL_VALUE |
EELS |
行为
引入了一个新的操作码:PAY
(0xfc
),它:
- 如果当前帧是静态的,则以异常失败halt,如 EIP-214 中定义的那样。
- 从堆栈中弹出两个值:
addr
然后val
。 - 如果
addr
的任何高 12 个字节设置为非零值(即,它不包含 20 字节地址),则异常halt。 - 收取下面详述的 gas 成本。
- 将
addr
标记为 warm(将addr
添加到accessed_addresses
)。 - 将
val
wei 从当前地址转移到地址addr
,仅当当前地址的余额大于或等于val
时。 - 如果
PAY
操作成功,则在堆栈上推送1
,如果失败,则推送0
。- 目前只有余额不足会产生
0
返回值。
- 目前只有余额不足会产生
Gas 成本
PAY
的 gas 成本是以下各项的总和:
addr
是否在accessed_addresses
中?- 如果是,
WARM_STORAGE_READ_COST
; - 否则,
COLD_ACCOUNT_ACCESS_COST
。
- 如果是,
addr
是否存在或val
是否为零?- 如果是,则为零;
- 否则,
GAS_NEW_ACCOUNT
。
val
是否为零?- 如果是,则为零;
- 否则,
GAS_CALL_VALUE
。
PAY
无法在具有空账户的网络上实现(参见 EIP-7523)。
理由
参数顺序
参数的顺序模仿 CALL
的顺序,后者在 val
之前弹出 addr
。除了保持一致性之外,这种排序还有助于验证器模式匹配 MEV 机会,因此 PAY
总是立即出现在 COINBASE
之后。
无效地址时暂停
暂停行为旨在允许地址空间扩展。
如果像在 CALL
中一样截断了高位字节,则合约可以依赖于截断行为。
如果地址空间扩展到 20 字节以上,则 PAY
要么无法定位这些账户,要么期望截断的代码可能会将以太币发送到错误的地址。
由于此行为可能会更改,因此合约不应依赖此暂停行为,而应使用指定为有意暂停的方法(例如 INVALID
操作码)。
向后兼容性
此更改需要硬分叉。
安全注意事项
现有合约不应依赖于其余额在其控制之下,因为已经可以通过使用 SELFDESTRUCT
操作码(在 EIP-6780 中受到一些限制)将以太币发送到地址而不调用它。
也可以通过发送到 block.coinbase
的优先级费用来非自愿地为账户提供资金。
但是,此操作码确实使此过程更便宜且更容易。因此,它不会打破不变性。
版权
在 CC0 下放弃版权及相关权利。
Citation
Please cite this document as:
Gavin John (@Pandapip1), Zainan Victor Zhou (@xinbenlv), Sam Wilson (@SamWilsn), Jochem Brouwer (@jochem-brouwer), Charles Cooper (@charles-cooper), "EIP-5920: PAY 操作码 [DRAFT]," Ethereum Improvement Proposals, no. 5920, March 2022. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-5920.