风险提示:理性看待区块链,提高风险意识!
柏林硬分叉对 Gas 影响几何?
首页 > 币界资讯 > 区块链新闻 2021-04-16 17:02
摘要
原标题:《柏林硬分叉对Gas影响几何?》原文来源:ECN 以太坊中文社区柏林硬分叉已于 4 月 14 日在主网上线,引入了四份 EIP。其中的两份 (EIP-2929 和 EIP-2930) 对交易的 gas 成本有影响。本文将解释部分 gas 成本在柏林前是如何计算的,加入了 EIP-2929 后会如何变化,以及如何使用 EIP-2930 引入的访问列表。要点速览这篇文章很长,这是它的概要:柏林硬分叉改变一些操作码的 gas 成本。如果在一个 dapp 或一个智能合约里 g..... 。
币界网报道:
原标题:《柏林硬分叉对Gas影响几何?》
原文来源:ECN 以太坊中文社区

柏林硬分叉已于 4 月 14 日在主网上线,引入了四份 EIP。其中的两份 (EIP-2929 和 EIP-2930) 对交易的 gas 成本有影响。本文将解释部分 gas 成本在柏林前是如何计算的,加入了 EIP-2929 后会如何变化,以及如何使用 EIP-2930 引入的访问列表。

要点速览

这篇文章很长,这是它的概要:

柏林硬分叉改变一些操作码的 gas 成本。如果在一个 dapp 或一个智能合约里 gas 费的值是硬编码的,它们可能会中止运行。如果这种情况发生了,且智能合约是不可更新的,消费者将需要用 EIP-2930 的访问列表才能使用那部分的操作码。

访问列表可以用作减少少量的 gas 成本,但实际上它们在一些情况下是会增加总 gas 消耗量的。

geth 增加了一个叫 eth_createAccessList 的新 RPC 方法,用以简化访问列表的创建。

柏林硬分叉前的 gas 成本

EVM 执行的每个操作码都有一笔相关的 gas 成本。它们大多数的成本是固定的:PUSH1 总是消耗 3 个单位的 gas,MUL 消耗 5 个,等等。其他一些是会变化的:比如 SHA3 的操作码成本依赖于它的输入大小。

我们主要讨论操作码 SLOAD 和 SSTORE,因为它们是最受柏林硬分叉影响的。我们以后会讨论针对地址的操作码,比如所有的 EXT*和 CALL*,因为它们的 gas 成本也改变了。

柏林前 SLOAD 的 gas 成本

在没有 EIP-2929 之前,SLOAD 的 gas 消耗很简单:它总是消耗 800 gas。所以(目前)没有什么可说的。

柏林前 SSTORE 的 gas 成本

在 gas 消耗方面,SSTORE 可能是最复杂的操作码了,因为它的成本取决于像存储 slot 的当前值、新值、以及它是否之前被修改过。我们

仅对一些情况进行分析以获得一个基本理解;如果你想了解更多,请阅读文末的 EIP 链接。

如果存储 slot 的值从 0 变成 1 (或任何非 0 的值),gas 消耗量是 20000。

如果存储 slot 的值从 1 变成 2 (或任何其他非 0 的值),gas 消耗量是 5000。

如果存储 slot 的值从 1 (或任何非 0 的值) 变成 0,gas 消耗量也是 5000,但在交易的最后你会获得 1 笔 gas 费返还。本文不会讨论 gas 费返还,因为它们在柏林硬分叉中不受影响。

如果存储 slot 的值在之前相同的交易中被修改了,往后所有 SSTORE 的 gas 消耗量都是 800。

这部分的细节并不有趣,重要的是 SSTORE 很贵,而它的消耗取决于几个因素。

EIP-2929 后的 gas 消耗

EIP-2929 对上述所有操作码的 gas 消耗都有影响。但在深入这些变化前,我们需要先谈谈这份 EIP 引入的一个重要概念:访问过的地址 (accessed addresses) 与访问过的存储密钥 (accessed storage keys)。

