# Ethernaut - Coin Flip Writeup

By [abbudi](https://paragraph.com/@abbudi) · 2023-06-29

---

Coin Flip is the third Ethernaut challenge, and it involves having to guess a “random” coin flip correctly 10 times in a row. This might seem impossible (or improbable), but we’ll learn that being random in a public blockchain is harder than it sounds.

As always, you can find the full source code for this challenge below on Github.

[https://github.com/imam-abbudi/ethernaut-web3py-solutions/tree/main/coinflip](https://github.com/imam-abbudi/ethernaut-web3py-solutions/tree/main/coinflip)

You’re going to want to download the challenge’s source code locally for this one, keep a folder that looks something like this:

    coinflip/
    |_ Coinflip.sol
    |_ CoinflipExploit.sol
    |_ coinflip.py
    

And yes, we are going to be writing the exploit in Solidity.

### coinflip.sol

![coinflip.sol source code](https://storage.googleapis.com/papyrus_images/f00639d56d8b250d3b3829a76c4033085fbd2cdd9e7026fbcd5793b4bf074372.png)

coinflip.sol source code

This file should include the source code, like this. Reading through the code, we can see that it reads the **block hash** of the **previous block**, divides it by **FACTOR**, and checks if the division is equals to 1. That’s how it picks the **side** of the coin.

It is important to note that we can’t just guess the same **side** ten times in a row in the same **block**. Because the contract will revert if it notices the same **blockValue** is generated twice.

### coinflipExploit.sol

![coinflipExploit.sol source code](https://storage.googleapis.com/papyrus_images/fb6478c79dbb123aeeaf459c27bdfec548e80dd1773a4515dbf498bb490d1cfd.png)

coinflipExploit.sol source code

We can create an interface with the Ethernaut’s challenge by importing the source code, and entering the challenge instance’s address in the constructor when we deploy the contract.

The function **flipGuess()** has the exact same logic as the challenge, and since the two contracts are running on the same network, **blockValue** will be the same value for both contracts. Since we already know **FACTOR**, we can directly import it as it doesn’t change values.

If someone were to call **flipGuess()**, it would create all the variables, and call the challenge contract’s **flip()** function with the correct side. Now we just have to write a Python script to call our **flipGuess()** function 10 blocks in a row.

### coinflip.py

As always we’ll import the necessary modules and variables.

![](https://storage.googleapis.com/papyrus_images/0c9c693d72bb8f4d48800015ce64250fb7e6ae0b74cbe1205055848a168ef953.png)

We’ll also need to **deploy** our contract for this challenge. To do this, we’ll need to get both the **ABI** and **bytecode** from our exploit script.

_A quick reminder_:

> **ABI**: An interface to interact with deployed Solidity contracts on the Ethereum network.

> **Bytecode**: The compiled version of our Solidity program, designed for computers to read instructions rather than humans.

![](https://storage.googleapis.com/papyrus_images/d8f536c7a75732ea031847ffb2b97aa667539f56f6461882a6ad839a632120c5.png)

This function will read our exploit contract, and return a tuple of both the **ABI** and **bytecode**. We will use both of these variables when deploying our contract.

![](https://storage.googleapis.com/papyrus_images/806bac453c9eaf0fb65717a2b9bd9a27f0ed75fa390bbc6a2181137094bd0dc6.png)

We’ll also use this function from previous challenges, it will sign the transaction we want and return the receipt.

![](https://storage.googleapis.com/papyrus_images/6dbfd47b0cb6d609ecf5dedbfb1711231df2a7fb8dd6078ae9aae96a742aed16.png)

Moving onto our **main** function, we will first save our **ABI** and **bytecode** from our exploit contract, build our transaction by supplying gas and its price, and deploy the contract.

In the **constructor** of our exploit contract, we will pass in the address of the Ethernaut challenge instance, which will let our exploit contract know which contract address to attack.

![](https://storage.googleapis.com/papyrus_images/98b7a977316843a3ea2ed9fa425e19316d3b4b3d102cf670d9928995fef8d544.png)

Using the receipt of the exploit contract deployment transaction, we can print the address of our contract if it was deployed successfully, or exit if the transaction failed.

![](https://storage.googleapis.com/papyrus_images/43a162bdcabc9e54e96d70f010b5491f161fe45453a4e0fd03dd2716a37bdbbe.png)

If it was successfully deployed, we’ll use the contract address and the **ABI** we generated at the top of our **main** function to create an instance.

We will also keep track of there number of correct guesses in **correct\_guesses**. In the **while** loop, we call our exploit function. If the transaction goes through, we assume the guess is correct and increment **correct\_guesses** by one.

Once we reach 10 guesses, we print a completion message and exit the program. The challenge is now complete, and you can try submitting on Ethernaut.

> _Note: You could also call the number of correct guesses from the Ethernaut instance itself, but I found that the guesses are always right so it makes more sense to keep a local track of the correct guesses._

---

*Originally published on [abbudi](https://paragraph.com/@abbudi/ethernaut-coin-flip-writeup)*
