Requirement
Trước khi vào làm các challenge ta cần một số thứ như sau:
- Metamask
- Sepolia network để lấy vài test ether: https://sepoliafaucet.com/
- Remix IDE (IDE để viết contract, compile, deploy,…): https://remix.ethereum.org/
Level 0: Hello Ethernaut
★☆☆☆☆
Chúng ta sẽ bắt đầu với một warmup challenge trước
Solution
Gợi ý của challenge là bắt đầu với contract.info()
trong console của Chrome, làm theo hướng dẫn ta sẽ được như sau:
1
2
3
4
|
await contract.info()
"You will find what you need in info1()."
|
1
2
| await contract.info1()
"Try info2(), but with "hello" as a parameter."
|
1
2
3
|
await contract.info2("hello")
"The property infoNum holds the number of the next info method to call."
|
Nhìn trong array, ta biết được phương thức sẽ gọi tiếp theo là info42()
1
2
3
4
5
6
7
|
await contract.infoNum()
t {s: 1, e: 1, c: Array(1)}
c: [42]
e: 1
s: 1
__proto__: Object
|
1
2
| await contract.info42()
"theMethodName is the name of the next method."
|
Tiếp tục gọi tới contract.theMethodName
1
2
3
|
await contract.theMethodName()
"The method name is method7123949."
|
1
2
| await contract.method7123949()
"If you know the password, submit it to authenticate()."
|
Sau khi gọi xong phương thức, ta để ý contract có phương thức password, gọi phương thức password và submit nó vào contract.authenticate
thôi.
1
2
| await contract.password()
"ethernaut0"
|
1
| await contract.authenticate("ethernaut0")
|
Submit instance ==> Done
Source code của challenge
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.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) {
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;
}
}