让我们想象一下简单的智能合约功能
mapping (address => uint8) votes;
function vote(address _address, uint8 _vote) {
require(notVotedYet(_address))
votes[_address] = _vote
}
我知道要使方法免费 - 我应该将其标记为view
,但这不合适。
只有当用户尚未投票时,此方法才会写入区块链。
我的问题是:
_address
的任何调用都不会花费任何GAS?我猜想我的主要问题是:在运行时计算气体消耗量,还是通过某种静态分析?
答案 0 :(得分:2)
- 将EVM"知道"可以要求失败,并免费拨打电话吗?
醇>
如果您的功能的可见性设置为view
,那么它将是免费的。
如果您的方法中存在require
并且它失败,则返回的值将为:
uint
bool
address
string
在你的情况下,行votes[_address] = _vote
正在修改状态。改变国家总是需要燃气。如果你添加新的非零值,它将需要20000气体,如果你将这个值设置为0,它将花费5000气体。此操作在较低级别称为SSTORE
。它说明您在存储内存中进行了更改。
将燃气"消费"当需求失败时和何时失败 它通过了?
这个想法是,tx发送者支付矿工完成的任何计算。如果是require
,矿工将获得奖励,无论如何 。 21000 gas
将涵盖椭圆曲线操作的成本,以便从签名 + 恢复require
之前计算消耗的任何气体的发件人地址。
如果gasLimit - gasConsumed
操作码在REVERT
评估为错误时被触发,则所有剩余的气体(require
)将被发送回tx发件人。所有 require-style 例外都会出现此行为。
如果出现断言式异常,则失败的交易将使用完整的gasLimit
。
文档中提到的Byzantium(Metropolis第1部分 - 2017年10月发布)更改是require
现在使用REVERT
操作码。在发布之前,它使用与assert
相同的操作码,这将消耗所有气体。 REVERT
退还剩余的气体。有关详细信息,请参阅此博客文章:POST
答案 1 :(得分:0)
编辑:所以文件不是很精确,而且“不消耗气体”显然意味着只消耗废气,而不是全部气体限制。
我不知道为什么会这样,但我在Udemy课程中注意到,当你明显看到几千个气体消耗时,主持人也说“没有气体消耗”。而且花费的订单或数量很少 - 它被认为是“真的花了”
这有点令人困惑。请检查Roman's answer。
所以我扫描了文档,找到了一个明确的答案:
请注意,断言式异常会消耗呼叫可用的所有气体,而需求式异常不会消耗从Metropolis版本开始的任何气体。
我找不到确切的日期,但根据各种文章,它看起来已经发布了(https://www.cryptocompare.com/coins/guides/the-ethereum-releases-of-frontier-homestead-metropolis-and-serenity/)