智能合约:Ethernaut题解(一)

2020-05-18 15:08:04 浏览数 (1)

Ethernaut 是一个部署在 Ropsten 测试网络上面的智能合约代码审计类题目,网址:

https://ethernaut.openzeppelin.com

先说一下开始之前的配置,首先要下一个插件,叫 MetaMask,跟着提示做就好了,然后我们需要点以太币来做题,因为我们用的是测试网络,所以有白嫖的方法,不用挖矿啥的

如果不能展示这个页面,可以试试换个电脑试试,我就是笔记本死活打不开,非要说我在主网上,然后把之前生成账号的那 12 个单词保存下来,用我家台式机登上获取了五个(最多能拿五个,另外后来发现我笔记本 360 浏览器能访问,chrome 不行)

在题目网站里面摁下 F12 打开控制台,然后输入 player,如果能展示出跟你 metamask 插件一样的地址的话,就说明环境没问题了

如果不行:科学上网,重启 MetaMask 插件,甚至换个浏览器、换台电脑都可以试试,总有一个适合你

Hello Ethernaut

这一关主要是告诉你怎么玩的

输入 player 就可以看到你的账户地址

getBalance(player) 查看以太币余额

chrome v62 以上的版本,可以用 await getBalance(player) 更简洁

ethernaut 可以查看合约

await ethernaut.owner() 可以看一下合约的拥有者

上面并不是这个游戏的关卡,只是一些简单的命令,让你了解了解

玩游戏时,不会直接与 ethernaut 合约进行交互。它会给你生成一个关卡实例。只要单击页面底部的蓝色按钮就可以生成。metamask 会弹一个框,确认就行

题目同时给出了源码,你可以从 info() 开始执行,根据提示,一步一步走

代码语言:javascript复制
pragma solidity ^0.4.18;
contract Instance {
  string public password;
  uint8 public infoNum = 42;
  string public theMethodName = 'The method name is method7123949.';
  bool private cleared = false;
  //上面声明了一系列的变量
  function Instance(string _password) public {
    password = _password;
  }//构造函数,password=_password
  function info() public pure returns (string) {
    return 'You will find what you need in info1().';
  }//info()函数返回一串字符串
  function info1() public pure returns (string) {
    return 'Try info2(), but with "hello" as a parameter.';
  }//info1()函数返回一串字符串
  function info2(string param) public pure returns (string) {
    if(keccak256(param) == keccak256('hello')) {
      return 'The property infoNum holds the number of the next info method to call.';
    }//info2()接受一个字符串与‘hello’比较一样则返回上面的,否则返回下面的
    return 'Wrong parameter.';
  }
  function info42() public pure returns (string) {
    return 'theMethodName is the name of the next method.';
  }//info()42返回一串字符串
  function method7123949() public pure returns (string) {
    return 'If you know the password, submit it to authenticate().';
  }//method7123949()返回一串字符串
  function authenticate(string passkey) public {
    if(keccak256(passkey) == keccak256(password)) {
      cleared = true;
    }//authenticate()接受一个字符串参数
  }//与password进行比较,一样的话cleared改为true
  function getCleared() public view returns (bool) {
    return cleared;
  }//返回cleared的状态
}

就像这样

也可以直接看源码,想要通过的话,也就是想要改变 cleared 的话,需要调用 authenticate,并且传入 passkey 与 password 进行 hash 的比较。可以看前面第三行,password 的定义是 public 的,所以可以直接:

代码语言:javascript复制
await contract.password()
await contract.authenticate("ethernaut0")

然后就可以点击那个橙色的摁钮提交了

OHHHHHHH,Well done!这就表示成功通过了这个关卡了

0 人点赞