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!这就表示成功通过了这个关卡了