如果一个地址或一个存储密钥在之前的交易中被「使用」过,那么它们就会被视为「访问过的」。例如,当你 CALL(调用)一个其他合约,该合约的地址就会被标为「accessed (访问过的)」。同样地,当你 SLOAD(加载)或 SSTORE(存储)一些 slot 的时候,交易的其

他部分也会被视为访问过的。哪个操作码执行它并不重要:如果一个 SLOAD 读取了一个 slot,接下来的 SLOAD 和SSTORE 都会被视为访问过的。

这里值得注意的是,存储密钥是「内置于「一些地址的。就如这份 EIP 所解释:「在执行交易时,维持一组 accessed_addresses: Set[Address] 和accessed_storage_keys: Set[Tuple[Address, Bytes32]]」

也就是说,当我们说一个存储 slot 被访问了,我们实际上说的一对 (address, storageKey) 被访问了。

接下来谈谈新的 gas 消耗。

柏林后的 SLOAD

在柏林硬分叉之前,SLOAD 固定消耗 800 gas。现在,它取决于该存储 slot 是否被访问过。如果它没有被访问过,gas 消耗是 2100;如果被访问过了,则是 100。因此,如果该 slot 是在访问过的存储密钥列表里的,SLOAD 的 gas 消耗会少于 2000。

柏林后的 SSTORE

让我们在 EIP-2929 语境下重温前面的 SSTORE 例子:

➤ 如果存储 slot 的值从 0 变成 1 (或任何非 0 的值),gas 消耗量是:

如果存储密钥没有被访问过,22100

如果被访问过了,20000

➤ 如果存储 slot 的值从 1 变成 2 (或任何其他非 0 的值),gas 消耗量是:

如果存储密钥没有被访问过,5000

如果被访问过了,2900

➤ 如果存储 slot 的值从 1 (或任何非 0 的值) 变成 0,gas 消耗与上一种情况一样,再加上返还。

➤ 如果存储 slot 的值在之前相同的交易中被修改了,往后所有 SSTORE 的 gas 消耗量都是 100。

如你所见,如果 SSTORE 正在修改的 slot 是之前被访问过的,第一个SSTORE 消耗少于 2100 gas。

总结

下表对上述的值进行了比较:

请注意,在最后一行没有必要谈论 slot 是否已经被访问过,因为如果它之前就被写入,那它就被访问过了。

EIP-2930: 可选访问列表交易

我们一开始提及的其他 EIP 就是 EIP-2930。这份 EIP 增加了一种新的交易类型,它可以在交易里加入一个访问列表。这意味着你可以在交易执行开始前,事先声明哪些地址和 slot 应被视为访问过的。例如,一个未被访问过的 slot 的一个 SLOAD 需要消耗 2100 gas,但如果该 slot 被加入到交易访问列表里,同一个操作码只需消耗 100 gas。

但如果已经被访问过的地址或存储密钥会消耗更少 gas,这是否意味着我们可以把所有东西都添加到交易访问列表来降低 gas 消耗了?棒!不用给 gas 费了!然而,不尽然是这样,因为你每次添加地址和存储密钥的时候还是需要支付 gas 费的。

我们来看一个例子。假如我们正在向合约 A 发送一笔交易,访问列表可能如下:

如果我们发送一笔附有这个访问列表的交易,使用 slot0x0 的第一个操作码是 SLOAD,它消耗的是 100 而不是 2100 gas。这减少了 2000 gas。但每次把存储密钥添加到交易的访问列表中都需要消耗 1900 gas。因此我们只省了 100 gas。(如果访问该 slot 的第一个操作码是 SSTORE 而不是 SLOAD,我们可以省 2100 gas,也就是说如果我们考虑的是存储密钥的消耗的话,我们总共节省 200 gas。)

