广告

柏林硬分叉已在主网上线对交易的 gas 成本有什么影响?

以太坊柏林硬分叉完成 Gas费会受到什么影响?

柏林硬分叉已于 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 发送一笔交易,访问列表可能如下:

accessList: [{
  address: "",
  storageKeys: [
    "0x0000000000000000000000000000000000000000000000000000000000000000"
  ]
}]

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

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

访问过的地址

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

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

accessList: [{ address: "", storageKeys: [] }]

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

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

accessList: [

{address: "", storageKeys: []},

{address: "", storageKeys: []},

]

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

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

accessList: [{

address: "",

storageKeys: [

"0x0000000000000000000000000000000000000000000000000000000000000000"

]

}]

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

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

eth_createAccessList RPC 方法

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

{

"accessList": [

{

"address": "0xb0ee076d7779a6ce152283f009f4c32b5f88756c",

"storageKeys": [

"0x0000000000000000000000000000000000000000000000000000000000000000",

"0x0000000000000000000000000000000000000000000000000000000000000001"

]

}

],

"gasUsed": "0x8496"

}

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

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

let gasEstimation = estimateGas(tx)

let { accessList, gasUsed } = createAccessList(tx)

if (gasUsed > gasEstimation) {

delete accessList[tx.to]

}

tx.accessList = accessList;

ransaction(tx)

给合约松绑

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

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

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

自己做检验

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

原文标题:《柏林硬分叉对 Gas 影响几何?》

撰文:Franco Victorio

翻译:ETH 中文站

24小时热点

BIBOX交易所无耻收割,限制提币

全球排名第6的Bibox虚拟币交易所违法运营,无耻收割,限制 ...

68444

CCFOX

满币交易所彻底崩盘

满币交易所彻底崩盘 「实锤」“满币网”高 ...

21748

T网

十大传销盘之:MASK币

MASK币 女装大佬开的项目,价格已经惨不忍睹 ...

90450

中国虚拟币排名

Dogwifhat (WIF)大幅飙升52%突破2美元 应该购买3个Solana生态迷因币

Meme币作为高风险、高波动又高回报的代币,其价格常常受市场 ...

20559

Business2Community

WBTC币(Wrapped Bitcoin)在那里下载?

WBTC(Wrapped Bitcoin)是一种基于以太坊网 ...

4034

Curve

元宇宙原力币未来潜力惊人,拉多先生:Forcecoin并不是作为一种替代币而诞生的

现如今加密货币的世界当中,每一个币种都会有着独自的价值,其中 ...

39692

波场区块链浏览器

Dogecoin狗狗币再次市值超越Cardano 迷因币季节到来要买哪些币可以是千倍币?

Dogecoin市值再次超越Cardano一事引发业内关注。 ...

4510

Business2Community

“千寻”数字藏品简介

“千寻”数字藏品是一套非常珍贵的数字藏品,由中国艺术家杨互君 ...

12028

泰达币交易平台

摩根大通分析师指比特币大涨反映现货ETF可望获核准

美国证管会(SEC)再次面临是否核准现货比特币ETF决定期限 ...

19550

Business2Community

defi,nft和元宇宙的基础概念与关联

Defi的概念是去中心化金融,它是自己掌握私钥,以数字货币为 ...

3155

波场区块链浏览器
广告

热点专题

NFT艺术品到底是什么?

Beeple,“EVERYDAYS: THE FIRST 5 ...

2292300

Opera House

最全的NFT发展史

当我们理解一个新生事物,必须要首先了解其起源,通过对其源头以 ...

1734143

iBox

“华英会”诈骗圈钱5000亿!崩盘后将会凄惨无比

“华英会”崩盘的预警已多次发出,尽管尚未正式宣布崩盘,但大家 ...

1249787

Magic Eden

什么是IDO?这种模式会带来怎样的影响?

要理解IDO(Initial DeFi Offering)初 ...

1133614

Bitstamp交易所

有黑客采取新型 USDT 假充值手法

根据慢雾区情报,有黑客采取新型 USDT 假充值手法,黑客采 ...

987547

区块链博客

4种利用永续合约资金费率套利的策略

下文将介绍在保持市场中立的条件下,如何从永续掉期资金费率中套 ...

882125

DCG区块链孵化器

国内NFT平台是怎么赚钱的?

2021年被称为NFT的“元年”,互联网巨头、各大企业、艺术 ...

788197

CoinBene满币网

链圈百科:韩国政府机构组织图

一、行政院 韩国行政院是一个由政府的行政机构组成的中央政府 ...

749298

BitKeep钱包

宝二爷郭宏才的乘风破浪之旅

10年后的比特币会涨到10万美元吗?宝二爷说过:“先吹吹牛B ...

695145

QuillAudits

元宇宙平台合法吗

现在,元宇宙平台备受热捧,但有人质疑其合法性。在此,我们将对 ...

694586

T网