假设 ETH 价格在 $1,500 到 $2,000 之间,智能合约的创建成本可能在 $10 到 $2,000 不等。最大的影响因素包括:1) Ethereum 价格,2) 编译后合约的大小(以字节为单位),3) Ethereum 网络当前的 Gas 价格。
决定部署合约所需 Gas 数量的因素共有六个部分。以美元计价的 Gas 成本取决于市场状况和网络状况。我们将在本文中详细计算所有这些具体数值。
智能合约部署成本
- 所有 Ethereum 交易都必须支付的 21,000 Gas
- 创建新合约的固定成本为 32,000 Gas
- 每设置一个存储变量需要 22,100 Gas
- 交易数据中每个零字节消耗 4 Gas,交易中每个非零字节消耗 16 Gas。
- 在初始化期间执行每个字节码的成本
- 已部署字节码每字节消耗 200 Gas
让我们以在 Remix 中部署一个极简的 Solidity contract 为例
pragma solidity 0.8.7;
contract Minimal {
constructor() payable {
}
}

智能合约创建 Gas 成本
请注意,根据 Remix,部署成本为 66,862。我们将在本文中详细拆解该成本。
我们已将 constructor 设为 payable,并将优化器设置运行 200 次。这能起到减小智能合约体积的效果。
我们先来计算一下
21,000 gas | deployment
32,000 gas | creation
Total: 53,000
我们还有 13,862 Gas 需要去解释
交易字节码 Gas 成本 (tx.data)
交易字节码为
0x6080604052603f8060116000396000f3fe6080604052600080fdfea2646970667358221220c5cad0aa1e64e2ca6a6cdf28a25255a8ebbf3cdd5ea0b8e4129a3c83c4fbb72a64736f6c63430008070033
每对十六进制字符代表一个字节,所以我们添加一些空格使其更具可读性。
要像这样进行拆分,我们可以使用以下 Python 代码
import itertools
# note that we manually removed the "0x" at the beginning
s = "6080604052603f8060116000396000f3fe6080604052600080fdfea2646970667358221220c5cad0aa1e64e2ca6a6cdf28a25255a8ebbf3cdd5ea0b8e4129a3c83c4fbb72a64736f6c63430008070033"
s = " ".join(["".join(group) for group in itertools.zip_longest(s[::2], s[1::2])])
print(s)
我们得到
60 80 60 40 52 60 3f 80 60 11 60 00 39 60 00 f3 fe 60 80 60 40 52 60 00 80 fd fe a2 64 69 70 66 73 58 22 12 20 c5 ca d0 aa 1e 64 e2 ca 6a 6c df 28 a2 52 55 a8 eb bf 3c dd 5e a0 b8 e4 12 9a 3c 83 c4 fb b7 2a 64 73 6f 6c 63 43 00 08 07 00 33
每个非零字节消耗 16 Gas,每个零字节(00)消耗 4 Gas。要计算它们的数量,我们可以使用这段 Python 单行代码:
s = "60 80 60 40 52 60 3f 80 60 11 60 00 39 60 00 f3 fe 60 80 60 40 52 60 00 80 fd fe a2 64 69 70 66 73 58 22 12 20 c5 ca d0 aa 1e 64 e2 ca 6a 6c df 28 a2 52 55 a8 eb bf 3c dd 5e a0 b8 e4 12 9a 3c 83 c4 fb b7 2a 64 73 6f 6c 63 43 00 08 07 00 33"
# non-zero bytes
print(len(list(filter(lambda x: x != '00', s.split(' ')))))
# zero bytes
print(len(list(filter(lambda x: x == '00', s.split(' ')))))
我们有 75 个非零字节和 5 个零字节。计算公式为 Gas
21,000 gas | deployment
32,000 gas | creation
1,220 gas | bytecode cost
Total: 54,220 gas.
为了使总成本达到 66,862,我们还有 12,642 Gas 需要计算。
部署代码
让我们再来看一遍字节码
60 80 60 40 52 60 3f 80 60 11 60 00 39 60 00 f3 fe 60 80 60 40 52 60 00 80 fd fe a2 64 69 70 66 73 58 22 12 20 c5 ca d0 aa 1e 64 e2 ca 6a 6c df 28 a2 52 55 a8 eb bf 3c dd 5e a0 b8 e4 12 9a 3c 83 c4 fb b7 2a 64 73 6f 6c 63 43 00 08 07 00 33
加粗部分为部署代码。第一部分为初始化代码。我们需要将部署代码的每个字节乘以 200 Gas 来计算成本。这部分的成本高于上述的字节码成本,因为这些内容会存储在 Ethereum 状态中。
让我们再次使用 Python 来计算
deployment_code = '60 80 60 40 52 60 00 80 fd fe a2 64 69 70 66 73 58 22 12 20 c5 ca d0 aa 1e 64 e2 ca 6a 6c df 28 a2 52 55 a8 eb bf 3c dd 5e a0 b8 e4 12 9a 3c 83 c4 fb b7 2a 64 73 6f 6c 63 43 00 08 07 00 33'
print(len(deployment_code.split(' ')))
# 63
Gas
到目前为止的成本拆解如下
21,000 gas | deployment
32,000 gas | creation
1,220 gas | bytecode cost
12,600 gas | deployed bytecode
Total: 66,820
马上就要完成了!我们距离 66,862 的目标还差 42 Gas。
字节码执行 Gas 成本
我们还需要考虑初始化字节码实际执行所产生的成本。
60 80 60 40 52 60 3f 80 60 11 60 00 39 60 00 f3 fe
我们可以使用 evm playground tool 将其转换成更为直观的格式。
PUSH1 0x80 | 3 gas
PUSH1 0x40 | 3 gas
MSTORE | 12 gas
PUSH1 0x3f | 3 gas
DUP1 | 3 gas
PUSH1 0x11 | 3 gas
PUSH1 0x00 | 3 gas
CODECOPY | 9 gas
PUSH1 0x00 | 3 gas
RETURN | 0 gas
INVALID | not executed
总计是 42,与预期一致。这些 Gas 成本是通过运行 Remix 调试器获取的。

智能合约部署 Gas 调试
大功告成,我们已经解释了智能合约部署的每一个成本组成部分。
最终的明细分解如下
21,000 gas | deployment
32,000 gas | creation
1,220 gas | bytecode cost
12,600 gas | deployed bytecode
42 gas | deployment execution cost
Total: 66,862 gas
请注意,如果我们在 constructor 中设置了存储变量,成本会更高。每设置一个变量都需要支付 22,100 Gas。但为了让本次讲解简单易懂,我们省略了这种情况。
请参阅我们关于 solidity gas optimization 的文章,以了解如何降低部署成本。此处获得的所有 Gas 成本数据均来自 Ethereum Yellow Paper。
转换为美元计价
要将“Gas”单位转换为美元,计算公式为
。
相关数据可以从 ethgasstation 或 etherscan 等网站获取。在我们的示例中,假设 Eth 价格为 $1,000,Gas 价格为 20 gwei,那么按美元计价的成本将是
最初发布于 2022 年 12 月 31 日