Ethernaut题库闯关连载的第18篇题解。
今天这篇是Ethernaut 题库闯关连载的第18篇,难度等级: 难。
欢迎大家订阅专栏:Ethernaut 题库闯关,坚持挑战下去,你的 Solidity代码能力肯定大有提高。
要解决这一关,需要我们提供一个 solver
合约,合约有一个方法 whatIsTheMeaningOfLife()
,返回正确的数字。
很容易吧?嗯...... 有一些要求,要求solver
的代码需要非常小,真的非常非常小。比如说,最多只有10个操作码。
提示:也许是时候暂时离开舒适的Solidity编译器,用手来构建这个原始EVM字节码。
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
contract MagicNum {
address public solver;
constructor() public {}
function setSolver(address _solver) public {
solver = _solver;
}
/*
____________/\\\_______/\\\\\\\\\_____
__________/\\\\\_____/\\\///////\\\___
________/\\\/\\\____\///______\//\\\__
______/\\\/\/\\\______________/\\\/___
____/\\\/__\/\\\___________/\\\//_____
__/\\\\\\\\\\\\\\\\_____/\\\//________
_\///////////\\\//____/\\\/___________
___________\/\\\_____/\\\\\\\\\\\\\\\_
___________\///_____\///////////////__
*/
}
// Query the solver for the magic number.
bytes32 magic = solver.whatIsTheMeaningOfLife();
if (magic != 0x000000000000000000000000000000000000000000000000000000000000002a) return false;
// Require the solver to have at most 10 opcodes.
uint256 size;
assembly {
size := extcodesize(solver)
}
if (size > 10) return false;
为了解决这个难题,我们需要创建和部署一个智能合约,其合约体积小于10个字节,并在调用whatIsTheMeaningOfLife
函数时返回42
。
在查看解题思路之前,可以先自己想一想,自己会怎么做?
你无法理解,当我看到这个挑战时,我是多么的兴奋。我在深入研究EVM时获得的所有努力和知识都得到了回报。
这个挑战非常棘手,我认为如果不了解EVM的工作原理和如何编写手动EVM字节码,你将无法解决这个问题,甚至无法理解解决方案,但无论如何,我们要在这里解决它。
为了解决这个难题,我们在MagicNumFactory
合约中看到有两个要求:
whatIsTheMeaningOfLife
函数,在调用时返回0x0000000000000000000000000000002a
(bytes32)。这是在十进制中42的十六进制转换。我们合约的代码必须小于10个字节
这些要求似...
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!