Ethereum 固体气体估计-设置为0时始终没有气体

Ethereum 固体气体估计-设置为0时始终没有气体,ethereum,solidity,smartcontracts,erc20,Ethereum,Solidity,Smartcontracts,Erc20,我正在试图找到解决此问题的方法,处理事务确认顺序并将值设置为0 pragma solidity ^0.5.17; contract Test { uint256 amount; constructor() public {} function join() public { amount += 100; } function leave() public { amount -= 100; } } 鉴于这些交

我正在试图找到解决此问题的方法,处理事务确认顺序并将值设置为
0

pragma solidity ^0.5.17;

contract Test {
    uint256 amount;

    constructor() public {}

    function join() public {
        amount += 100;
    }

    function leave() public {
        amount -= 100;
    }
}
鉴于这些交易(在ropsten上测试):

tx 1)呼叫加入已确认
金额==100

tx 2)呼叫加入(天然气价格1)待定
amount==100如果tx3先被开采

tx 3)呼叫许可(天然气价格100)待定
金额==0

但是,只要将
量设置回
0
,则
tx 2
将始终失败,并出现
缺气
错误。如果该值高于
0
,则不会发生这种情况。我的理解是,将一个值设置为其
0
状态而不是一个正整数会花费更多的汽油,而汽油估算没有考虑到这一点。我尝试了
delete
,希望这能给汽油退款,以补偿太低的汽油限制,但还是失败了


有没有一种优雅的方式来处理这种情况?我能想到的唯一方法是高估所有
join
事务的gas,这有其明显的缺点,或者从不将
amount
设置回
0
您的观察结果是正确的

通过将其设置为0,您可以删除存储,并获得汽油退款。这就是为什么它需要更少的汽油。但是汽油退款是有上限的,所以你不能用它来储存汽油

在插槽中存储一个值需要20000燃气(来源:)

从存储插槽加载一个值需要2200燃气(来源:)

这就是为什么你会看到不同的气体消耗值

只需将你的气体极限设置为一些经验发现的粗略估计值

跟踪您的交易,您将看到所有的气体消耗值


现在,天然气退款的工作方式是,在状态转换功能期间,要求您为合同的运行提供全部天然气。在此运行期间,所有天然气退款都累积在StateDB(临时状态对象)中。在状态转换功能结束时,您将获得合同将要发布的所有存储版本的退款。这就是为什么您必须设置Etherscan显示的更高的气体限制,因为假设您的合同需要15000气体才能运行,在释放存储后(比如5000气体),Etherscan将显示交易需要10000气体。这是不正确的,因为你在最后得到了汽油退款,但在开始时你需要全部的汽油(15000)。天然气退款是由矿工赞助的,他的帐户将获得更少的ETH,因为他向您支付这些退款。

感谢您的回复,这是有意义的。我不确定手动设置更高的天然气限值以确保安全(交易警告“似乎”更昂贵)是否是一种好的做法,还是将其留给供应商进行天然气估算。