以太坊今日将完成柏林硬分叉升级,这些知识点你需要了解

注册并登录App即可领取高达 60,000 元的数字货币盲盒:点击此处注册OKX

一文了解以太坊柏林(Berlin)硬分叉升级

在北京时刻4月15日下午18:00左右(具体是以太坊网络区块高度达到#12244000时),以太坊的柏林(Berlin)硬分叉晋级将会产生,这次晋级将纳入4个新的EIP改善提案,而其间两个(EIP-2929和EIP-2930)将会影响买卖的gas本钱计算。

本文解释了在这次硬分叉晋级前后的gas本钱计算,这将怎么随EIP-2929而产生改变,以及怎么运用EIP-2930引进的拜访列表功能,原文作者是Nomic Labs软件开发者Franco Victorio。

以太坊今日将完成柏林硬分叉升级,这些知识点你需要了解

注:文章篇幅较长,以下是其间的一些要点:

柏林硬分叉改变了一些opcode操作码的gas本钱。假如你在dapp或智能合约中有一个硬编码的gas值,它们或许会停止工作。假如产生这种情况,而且智能合约是不可晋级的,则用户将需求运用拜访列表(EIP-2930)来启用它。

拜访列表可用于稍稍下降gas本钱,但在某些情况下,它们实践上会增加gas耗费总量。

geth包括了一个新的RPC办法(eth\u createAccessList)来简化拜访列表的创立。

1

柏林硬分叉前的gas本钱

EVM履行的每个opcode操作码都有一个相关的gas本钱。关于大多数操作码而言,这个本钱是固定的:PUSH1总是耗费3个单位的gas,MUL则耗费5个单位的gas,等等。而关于其他操作码来说,它是可变的:例如,SHA3操作码的本钱取决于其输入的大小。

咱们将要点讨论SLOAD和SSTORE操作码,由于它们是受柏林硬分叉影响最大的操作码。咱们稍后将讨论那些以地址为目标的操作码,就像一切的 EXT*和CALL*操作码,由于它们的gas本钱也会产生变化。

柏林硬分叉之前的SLOAD

假如没有EIP-2929,SLOAD的本钱很简单:它总是会耗费800 gas。柏林硬分叉之前的SSTORE

就gas而言,SSTORE或许是最杂乱的操作码,由于它的本钱取决于存储slot的当时值、新值以及它是否曾经被修正正。咱们将只分析一些场景以取得根本的了解。假如你想了解更多,请阅读本文结尾链接的eip。

假如slot的的值从0更改为1(或任何非零值),则本钱为20000;

假如slot的的值从1更改为2(或任何其他非零值),则本钱为5000;

假如slot的的值从1(或任何非零值)更改为0,则本钱也为5000,但在买卖结束时你将取得gas退款。这篇文章中,咱们不会具体讨论退款,由于它们不受柏林硬分叉的影响;

假如曾经在同一业务中修正了该值,则一切后续sstore的本钱为800;

这儿的细节有些枯燥,重要的一点是,SSTORE是十分昂贵的,其本钱取决于几个因素。

2

施行EIP-2929之后的gas本钱

EIP-2929改变了一切这些值,但在此之前,咱们需求先谈谈这个EIP引进的一个重要概念:已拜访地址和已拜访存储密钥。

假如地址或存储密钥曾经在买卖期间被“运用”,则该地址或存储密钥就被视为已拜访。例如,当你调用另一个合约时,该合约的地址会被标记为已拜访。类似地,当你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。假如未拜访,则本钱为2100 gas,假如已拜访,则本钱为100 gas。因而,假如slot在已拜访的存储密钥列表中,则一次SLOAD的本钱会下降2000 gas。

柏林硬分叉之后的SSTORE

让咱们在部署EIP-2929的环境下回顾一下之前的SSTORE示例:

假如slot的值从0更改为1(或任何非零值),则本钱为:22100(假如未拜访存储密钥),20000(假如已拜访存储密钥);

假如slot的值从1更改为2(或任何其他非零值),则本钱为:5000(假如未拜访存储密钥),2900(假如已拜访存储密钥);

假如slot的值从1(或任何非零值)更改为0,则本钱与上一项相同,然后加上退款;

假如曾经在同一买卖中修正了该值,则一切后续SSTORE的本钱为100;

如你所见,假如要修正的slot曾经被拜访过,那么第一次SSTORE的本钱将下降2100 gas。

下面的表总结了目前为止一切改变的值:

以太坊今日将完成柏林硬分叉升级,这些知识点你需要了解

请留意,在最终一行中,议论是否拜访了slot是没有意义的,由于假如它曾经被写入过,则表明其也被拜访过。

3

EIP-2930

咱们在文章最初说到的另一个EIP便是EIP-2930,这个改善提案添加了一种新类型的业务,该业务能够在业务负载中包括拜访列表。这意味着你能够在业务开端履行之前预先声明哪些地址和slot应被视为是已拜访的。例如,一个未拜访slot的SLOAD本钱为2100,可是假如该slot包括在业务的拜访列表中,则相同的操作码本钱就为100。

可是,假如当地址或存储密钥已被拜访时,gas本钱变更低了,这是否意味着咱们能够将一切内容添加到业务的拜访列表中并下降gas本钱呢?不完全是这样,由于你还需求为添加的每个地址和每个存储密钥付出gas。

让咱们看一个比如,假定咱们正在向合约A发送一笔买卖,拜访列表或许如下所示:

以太坊今日将完成柏林硬分叉升级,这些知识点你需要了解

假如咱们用这个拜访列表发送了一笔买卖,而且第一个运用0x0 slot的操作码是SLOAD,则它将花费100 gas(而不是2100 gas),这就下降了2000 gas的耗费量。但业务拜访列表中包括的每个存储密钥的本钱为1900 gas,所以咱们只省了100 gas。(假如拜访该slot的第一个操作码是SSTORE,那么咱们将节约2100 gas,这意味着假如考虑到存储密钥的本钱,咱们总共将节约200 gas。)

这是否意味着咱们在运用带有拜访列表的买卖时总是能节约gas耗费?并非如此,由于咱们还要为拜访列表中的地址付出gas本钱(在咱们的示例中是"<address of A>")

已拜访地址

以上,咱们只讨论了SLOAD和SSTORE操作码,但这些并不是柏林硬分叉之后仅有改变的操作码。例如,原先调用操作码的固定本钱为700 gas。可是在施行EIP-2929之后,假如地址不在拜访列表中,则开销便是2600 gas,但假如是在已拜访列表中,则开销便是100 gas。而且,与已拜访存储密钥相同,之前拜访该地址的操作码并不重要(例如,假如先调用EXTCODESIZE,则该操作码将花费2600 gas,运用相同地址的任何后续EXTCODESIZE、CALL、STATICCALL将花费100 gas)。

这是怎么遭到拜访列表买卖的影响的?例如,假如咱们将一笔买卖发送至合约A,而该合约调用另一个合约B,那么咱们能够包括如下拜访列表:

以太坊今日将完成柏林硬分叉升级,这些知识点你需要了解

咱们必须付出2400 gas的费用才能将这个拜访列表包括在买卖中,可是第一个运用B地址的操作码将花费100 gas(而不是2600gas)。所以咱们这样做就节约了100 gas,假如B以某种办法运用它的存储,而且咱们知道它将运用哪些密钥,那么咱们还能够将它们包括在拜访列表中,并为每个密钥节约100/200的gas(取决于第一个操作码是SLOAD仍是SSTORE)。

但咱们为什么要谈另一个合约呢?咱们调用的合约怎么了?咱们为什么不这样做?

以太坊今日将完成柏林硬分叉升级,这些知识点你需要了解

咱们能够这样做,但这是不值得的,由于EIP-2929指定了被调用的合约地址(即tx.to)总是包括在accessed_addresses列表中,因而这只会白白浪费2400 gas。

让咱们再次分析上一节的示例:

以太坊今日将完成柏林硬分叉升级,这些知识点你需要了解

这实践上是浪费,除非咱们包括多个存储密钥。假如咱们假定一个SLOAD总是首先运用一个存储密钥,那么咱们至少需求24个存储密钥才能完成收支平衡。

明显,分析并创立这样的一个拜访列表是没有意义的。走运的是,咱们有更好的办法。

4

eth_createAccessList RPC办法

Geth(从1.10.2版本开端)包括了一个新的eth\u createAccessList RPC办法,其能够用来生成拜访列表。它的用法类似于eth_estimateGas,但它不是用于预算gas,而是返回如下内容:

以太坊今日将完成柏林硬分叉升级,这些知识点你需要了解

也便是说,它为你提供了该买卖将运用的地址和存储密钥的列表,以及假如包括拜访列表,则会耗费的gas。(而且,与eth_estimateGas相同,这是一种估计值,在实践进行买卖时,列表或许会更改。)

我想,跟着时刻的推移,咱们会发现履行此操作的正确办法是什么,而我的伪代码猜想是:

以太坊今日将完成柏林硬分叉升级,这些知识点你需要了解

5

激活合约

必须要指出的是,拜访列表的首要目的不是运用gas,正如EIP所解释的:

“EIP-2929所引进的是减轻合约破坏危险,由于买卖可预先指定和付出买卖计划拜访的帐户和存储slot。因而,在实践履行中,SLOAD和EXT*操作码只需求100 gas,这已经满足低了,它不仅可避免因该EIP而导致的破坏,还能够“激活”由于EIP 1884而卡住的任何合约。”

这意味着,假如一个合约对履行某些操作的本钱做出假定,那么gas本钱的增加或许会导致它无法工作。例如,一个合约调用另一个合约(例如someOtherContract.someFunction{gas: 34500}())由于它假定某个函数正好运用34500 gas,那么它就会中止,但假如在业务中包括适当的拜访列表,那么合约将再次工作。

假如你想自己测验这些EIP,你能够仿制这个repo,它有几个可运用Hardhat和geth履行的示例。有关说明,请检查README文件。

相关资料:

1、EIP-2929‌和EIP-2930‌

2、EIP-2930依赖于柏林硬分叉的另一组成部分:EIP-2718‌;

3、EIP-2929引用了很多EIP-2200‌的内容,所以假如你想更深化地了解gas本钱,你应该从EIP-2200开端;

4、有关比较gas运用量变化的更杂乱示例‌;

原文出处:巴比特,不代表云顶量化立场,如有侵权,请联系删除

云顶量化是币圈专业量化策略团队,团队成员均有3年以上金融量化实战经验,主要针对比特币量化(BTC),以太坊量化(ETH),狗狗币(DOGE),SHIB等各种虚拟数字货币推出资金费率套利策略和合约趋势型量化机器人策略。经过长时间实盘测试,策略的稳定型,实用型,可行性都是顶尖水平。

量化客服微信:dx185388