LEVEL 18 (MagicNum):
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
contract MagicNum {
  address public solver;
  constructor() public {}
  function setSolver(address _solver) public {
    solver = _solver;
  }
  /*
    ____________/\\\_______/\\\\\\\\\_____        
     __________/\\\\\_____/\\\///////\\\___       
      ________/\\\/\\\____\///______\//\\\__      
       ______/\\\/\/\\\______________/\\\/___     
        ____/\\\/__\/\\\___________/\\\//_____    
         __/\\\\\\\\\\\\\\\\_____/\\\//________   
          _\///////////\\\//____/\\\/___________  
           ___________\/\\\_____/\\\\\\\\\\\\\\\_ 
            ___________\///_____\///////////////__
  */
}
通关要求
写个合约,设置为solver
  合约要求:
1.调用合约的whatIsTheMeaningOfLife()方法返回一个代表生命意思的答案(科幻梗数字42)
2.合约的字节码要足够小,extcodesize <=10
要点
1.了解yul编码(或以太坊的opcodes)
https://docs.soliditylang.org/en/v0.8.14/yul.html
解题思路
由于需要考虑到合约的大小,所以不能用solidity来编写
可以使用yul来编写,参考官方文档的例子
https://docs.soliditylang.org/en/v0.8.14/yul.html
新建18MagicNum.yul
object "magic42" {
    code {
        //部署
        datacopy(0, dataoffset("runtime"), datasize("runtime"))
        return(0, datasize("runtime"))
    }
    object "runtime" {
        code {
            mstore(0, 0x2a)  //设置mem[0..32]=0x2a
            return(0, 0x20)  //返回mem[0..32]
        }
    }
}
然后用命令编译:
solc --strict-assembly --optimize contracts/18MagicNum.yul
得到
Binary representation:
600a80600c6000396000f3fe602a60005260206000f3
如果使用在线的remix,也可以在线用yul编译,再复制Bytecode->object
如图:

这串是合约部署bytecode,实际部署完会更小
线上过关可以在chrome控制台执行
bytecode = '600a80600c6000396000f3fe602a60005260206000f3'
txn = await web3.eth.sendTransaction({from: player, data: bytecode})
await contract.setSolver(txn.contractAddress)
hardhat里
contracts/18MagicNumRun.sol
  function check(address _runAddress,uint codeszie) external payable {
    require(ILevel(_runAddress).whatIsTheMeaningOfLife() == 42, "not equal 42");
    uint256 size;
    assembly {
      size := extcodesize(_runAddress)
    }
    require(size <= codeszie,"bigger codeszie ");
  } 
test/18MagicNum.js
describe("18MagicNumb", function () {
  let player, levelOwner, levelContract, runContract;
  it("setup", async function () {
    [player, levelOwner] = await ethers.getSigners();
    const interface = ["function whatIsTheMeaningOfLife() returns (uint)"];
    //使用:得到这个solc --strict-assembly --optimize contracts/18MagicNumber.yul
    //也可以使用remix在线编译,再复制Bytecode
    const bytecode = "600a80600c6000396000f3fe602a60005260206000f3";
    const Contract = new ethers.ContractFactory(
      interface,
      bytecode,
      levelOwner
    );
    levelContract = await Contract.deploy();
    await levelContract.deployed();
    runContract = await tools.deployContract("MagicNumRun", player);
  });
  it("attacks", async function () {});
  it("check", async function () {
    //检查通过条件
    await runContract.check(levelContract.address, 10);
  });
});
    
Top comments (0)