DEV Community

Cover image for Ethernaut Level 3: Coin Flip Tutorial
Kamil Polak
Kamil Polak

Posted on

Ethernaut Level 3: Coin Flip Tutorial

In level 3 you have to play a game: coin flip. To complete this level you'll need to guess the correct outcome of a coin flip 10 times in a row.

So let's look at the code of the smart contract. We can see that there is only one function - flip.

The flip function takes a boolean value as its argument which
represents a side of the coin that's being flipped and it returns a boolean that says whether the caller of this function won or not.

Let me also explain the following line of code.

uint256 blockValue = uint256(blockhash(block.number.sub(1)))
Enter fullscreen mode Exit fullscreen mode

Blockhashis a global variable that takes blocknumber and returns hash of the given block when blocknumber is one of the 256 most recent blocks; otherwise returns zero.

block.number.sub(1) returns the block number of the last block. Why the last one, not the current one? Because at the time the function is called, the current block is not yet mineded.

To sum up, the random number is being generated from the block hash or the hash of the previously mined block. This number is used as the source of randomness which ultimately influences the
side of the flipped coin.

We can use something like a proxy contract and in the code
we could mimic the exact calculation of the hash of the previously mined block to generate the random number that we know this function is using.

Next, we can copy the rest of the contract logic to get the same results.

contract HackCoinFlip{

    using SafeMath for uint256;
    CoinFlip public coinFlipContract;
    uint256 FACTOR = 57896044618658097711785492504343953926634992332820282019728792003956564819968;

    constructor(address _coinFlipContract) public{
        coinFlipContract = CoinFlip(_coinFlipContract);
    }
    function makeGuess() public {

        uint256 blockValue = uint256(blockhash(block.number.sub(1)));
        uint256 coinFlip = blockValue.div(FACTOR);
        bool guess = coinFlip == 1 ? true : false;

        coinFlipContract.flip(guess);
    }
}
Enter fullscreen mode Exit fullscreen mode

Note: in this case you need to use Remix IDE because it is not possible to upload an external smart contract.

To do that just copy&paste the CoinFlip and HackCoinFlip contracts. Keep in mind that before you deploy the contract you have to change the environment from JavaScript VM to Injected Web3 to be able to approve transactions using MetaMask.

ethernaut level 3

Before we interact with smart contract let's check the initial state of consecutiveWins

ethernaut level 3

As you can see it is 0. When you call the flip function in the HackCoinFlip contract the value will increase to 1. However, to win the game we need to guess the correct outcome of a coin flip 10 times in a row. This means that you have to call the function 10 times.

When you do this you should see something like this

ethernaut level 3

You are the winner!

Top comments (0)