포스트

1. Hello Ethernaut

1. Hello Ethernaut

이 글은 티스토리에서 옮겨온 글입니다.

HSPACE 나이츠 프론티어 프로젝트의 일환으로, 평소 궁금했던 Web3에 대한 공부를 수행하기 위해 OpenZepplin에서 만든 Web3 wargame인 The Ethernaut를 풀어보았습니다. 아직은 Solidity문법이 뭔지 잘 모르지만, 일단 풀어 보면서 알아볼 예정입니다.


Hello Ethernaut

이 wargame이 어떻게 돌아가는지 기본적인 방법을 알아가는 문제입니다. 1번~9번까지 안내에 따라 설정하면 됩니다.
MetaMask를 처음 시작하여 지갑에 이더가 없는 경우, 이더 파우셋으로 무료 이더를 받을 수 있습니다. 제 경우 기존 MetaMask가 지원하는 파우셋 기능이 찾아봐도 안보여서(신규 패치 후 사라졌을 수 있습니다.) 다른 방법으로 Sepolia Ether를 확보해야 했습니다.

테스트용 Sepolia Ether 채굴하기

다음 소개할 사이트는 테스트용 Sepolia Ether를 본인의 컴퓨터 자원을 사용해 채굴해 입금받을 수 있는 사이트입니다. 채굴 시작 후 최소 0.05ETH부터 입금이 가능합니다.
https://sepolia-faucet.pk910.de/#/
alchemy같은 faucet사이트에서는 이제 기본 ETH를 일정량 보유하고 있어야 파우셋을 받을 수 있기 때문에 위 방법을 사용하면 조금 걸리더라도 확실하게 받을 수 있을 것입니다.


풀이

지갑에 성공적으로 테스트 이더를 보유하게 되었다면, wargame사이트에 재접속했을 때 MetaMask와 사이트가 연결을 시도합니다. 이 때 지갑에서 연결 수수료를 요구하기 때문에 소량의 이더가 필요한 것입니다. 이후 사이트에서 레벨 인스턴스 생성 버튼을 클릭해 인스턴스를 생성해달라고 요청하고, 승인하여 문제의 컨트랙트를 조사합니다.

연결 후 문제의 설명대로 console에 명령들을 입력해보면, 다음과 같은 현재 연결된 메인 스마트 컨트랙트의 메서드를 볼 수 있습니다. 여러 메서드들을 실행해 보면서 문제를 조사합니다.

몇몇 메소드를 실행해 보면, 위 내용처럼 문제를 어떻게 풀어야 하는지 설명이 존재합니다. 위와 같이 알아낸 password를 인증하면, MetaMask에 트랜젝션 요청이 왔음을 확인할 수 있습니다.

컨펌 버튼을 누르고, 문제 사이트에서 레벨 완료하기 버튼을 누르면 됩니다.

소스코드

문제를 다 풀고 나서야 보여줍니다. 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;
    }
}
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.