Solidity 0.8.20 版本发布,引入了新的操作码 PUSH0
。PUSH0
的作用是将常量 0 推送到堆栈上,可以减少合约字节码大小,降低合约部署的 Gas 成本。在以太坊主网使用该操作码时,需要注意其他链可能不支持 PUSH0
操作码,需要选择正确的 EVM 版本。
Solidity 发布了最新版本 Solidity 0.8.20。
而且,和往常一样,随之而来的是相当多的新变化、改进、错误修复等等。
但是,这个版本中有一个强制性的更新,作为智能合约开发者,你必须了解。
那就是 - 包含了一个名为 PUSH0
的新操作码。
Solidity 团队在关于 PUSH0
的官方公告博客中给出的一个快速重要提示:
新的编译器将默认目标 EVM 版本切换到上海,这意味着生成的字节码将包含
PUSH0
操作码。
PUSH0
操作码实际上非常简单。
它是一个只有一项特定任务的指令,即将常量值 ZERO 推送到堆栈上。就是这样,相信我。
虽然 PUSH0
最近才被包含在 solidity 版本 加粗0.8.20加粗 中,但自 2021 年 EIP-3855 诞生以来,它的重要性就显而易见了。
在接下来的章节中,我们将更深入地研究这个加粗看似简单加粗的操作码的重要性,并探讨它的关键含义。
如果你快速浏览一下到目前为止我们拥有的与 PUSH 操作相关的操作码(指令 0x60 到 0x7f),你就会意识到我们有从 PUSH1 到 PUSH32 的操作码。
从技术上讲,这意味着我们可以根据需要使用相应的操作码将从 1 字节到 32 字节的任何项目 PUSH 到堆栈上。
PUSH1 = 0x60, // 将 1 字节的项目放在堆栈上。
PUSH2 = 0x61, // 将 2 字节的项目放在堆栈上。
PUSH3 = 0x62, // 将 3 字节的项目放在堆栈上。
PUSH4 = 0x63, // 将 4 字节的项目放在堆栈上。
PUSH5 = 0x64, // 将 5 字节的项目放在堆栈上。
PUSH6 = 0x65, // 将 6 字节的项目放在堆栈上。
PUSH7 = 0x66, // 将 7 字节的项目放在堆栈上。
PUSH8 = 0x67, // 将 8 字节的项目放在堆栈上。
PUSH9 = 0x68, // 将 9 字节的项目放在堆栈上。
PUSH10 = 0x69, // 将 10 字节的项目放在堆栈上。
....
PUSH31 = 0x7e, // 将 31 字节的项目放在堆栈上。
PUSH32 = 0x7f, // 将 32 字节的项目放在堆栈上。
但是,我们没有足够的方法将 ZERO 推送到堆栈上。
因此,为了将 ZERO 推送到堆栈上,我们有变通方法,例如:
虽然上面提到的变通方法完成了这项工作,但它们还不够充分。
例如,使用 "加粗PUSH1 00加粗" 被编码为两个字节,并且从技术上讲,比在堆栈上放置零消耗更多的 gas。
并且使用多个 DUP 指令可能会增加合约代码大小,并且不是一种优化的方法。
如前所述,这个新的操作码可能看起来很简单,但它确实解决了所有这些长期以来被忽略的问题。
EIP3855 文档的一部分内容是:
为了正确看待“浪费”,在现有帐户中,340,557,331 字节浪费在
PUSH1 00
指令上,这意味着花费了 68,111,466,200 gas 来部署它们。在实践中,许多这些帐户与其他帐户共享相同的字节码,因此它们在客户端中的总存储大小较低,但是,无论如何都必须支付部署时间成本。
加粗仅仅为了将零放在堆栈上就浪费了如此惊人的 gas 量。加粗 🤯
现在有了 PUSH0
,我们将能够一次性解决所有这些问题。
PUSH0 操作码将允许我们直接将常量 0 值推送到堆栈上,而无需使用多个 DUP 指令或其他操作码的组合。
有了新的 PUSH0
操作码,我们现在有了:
这是 Web3 的人,所以 👇
不要信任,去验证。
让我们尝试用一个例子来验证上述所有关于 PUSH0
操作码的细节,看看它是否真的能产生奇迹。🪄
我们将以这个小合约为例,
contract PushZero_Test{
uint256 public num;
function set(uint256 _n) public{
num = _n;
}
}
然后,让我们编译和部署这个合约:
➡️ 使用旧版本的合约字节码大小 = ~678 个字符
➡️ 使用 0.8.20 版本的合约字节码大小 = ~646 个字符
➡️ 使用旧版本的合约部署成本 = ~61511 gas
➡️ 使用 0.8.20 版本的合约部署成本 = ~58909 gas
作为这个简短实验的结果,我们可以清楚地验证,通过包含 PUSH0
操作码,我们现在有了:
嗯,这个操作码的魔力很好。🧐
加粗不要跳过实验。加粗
加粗也尝试自己验证一下加粗
虽然 PUSH0
操作码现在包含在最新的 solidity 编译器中,但在 ETH 主网以外的任何其他链上使用它时,你需要小心。
仍然有一些其他的链,如 L2,它们不识别 PUSH0
操作码。因此,如果你尝试使用最新的编译器在任何不支持此操作码的链上部署合约,你的合约部署将失败。
你可能会收到这样的错误 👇
因此,在这种情况下,你必须确保已选择正确的 EVM 版本。在此处了解有关选择正确 EVM 目标版本的更多信息:HERE。
好的,解密者们,希望这有帮助。
再见。👋🏻
\
用于 Solidity ABI 编码的深度心智模型:第 1 部分![为什么要学习 Solidity 的难题 [ABI 编码系列:第 0 部分]] (https://www.decipherclub.com/content/images/size/w600/2025/06/ChatGPT-Image-Jun-8--2025--07_07_45-PM.png)\
为什么要学习 Solidity 的难题 [ ABI 编码系列:第 0 部分 ] \
\
Solidity 很简单。\
\
它是一种简单而美丽的语言。\
\
随着优秀的教育资源、课程、开发工具和 LLM 的兴起,学习和编写 Solidity 从未如此简单。\
\
但这是一个残酷的现实——如果每个人都很容易上手,那么
\
我在 SUI-Move 中的第一个迷你项目 - 第 2 部分
\
我对 Move 智能合约的初次体验 - 第 1 部分 \
\
我最近尝试了一种新的智能合约语言 MOVE。\
\
该语言的灵感来自 Rust,因此对于 Solidity 开发人员来说并不直观。\
\
但是,使用它构建超级有趣。\
\
在本系列文章中,我旨在介绍 Move 语言及其功能。
- 原文链接: decipherclub.com/push0-o...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!