《我学区块链》—— 十八、以太坊安全之 call depth 调用深度限制

十八、以太坊安全之 call depth(调用深度限制)

       调用深度(call depth)被限制为 1024。EVM 中一个智能合约可以通过 message call 调用其它智能合约,被调用的智能合约可以继续通过 message call 再调用其它合约,甚至是再调用回来(recursive)。嵌套调用的深度被限定为 1024。

       看下面这段代码:

function sendether() {
    address addr = 0x6c8f2a135f6ed072de4503bd7c4999a1a17f824b;
    addr.send(20 ether);
    //you think the send should return true
    var thesendok = true;
    //do something regarding send returns ok
    ...
}

       并且对方的 fallback 函数定义为:

function() {
    //do nothing
}

       你认为你的代码肯定是安全的,因为对方已经明确定义了 fallback 方法。但是你错了,攻击者只需要制造出 1023 个嵌套调用,然后再调用 sendether(),就可以让 add.send(20 ether) 失败,而其它执行成功。代码如下:

function hack() {
    var count = 0;
    while (count < 1023) {
        this.hack();
        //this keyword makes it a message call
        count++;
    }
    if (count == 1023) {
        thecallingaddr.call("sendether");
    }
}

       所以为了解决深度限制的问题,正确的写法应该是在每次涉及到 call depth 增加的地方都检查调用返回是否正确,如下:

function sendether() {
    address addr = 0x6c8f2a135f6ed072de4503bd7c4999a1a17f824b;
    if (!addr.send(20 ether)) {
        throw;
        //somebody hacks me
    }
    //you think the send should return true
    var thesendok = true;
    //do something regarding send returns ok
    ...
}

       以上为调用深度问题的演示,与防治,希望对小伙伴们有用。

猜你喜欢

转载自blog.csdn.net/xuguangyuansh/article/details/81329671