63/64rule和EIP150

背景

介绍以太坊中的63/64 Rule。

Call Depth Attack

以太坊的合约可调用合约的,但调用的深度是有限制,最大为1024层。

在EVM.Call中有这样具体的处理逻辑:

// Fail if we're trying to execute above the call depth limit
if evm.depth > int(params.CallCreateDepth) {
    return nil, gas, ErrDepth
}

显然,如果大于1024层调用,就返回失败。

也就是说,在理论上,没有一个合约的调用是一定会成功的,都有出错的可能,

但是有些合约在编写时,没有考虑过这个问题,并没有处理可能的失败,比如这个合约例子:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.5;

// DO NOT USE!!!
contract Auction {
    address highestBidder;
    uint256 highestBid;

    function bid() external payable {
        if (msg.value < highestBid) revert();

        if (highestBidder != address(0)) {
            //might be error
            payable(highestBidder).send(highestBid); // refund previous bidder
        }
        highestBidder = msg.sender;
        highestBid = msg.value;
    }
}

这个合约中,payable(highestBidder).send(highestBid)这个调用,是可能失败的。

如果当前Auction合约的调用已经是1024层,再掉用send就会失败,由于这个合约没有处理send的返回值,导致合约会在send调用失败的情况下,继续执行后面的逻辑。

攻击者察觉到这个机会,于是就会故意创建足够深度的合约调用,来触发大于1024层的调用上限,进而达到自己的目的。上面这个合约例子中,send失败会导致不给前一个最高的bidder转账,实现最高bidder角色的转移。

这种利用1024上限的攻击,叫做call depth attack。而以太坊的应对方案是63/64 Rule,在EIP150中被提出。

63/64 Rule

63/64 Rule的思路很简单,就是调用下一层合约时,调用者会保留1/64的gas,只剩下最多63/64的Gas传递到被调用合约中。

比如A合约调用B合约的时候,A拥有1000Gas:

  • 在63/64Rule出现之前,A最多可以把1000Gas全部传递给B,作为B合约调用的GasLimit。
  • 在63/64Rule出现之后,A最多只能传递1000*(63/64)=984的Gas给B, 作为B合约调用的GasLimit。

这样随着调用深度的增加,越往后的合约,能够拥有的GasLimit越少,很快Gas就花光了,根本支撑不到1024层最大限制。

这个花费的效果如图:

也就是虽然1024层最大限制存在,call depth attack也存在,但是海量的Gas消耗让攻击者无法达到1024的上限。

Gas费不够引起的失败安全吗

回到合约例子:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.5;

// DO NOT USE!!!
contract Auction {
    address highestBidder;
    uint256 highestBid;

    function bid() external payable {
        if (msg.value < highestBid) revert();

        if (highestBidder != address(0)) {
            //might be error
            payable(highestBidder).send(highestBid); // refund previous bidder
        }
        highestBidder = msg.sender;
        highestBid = msg.value;
    }
}

payable(highestBidder).send(highestBid)这行代码没有处理返回错误,虽然63/64 rule的引用,让攻击者无法触发call depth attack。

但如果正常执行send代码时,因为Gas费不够失败了,这个合约中没有处理send的返回错误,安全吗?

答案是安全的,因为Gas费不够了,而send后面的代码会消费Gas,所以不会被执行,整个合约的调用就终止了。

这和call depth attack是有区别的。call depth attack触发时,Gas费完全可能是充足的,send后面的代码依然会被执行。

Ref



《 “63/64rule和EIP150” 》 有 5 条评论

  1. where can i buy cheap cytotec without dr prescription A key strategy for for preventing relapse and aborting manic episodes Part two

  2. to enhance percutaneous effectiveness, the compositions or complexes comprise penetration enhancers that improve percutaneous absorption by reducing the resistance of stratum corneum by reversibly altering its physicochemical properties, changing hydration in the stratum corneum, acting as co solvent, or changing the organization of lipids or proteins in the intracellular spaces can i get cheap cytotec

  3. Macrophages are intricately involved in the presentation of antigens to lymphocytes and in the subsequent removal of immune complexes buy priligy in usa

  4. pqf64cd8e32f5ac7553c150bd05d6f2252bb73f68dpq 的头像
    pqf64cd8e32f5ac7553c150bd05d6f2252bb73f68dpq

    pq118a9989815489c24b81b160782015890ed2085epq

回复 can i order cheap cytotec without prescription 取消回复

您的邮箱地址不会被公开。 必填项已用 * 标注

About Me

一位程序员,会弹吉他,喜欢读诗。
有一颗感恩的心,一位美丽的妻子,两个可爱的女儿
mail: geraldlee0825@gmail.com
github: https://github.com/lisuxiaoqi
medium: https://medium.com/@geraldlee0825