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)