织梦CMS - 轻松建站从此开始!

我的网站

当前位置: 主页 > 竞争币

搞懂 “柏林” 之后的合约Gas开销

时间:2021-04-18 16:35来源:未知 作者:admin 点击:
“柏林”硬分叉将在4月15日激活,该硬分叉所包含EIP中的两个(EIP-2929和EIP-2930)都会影响事务的Gas开销。本文会解释“柏林”激活之前,一些操作码的Gas消耗量是如何计算的,而EIP-2

“柏林”硬分叉将在4月15日激活,该硬分叉所包含EIP中的两个(EIP-2929和EIP-2930)都会影响事务的Gas开销。本文会解释“柏林”激活之前,一些操作码的Gas消耗量是如何计算的,而EIP-2929对此有何影响,以及,2930引入的访问清单(Access List)功能应如何使用。

摘要

这篇文章很长,你要是只想知道结论,看完这部分就可以把网页关掉了:

柏林硬分叉改变了某些操作码的Gas开销。如果你在自己的应用中硬编码了一些操作可使用的Gas数量,这些操作可能会卡死。如果真的出现了这种情况,而你的智能合约又是没法升级的,用户就需要使用“访问清单”功能来使用你的应用。

访问清单功能可略微减少Gas开销,但有些时候也可能会提高总的Gas消耗量。

geth客户端引入了一种新的RPC方法,叫做eth_createAccessList来简化访问清单的生成。

“柏林”升级以前的Gas开销

EVM所执行的每一个操作码都有一个对应的Gas消耗量。大部分操作码的消耗量都是固定的:PUSH1总是消耗3 gas,而MUL消耗5 gas,等等。有一些操作码的消耗量是可变的:举个例子,SHA3操作码的开销由输入值的长度决定。

我们先了解SLOAD和SSTORE操作码,因为这两个操作码受“柏林”影响最大。后面我们会再谈谈那些以地址为目标的操作,比如所有的EXT*类操作码和CALL*类操作码,因为它们的Gas开销也被改变了。

“柏林”以前的SLOAD

在EIP-2929实施前,SLOAD开销的计算方式很简单:总是消耗800 gas。所以,也没啥可展开的。

“柏林”以前的SSTORE

要讲到Gas消耗量的计算,SSTORE操作码可能是最复杂的了。因为消耗多少取决于该存储项槽当前的值、要写入的新值、该存储项是否已经修改过。我们只会分析少数几种场景,了解个大概。如果你想了解更多,请阅读本文末尾所附的EIP链接。

如果存储项的值从0改为1(或者任意非零的值),Gas消耗量是20000

如果存储项的值从1改为2(或者任意非零的值),Gas消耗量是5000

如果存储项的值从1(或任意非零的值)改为0,消耗量也是5000,但你会在事务执行结束后获得gas补贴。我们这里也不讨论gas返还机制,因为它不会受到柏林的影响

在一笔事务中,如果存储项已不是第一次修改,则后续每一次SSTORE都消耗800 gas

细节在这里并不重要,重要的是,SSTORE是昂贵的,具体消耗多少gas则依赖于多个因素。

EIP-2929之后的Gas消耗量

EIP-2929改变了所有这些数值。但在展开之前,我们要先谈谈该EIP引入的一个重要概念:被访问过的地址和被访问过的存储项的键(storage key)。

当一个地址或者一个存储项的键,在一笔事务中被“使用过”之后,在该笔交易余下的执行过程中,这个地址(或者这个键)都会被当成“已被访问过的”。举个例子,如果你在一笔事务中CALL(调用)另一个合约,那么该合约的地址就会被标记为“访问过的”。类似地,如果你SLOAD或者SSTORE过一些存储项槽,在该笔事务余下的执行过程里,这些槽也会被当成已经访问过的。到底用的哪个操作码是没有关系的,即使你只SLOAD过某个槽,接下来使用SSTORE时该槽也会被当成已访问过的。 (责任编辑:admin)

织梦二维码生成器
顶一下
(0)
0%
踩一下
(0)
0%
------分隔线----------------------------
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
表情:
用户名: 验证码:点击我更换图片
栏目列表
推荐内容