DEV Community

Cover image for Ethernaut - Lvl 0: Hello Ethernaut
pacelliv
pacelliv

Posted on • Updated on

Ethernaut - Lvl 0: Hello Ethernaut

Requirements: basic smart contracts knowledge.

Intro πŸ‘‹πŸ‘‹

Hello fren, my name is Pacelli.

In this series I will be presenting my solutions to the Ethernaut hacking challenges created by the OpenZeppelin team.

Although there are many repos and blogs around the web with the solutions to these challenges, I still decided to make the exercise of publishing my own solutions and explations for my own benefit and in the hope that this blog will help future readers looking for up-to-date solutions.

For the majority of the challenges Remix IDE will be enough, except for some cases in which an editor like VS Code will be necessary.

To play the game you will need:

  • Metamask. If you don't have it installed in your browser learn how to set up a profile for free.
  • Test ether. My recommendation is to use the Sepolia tesnet because is the one with most active faucets. You can get test ether from either the Alchemy or Chainlink faucets.

Get some test ether and come back!

How does Ethernaut works? βš™οΈ

All smart contracts source code are compiled into two formats, by the Ethereum Virtual Machine (EVM):

  • Application Binary Interface (ABI): communication layer between Solidity and Javascript, in JSON format.
  • Bytecode: low-level machine language that it's interpreted and executed by the EVM.

When you request Get new instance for each level, Ethernaut compiles and deploy the bytecode to a new address on the network you're connected.

Deployment process of smart contracts and how clients access smart contracts from the blockchain

Once a new instance of the level is created on the blockchain, an address is returned to your web client through an event emitted by the main contract game, Ethernaut.sol:

// This is a fragment of the contract

event LevelInstanceCreatedLog(
    address indexed player,
    address indexed instance,
    address indexed level
);

function createLevelInstance(Level _level) public payable {
    // Ensure level is registered.
    require(registeredLevels[address(_level)], "This level doesn't exists");

    // Get level factory to create an instance.
    address instance = _level.createInstance{value: msg.value}(msg.sender);

    // Store emitted instance relationship with player and level.
    emittedInstances[instance] = EmittedInstanceData(
        msg.sender,
        _level,
        false
    );

    statistics.createNewInstance(instance, address(_level), msg.sender);

    // Retrieve created instance via logs.
    emit LevelInstanceCreatedLog(msg.sender, instance, address(_level));
}
Enter fullscreen mode Exit fullscreen mode

Finally, with the help of web3js an ABI is wrapped around the new contract instance that will allow you to easily interact with it using the console in your developer tools.

ABI of created contract instance

Also is important to mention the game provides a series of custom web3 add-ons, some of them will be useful to solve the challenges.

Challenge Walkthrough πŸšΆπŸ½β€β™€οΈπŸšΆπŸ½

This a introductory challenge, its main objective is to help us get related with the UI and how to interact with a contract using web3js and the ABI.

Let's solve this challenge:

  • Request a new instance of this level, send the transaction and wait for it to be mined so you to get a Intance address for this leven.
  • Open your developer tools, type contract and press enter. This will print the recently deployed contract to the console. This contract object contains an abi with all the methods we can call.
  • Type await contract.info(), this will return:
'You will find what you need in info1().'
Enter fullscreen mode Exit fullscreen mode
  • Let's follow the new instruction by calling the info1() method, type await contract.info1(), now you will get:
'Try info2(), but with "hello" as a parameter.'
Enter fullscreen mode Exit fullscreen mode
  • This time it is a little different, now we have to call the method with a parameter like this await contract.info2("hello") and it will return:
'The property infoNum holds the number of the next info method to call.'
Enter fullscreen mode Exit fullscreen mode
  • If you call the infoNum method it will return an object. The information we required is in the first element of the words property. We can access this value more easily with this syntax (await contract.infoNum()).words[0].
  • The previous contract call returned "42". This is a clue to help us determine the next method we need to call. If we inspect the ABI of the contract again, we will see a info42 method. This is the method we have to call next.
  • Type await contract.info42() and you will see in the console:
'theMethodName is the name of the next method.'
Enter fullscreen mode Exit fullscreen mode
  • Call await contract.theMethodName(), it will return:
'The method name is method7123949.'
Enter fullscreen mode Exit fullscreen mode
  • After calling await contract.method7123949(), the contract will return this message:
'If you know the password, submit it to authenticate().'
Enter fullscreen mode Exit fullscreen mode
  • We have to call the authenticate method with a password, but we don't know it yet. Luckily for us and not for the dev who wrote this contract, the password is stored in the contract (big mistake). To read the password type password = await contract.password():
// this is the password:
'ethernaut0'
Enter fullscreen mode Exit fullscreen mode
  • Finally type await contract.authenticate(password) and press enter. Metamask will pop-up, send the transaction and wait for it to be mined to get a transaction receipt.
  • Submit the instance to complete this level.

Uf! 😩 those were a lot of contract calls, but it wasn't so terrible right?

Conclusion βœ”οΈ

After clearing this level you will see Instance.sol with the code you just interacted with. The methods of this contract acted as breadcrumbs that we follow to discover the password to clear this level.

Data in the blockchain is public and everybody can see it. Storing sensitive data in a blockchain is a huge mistake.

Further reading πŸ“š

Top comments (0)