Ethernaut Level 3: Coin Flip Tutorial
Tags: solidity, tutorial, smartcontract, blockchain
Published: 2022-01-21 17:31:29

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

`Blockhash`is 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);
    }
}
```

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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/srxo9hcawmhuab6lr2hu.png)

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


![ethernaut level 3](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/47frmtaj78iysvqq3oyq.jpg)
 
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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5vwysnrlc5f2u615kvqy.jpg)

You are the winner!