EIP-3855 是一项 以太坊改进提案,提议在 以太坊 虚拟机 (EVM) 中添加一个名为 PUSH0 (0x5f) 的新指令,作为 Shapella 升级的上海 硬分叉 的一部分。该指令旨在帮助降低合约的 gas 成本和存储成本,这些合约需要将常量 0 推送到堆栈上。 [1]
2021 年 2 月 19 日,创建了 EIP-3855 以引入 PUSH0,旨在减少合约代码大小,降低合约滥用其他指令的风险,并减少使用 DUP 指令复制零的需要。目前,开发人员可以使用其他指令(如 PC、MSIZE、CALLDATASIZE、RETURNDATASIZE、CODESIZE、CALLVALUE 和 SELFBALANCE)来实现此效果,但这些指令具有不同的成本,并且可能因上下文而异。此外,现有帐户中当前 PUSH1 00 指令产生的浪费为:340,557,331 字节,相当于花费 68,111,466,200 gas 来部署它们。该提案旨在减少这种冗余以及其他主要目标。 [1][2]
PUSH0 指令没有立即数据,不会从堆栈中弹出项目,并将一个值为 0 的项目放置到堆栈上。它的 gas 成本为 2,与其他将常量值放置到堆栈上的指令(如 ADDRESS 和 ORIGIN)相同。PUSH0 的操作码为 0x5f,这意味着它与其他 PUSH 实现位于“连续”空间中,并且可能共享实现。 [2][3]
对 Mainnet 的分析表明,大约 11.5% 的所有执行的 PUSH* 指令都推送值为零,并且使用 PUSH1 推送常量 0 的 gas 和存储成本浪费巨大。 [2]
引入 PUSH0 的一个潜在问题是,已经部署的使用此操作码的合约可能会在此 EIP 之后更改其行为。但是,作者不知道对安全性的任何影响,并且 jumpdest 分析不受影响,因为 PUSH0 没有立即数据字节。 [1]