# 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`