这是否代表只要我们使用交易访问列表就能节省 gas?不是的,因为我们还需要支付添加地址到访问列表 (即我们的例子中的 "<address of A>" ) 的 gas。

访问过的地址

到目前为止,我们只讨论了操作码 SLOAD和 SSTORE,但柏林升级后不是只有这些操作码有变化。例如,操作码 CALL 之前的固定消耗量是 700。但 EIP-2929 后,如果地址不在访问列表里,它的消耗量变成了 2600,如果在,则是 100。还有,像访问过的存储密钥,无论之前访问的是什么操作码 (例如,如果 EXTCODESIZE 是第一次被调用,那么该操作码将消耗 2600 gas,而往后任何使用同一个地址的 EXTCODESIZE、CALL 还是 STATICCALL 都只消耗 100 gas)。

这是如何影响有访问列表的交易的呢?例如,假如我们给合约 A 发送一笔交易,而该合约调用另一个合约 B,那么我们可以加入这样一个列表:

我们将需要支付 2400 gas 以把这个访问列表加入到交易里,但之后使用 B 地址的第一个操作码只消耗 100 gas,而不是 2600。因此,我们通过这样做节省了 100 gas。如果 B 以某种方式使用它的存储,且我们知道使用的是哪个密钥,那么我们也可以把它们加入到访问列表里,这样可以为每个密钥节省 100~200 gas (取决于你的第一个操作码是 SLOAD 还是 SSTORE)。

但是为什么我们要谈论另一个合约?我们正在调用的合约呢?为什么不对这个合约进行这些操作?

我们可以这样做,但这样不划算,因为 EIP-2929 明确规定正在被调用的合约 (即 tx.to) 地址会默认加入到 accessed_addresses 列表里。因

此我们无须支付多余的 2400 gas。

让我们再对之前的例子进行分析:

除非我们要加入多几个存储密钥,否则这其实很浪费。如果我们预设SLOAD总是首先使用存储密钥,那么我们起码需要 24 个存储密钥能保本。

你可以想象一下,做分析与手动创建一个访问列表并不那么有趣。幸运的是,其实有更好的方法。

eth_createAccessListRPC 方法

Geth (从 1.10.2 版本开始 ) 加入了一个新的 eth_createAccessListRPC 方法,你可以用它来生成访问列表。它的使用与eth_estimateGas相似,但它返回的不是 gas 估值,而是像下面这样的结果:

也就是它给你该交易会用到的地址与存储密钥的列表,加上访问列表被加入情况下所消耗的 gas。(像eth_estimateGas,这是一个估值,当交易实际上被挖的时候,这个列表可能会改变。)但,这并不代表 gas 消耗量会低于在没有访问列表情况下发送同一笔交易所消耗的!

我想我们会随着时间推移发现使用它的正确方法,但我猜的伪代码如下:

给合约松绑

值得一提的是,访问列表的主要目的不在于使用 gas。如 EIP 所解释:

「减轻由 EIP-2929 引入的合约断裂风险,因为交易可以提前指定交易计划访问的账户和存储 slot 并提前支付;最终在实际执行中,操作码 SLOAD 和EXT*只消耗 100 gas:这个低 gas 消耗不仅可以防止由该 EIP 引起的断裂,还可以「松开」任何因 EIP-1884 而受限的合约。」

这意味着如果一个合约对执行某事务的成本做了假设,gas 成本的增加就可能使它停止运作。例如,一个合约调用另一个合约,像这样someOtherContract.someFunction{gas: 34500}(),因为它假设 someFunction 会准确消耗 34500 gas,这样它会出问题。但如果你添加了一个合理的访问列表,那么合约会再次运作。

自己做检验

如果你像自己去测试,复制这个代码库,里面由多个可以用 Hardhat 和 geth 执行的实例。在 README 查看说明。

参考文献

EIP-2929 和 EIP-2930 是与本文相关的两个柏林硬分叉 EIP。

EIP-2930 依赖于柏林硬分叉的另一部分:EIP-2718,它又叫类型交易。

