# Ethernaut Lvl 3 Coin Flip Walkthrough: how to abuse psuedo randomness in smart contracts

*This is a **in-depth series** around **Zeppelin** team’s **smart contract security puzzles**. I’ll give you the direct resources and key concepts you’ll need to solve the puzzles 100% on your own.*

This levels requires you to correctly guess the outcome of a coin flip, **ten times in a row**.

**How Ethereum generate “randomness”**

There’s no true randomness on Ethereum blockchain, only random generators that are considered “good enough”.

Developers currently create psuedo-randomness in Ethereum by hashing variables that are **unique**, or **difficult to tamper** with. Examples of such variables include `transaction timestamp`

, `sender address`

, `block height`

, etc.

Ethereum then offers two main cryptographic hashing functions, namely, SHA-3 and the newer KECCAK256, which hash the concatenation string of these input variables.

This generated hash is finally converted into a large integer, and then mod’ed by n. This is to get a discrete set of probability integers, inside the desired range of 0 to n.

Notice that in our Ethernaut exercise,

`n=2`

to represent the two sides of a coin flip.

**This method of deriving pseudo-randomness in smart contracts makes them vulnerable to attack.** Adversaries who know the input, can thus guess the “random” outcome.

This is the key to solving your `CoinFlip`

level. Here, the input variables that determine the coin flip are publicly available to you.

# Detailed Walkthrough

Let’s create a malicious contract that checks the outcome of the coin flip.

Only when you’ve *correctly* guessed the outcome, should you invoke the real contract’s `flip(bool _guess)`

function.

- Inside Remix IDE, create a malicious contract that closely mirrors
`CoinFlip.sol`

:

2. Implement a `hackFlip()`

function that predicts the flip outcome, using the same logic and input variables as the original contract. Since you also know `blockhash`

and `block.number`

, you’re able to accurately predict the correct `_guess`

.

Your function should only invoke the `originalContract.flip()`

with the correct `_guess`

.

3. Call your `hackFlip()`

function 10 times. The original contract’s `consecutiveWins`

counter should steadily increase, as you are only making correct guesses.

# Key Security Takeaways

- There’s no such thing as true randomness
**Be careful when calculating “randomness” in your contract**(or even when inheriting from an existing random numbers library). In cases where you use randomness to determine contest winners, remember that**adversaries can easily guess the random outcome and hack your game!**