写在前面
我放弃了
关于
地址
第一条是Rinkeby测试链的题,因为水龙头日常罢工,所以余额不好整,推荐使用第二个Ropsten测试链的。
WriteUp
Level 0 [Hello Ethernaut]
第一次接触以太坊,一脸懵逼,只能照着文本引导一步一步来了。
先在浏览器上装了个MetaMask
,建了个钱包,然后换成Ropsten
测试链。
然后在水龙头Ropsten Ethereum (rETH) Faucet上领取5个测试ETH。
之后回到平台,点击Get new instance
,进行合约交互,等控制台显示Instance address
字样就是创建好实例了。
然后照着文本提示输入await contract.info()
命令,返回You will find what you need in info1().
。
输入await contract.info1()
命令,返回Try info2(), but with "hello" as a parameter.
。
输入await contract.info2("hello")
命令,返回The property infoNum holds the number of the next info method to call.
。
输入await contract.infoNum()
命令,返回42
。
输入await contract.info42()
命令,返回theMethodName is the name of the next method.
。
输入await contract.theMethodName()
命令,返回The method name is method7123949.
。
输入await contract.method7123949()
命令,返回If you know the password, submit it to authenticate().
。
输入await contract.password()
命令,返回ethernaut0
。
输入await contract.authenticate("ethernaut0")
命令,进行登录,等待交易确认。
最后点击Submit instance
即可提交实例进行评测,若操作无误即可拿到合约源码。
pragma solidity ^0.5.0;
contract Instance {
string public password;
uint8 public infoNum = 42;
string public theMethodName = 'The method name is method7123949.';
bool private cleared = false;
// constructor
constructor(string memory _password) public {
password = _password;
}
function info() public pure returns (string memory) {
return 'You will find what you need in info1().';
}
function info1() public pure returns (string memory) {
return 'Try info2(), but with "hello" as a parameter.';
}
function info2(string memory param) public pure returns (string memory) {
if(keccak256(abi.encodePacked(param)) == keccak256(abi.encodePacked('hello'))) {
return 'The property infoNum holds the number of the next info method to call.';
}
return 'Wrong parameter.';
}
function info42() public pure returns (string memory) {
return 'theMethodName is the name of the next method.';
}
function method7123949() public pure returns (string memory) {
return 'If you know the password, submit it to authenticate().';
}
function authenticate(string memory passkey) public {
if(keccak256(abi.encodePacked(passkey)) == keccak256(abi.encodePacked(password))) {
cleared = true;
}
}
function getCleared() public view returns (bool) {
return cleared;
}
}
Chrome内核版本在62以上的务必在每个命令之前加上
await
,不然返回会很奇怪,而且password
似乎不会被初始化导致无法获取返回。
Level 1 [Fallback]
题目给了通关要求:
- 拿到合约的拥有权
- 转出所有余额
先看看给的合约代码。
pragma solidity ^0.5.0;
import 'openzeppelin-solidity/contracts/math/SafeMath.sol';
contract Fallback {
using SafeMath for uint256;
mapping(address => uint) public contributions;
address payable public owner;
constructor() public {
owner = msg.sender;
contributions[msg.sender] = 1000 * (1 ether);
}
modifier onlyOwner {
require(
msg.sender == owner,
"caller is not the owner"
);
_;
}
function contribute() public payable {
require(msg.value < 0.001 ether);
contributions[msg.sender] += msg.value;
if(contributions[msg.sender] > contributions[owner]) {
owner = msg.sender;
}
}
function getContribution() public view returns (uint) {
return contributions[msg.sender];
}
function withdraw() public onlyOwner {
owner.transfer(address(this).balance);
}
function() payable external {
require(msg.value > 0 && contributions[msg.sender] > 0);
owner = msg.sender;
}
}
发现我根本看不懂solidity
语言,等我有空了能看个大概了再回来做。