1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
| pragma solidity 0.8.21;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
contract A{ function number() pure external returns(uint256){ return 10; } }
contract MyToken is ERC20 { constructor() ERC20("MyToken", "MTK") { _mint(msg.sender,100); }
}
contract GuessGame { uint256 private immutable random01; uint256 private immutable random02; uint256 private immutable random03; A private immutable random04; MyToken private immutable mytoken;
constructor(A _a) public { mytoken = new MyToken();
random01 = uint160(msg.sender); random02 = uint256(keccak256(address(new A()).code)); random03 = block.timestamp; random04 = _a; // 不要输入A的合约的地址,输入B合约的地址 pureFunc(); }
function pureFunc() pure internal { assembly{ // 1,2,32才是实际的random01、random02、random03的值 mstore(0x80,1) mstore(0xa0,2) mstore(0xc0,32) } }
function guess(uint256 _random01, uint256 _random02, uint256 _random03, uint256 _random04) external payable returns(bool){ if(msg.value > 100 ether){ // 100 eth! you are VIP! }else{ // 零槽位 // _random01 = 0x60 = 96 && msg.value = 1 wei uint256[] memory arr; uint256 money = msg.value; assembly{ mstore(_random01, money) } require(random01 == arr.length,"wrong number01"); }
// CREATE2 // C4 + 1 + 2 + 32 + ? = 2 // msg.sender = 0x5B38Da6a701c568545dCfcB03FcB875f56beddC4 // 231 + ? = 2 ==> 0xE7(231) + ? = 0x02(2) ==> ?=27 // ==> _random02=27 // 玩家需要自行计算自己的_random02,27是举个例子 uint256 y = ( uint160(address(msg.sender)) + random01 + random02 + random03 + _random02) & 0xff; require(random02 == y,"wrong number02");
// 似乎想用CREATE2爆破?这难度非常高,爆破要非常久 // 不不不,这里的考点不是CREATE2而是precompile contract // _random03 = 0x0000000000000000000000000000000000000002 sha2-256 input: any output: bytes32 require(uint160(_random03) < uint160(0x0000000000fFff8545DcFcb03fCB875F56bedDc4)); (,bytes memory data) = address(uint160(_random03)).staticcall("Fallbacker()"); require(random03 == data.length,"wrong number03");
// random 并不是new 出来的。B合约不verify,反编译可以得到number()为11,或者直接获取number() // _random04 = 11 require(random04.number() == _random04, "wrong number04");
mytoken.transfer(msg.sender,100); payable(msg.sender).transfer(address(this).balance);
return true; }
function captureTheFalg() external view returns(bool){ return mytoken.balanceOf(address(this)) == 0; }
}
|