首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么DELEGATECALL在我在Remix的合同中使用94k气体?

为什么DELEGATECALL在我在Remix的合同中使用94k气体?
EN

Ethereum用户
提问于 2017-08-03 00:45:49
回答 1查看 1.7K关注 0票数 3

我受到另一个问题的启发,学习了更多关于堆栈深度攻击的知识。

当我试图在Remix上运行attack(1023)时,我的合同是:

代码语言:javascript
复制
pragma solidity ^0.4.14;

contract Attacker {
    uint x;

    function attack(uint y) {
        if (y > x) {
            this.delegatecall(bytes4(sha3('attack(uint256)')), --y);
        }
        else {
            throw ; // doesn't matter, we never get here
        }
    }
}

使用3M汽油,我就用光了228个电话。最后,DELEGATECALL指令似乎使用了大约1.5k的气体。但是在第一部,我看到的是94k。下面是生成该数字的步骤:

  1. 使用Javascript VM在Remix中创建上述合同
  2. 调用attack(1023)
  3. 在调试器用完汽油后单击调试器
  4. 打开“说明”栏,直到DELEGATECALL之前
  5. 在“步骤细节”下,注5977987的“剩余气体”。
  6. 点击“向前一步”
  7. 在“步骤细节”下,注5883892的“剩余气体”。
EN

回答 1

Ethereum用户

回答已采纳

发布于 2017-08-03 06:53:43

更新。我把答案留在下面,因为它有一些有趣的观点,但我想我终于找到了真相。

关键点隐藏在微妙之处页面中:

呼叫或创建最多可以消耗呼叫时剩余气体的63/64;如果呼叫要求超过这个规定的最大值,那么无论要求多少气体,内部调用都只能有规定的最大气体。

这一点在YP中解释得很清楚,所以我不知道我是怎么错过的:-)

所以,您的调用并没有消耗那么多气体,而是不能将所有要调用的气体传递到递归中的下一个调用。如果你的初始气体在6.4M左右,那么你的第一份CALLed合同将收到比你想象的少大约10万的气体。我想这就是你所看到的。在合同终止时,没有传递给呼叫的剩余气体仍未使用,也没有用完。

所以-不是Remix故障(对不起,Remix!)如果有的话,看起来testrpc没有强制执行。

我觉得这是Remix的报道问题。我对您针对testrpc的合同做了一个小小的改动(也就是说,在我自己的环境中,不是Remix ),但是没有看到相同的情况。

代码语言:javascript
复制
pragma solidity ^0.4.13;

contract Attacker {
    uint256 x;

    function attack(uint256 y) payable returns(uint256) {
        if (y > 0) {
            this.delegatecall(bytes4(sha3('attack(uint256)')), --y);
        }
        else {
             // Save the remaining gas in storage so that we can access it later
             x = msg.gas;
             return;             
        }
    }
}

开始的y是使用delegatecall的次数。它把剩余的气体留在储存中,可以用eth_getStorageAt访问。

结果(y是委托调用的次数,值是gas剩余,diff是这个和以前的gas之间的差异)。

  • y=0,2978464
  • y=1,2977288,diff = 1176
  • y=2,2976176,diff = 1112
  • y=3,2975064,diff = 1112
  • y=4,2973952,diff = 1112

在每种情况下,差异都是1112个气体,包括零委托和一个委托之间的差异(除了一个额外的64个气体,我认为这是由于y=0时初始调用数据中的额外零字节造成的;这是按4 gas计费的,而不是一个非零字节的68 )。

这基本上就是我所期望的,这就是为什么我认为Remix在这里一定有点摇摇欲坠。

编辑:只是为了确认Remix的呆滞。使用同样的程序:从气体的内部度量(msg.gas放在存储中),Remix报告说,每增加一段时间,就会再使用大约45000个气体;然而,Remix在合同选项卡上报告的合同执行成本只增加了每个代表团1339个燃气。

请注意,气体是在sstore of x之前计算的,因此我们看不到(很大的)成本。但这并不重要,因为这是一次性的。

票数 6
EN
页面原文内容由Ethereum提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://ethereum.stackexchange.com/questions/23578

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档