EIP-2929 参考了很多 EIP-2200,因此如果你想深入了解 gas 成本,你可以从那里开始。

如果想看比较 gas 使用变更的更复杂实例,请看这里。

原文链接

发表评论
发表评论
暂无评论
    相关阅读
    Ripple案和Terraform案是美国加密行业绕不开的两起标志性案件。
    区块链
    2025-01-08 10:31:28
    法庭文件称,当UST和LUNA在2022年崩溃时,Do Kwon的加密生态系统Terra可能影响了100多万受害者。
    区块链
    2025-01-08 04:14:35
    立法者指责他扼杀了加密货币创新,限制了银行在美国参与数字资产的能力。
    区块链
    2025-01-08 02:27:21
    美国加密货币交易所Coinbase将SHIB的现货交易量增加了1711%。Shiba Inu的总交易量在过去24小时内上升至4.94亿美元。
    区块链
    2025-01-07 23:54:32
    IOST 的治理提案投票指南
    区块链
    2025-01-07 22:31:41
    推荐专栏
    热门币种
    更多
    币种
    美元价格
    24H涨跌幅
    BTC比特币
    60,963.61 USDT
    ¥435,103.38
    -2.72%
    ETH以太坊
    3,368.69 USDT
    ¥24,042.67
    -0.3%
    BNB币安币
    570.68 USDT
    ¥4,073.00
    -0.28%
    USDT泰达币
    1.02 USDT
    ¥7.25
    -0.19%
    SOL
    135.96 USDT
    ¥970.36
    +7.66%
    USDC
    1.00 USDT
    ¥7.15
    -0.01%
    TON
    7.59 USDT
    ¥54.14
    +4.55%
    XRP瑞波币
    0.47720 USDT
    ¥3.41
    +0.48%
    DOGE狗狗币
    0.12210 USDT
    ¥0.87140
    +2.43%
    ADA艾达币
    0.39050 USDT
    ¥2.79
    +3.88%
    热搜币种
    更多
    币种
    美元价格
    24H涨跌幅
    Filecoin
    5.3263 USDT
    ¥39.05
    -10.41%
    狗狗币
    0.3519 USDT
    ¥2.58
    -9.95%
    比特币
    96492.68 USDT
    ¥707,445.73
    -5.15%
    Gatechain Token
    17.7171 USDT
    ¥129.89
    -4.23%
    Horizen
    23.0186 USDT
    ¥168.76
    -17.93%
    柚子
    0.808 USDT
    ¥5.92
    -10.67%
    dYdX
    1.3972 USDT
    ¥10.24
    -13.66%
    Solana
    197.65 USDT
    ¥1,449.09
    -8.57%
    Shiba Inu
    2.17E-5 USDT
    ¥0.00
    -9.51%
    艾达币
    0.9946 USDT
    ¥7.29
    -8.58%
    FTX Token
    2.8346 USDT
    ¥20.78
    -16.53%
    火币积分
    0.9283 USDT
    ¥6.81
    -28.72%
    最新快讯
    更多
    币界网实时价格午报:ETH以太坊站上3372.55美元/枚,涨幅达1.01%
    2025-01-08 13:27:09
    名义价值约22.29亿美元BTC和ETH期权将于周五到期交割
    2025-01-08 13:26:59
    Morpho推出MorphoVaults1.1
    2025-01-08 13:24:44
    Asymmetric创始人:宏观和情绪变化导致比特币面临短期压力,但长期仍看涨
    2025-01-08 13:20:00
    中国银行原副行长王永利:理性看待特朗普的比特币新政,不可盲目跟风
    2025-01-08 13:18:00
    中国银行原副行长:理性看待特朗普的比特币新政,不可盲目跟风
    2025-01-08 13:14:49
    ACT宣布推出生态系统加速计划,正开发无缝连接AI与加密的框架
    2025-01-08 13:10:55