# Ethernaut CTF Level 0 - Hello Ethernaut
[toc]
## 題目與Setup
https://ethernaut.openzeppelin.com/level/0x7E0f53981657345B31C59aC44e9c21631Ce710c7
<br>
本關算是Setup的一個簡單關卡,目的是認識環境以及Setup
- Setup Metamask
- 選擇Testnet - 我選擇Sepolia
- 先去Faucet要測試Token - https://sepoliafaucet.com/
<br>
設定好後,回到Ethernaut關卡0
按下 `產生新實例` ,進入Dev Console開始遊戲
- 因為是async function, 會需要用 `await`
- `contract.xxx` 是新產生智能合約的實例,我們能夠透過這種方式呼叫合約的function
以下是本題的流程
```javascript=
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")
```
最後,按下 `提交新實例` 通過本關卡
<br>
## Source Code
可以看到我們剛剛用了`await contract.xxx`與合約的function做各種互動
```solidity=
// 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;
}
}
```
<br>
## Foundry Test
```solidity=
// SPDX-License-Identifier: UNLICENSED
// forge test -vvvv --match-test testEthernaut00
pragma solidity ^0.8.0;
import "ds-test/test.sol";
import "forge-std/Vm.sol";
interface Instance {
function authenticate(string memory passkey) external;
function password() external view returns (string memory);
function getCleared() external view returns (bool);
}
contract ContractTest is DSTest {
function setUp() public {
Vm vm = Vm(address(0x7109709ECfa91a80626fF3989D68f67F5b1DD12D));
vm.createSelectFork(vm.rpcUrl("sepolia"));
vm.label(address(this), "Attacker");
vm.label(
address(0x6a924cB09C1E2043527e6Af91BaD1fee61acf805),
"Ethernaut00"
);
}
function testEthernaut00() public {
Instance contract_lv0 = Instance(
0x6a924cB09C1E2043527e6Af91BaD1fee61acf805
);
// Trigger authenticate
contract_lv0.authenticate(contract_lv0.password());
// getCleared
bool result = contract_lv0.getCleared();
assert(result == true);
}
}
```
###### tags:`Ethernaut` `Smart Contract Audit` `Blockchain`