Ethernaut 题库闯关 #18 — Magic Number

Ethernaut题库闯关连载的第18篇题解。

今天这篇是Ethernaut 题库闯关连载的第18篇,难度等级: 难。

欢迎大家订阅专栏:Ethernaut 题库闯关,坚持挑战下去,你的 Solidity代码能力肯定大有提高。

挑战 #18 神奇数字

要解决这一关,需要我们提供一个 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!

这个挑战非常棘手,我认为如果不了解EVM的工作原理和如何编写手动EVM字节码,你将无法解决这个问题,甚至无法理解解决方案,但无论如何,我们要在这里解决它。

为了解决这个难题,我们在MagicNumFactory合约中看到有两个要求:

  1. 有一个whatIsTheMeaningOfLife函数,在调用时返回0x0000000000000000000000000000002a(bytes32)。这是在十进制中42的十六进制转换。
  2. 我们合约的代码必须小于10个字节

    这些要求似...

剩余50%的内容订阅专栏后可查看

点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

1 条评论

请先 登录 后评论
Ethernaut CTF
Ethernaut CTF
信奉 CODE IS LAW.