3 - Coinflip

randomness in blockchain

Ethernaut Level3: Coinfliparrow-up-right

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract CoinFlip {

  uint256 public consecutiveWins;
  uint256 lastHash;
  uint256 FACTOR = 57896044618658097711785492504343953926634992332820282019728792003956564819968;

  constructor() {
    consecutiveWins = 0;
  }

  function flip(bool _guess) public returns (bool) {
    uint256 blockValue = uint256(blockhash(block.number - 1));

    if (lastHash == blockValue) {
      revert();
    }

    lastHash = blockValue;
    uint256 coinFlip = blockValue / FACTOR;
    bool side = coinFlip == 1 ? true : false;

    if (side == _guess) {
      consecutiveWins++;
      return true;
    } else {
      consecutiveWins = 0;
      return false;
    }
  }
}

Goal of this level

  • guess the correct outcome 10 times in a row

What you should know before

Solution

chevron-rightKey to solve this problem 🔑hashtag

You can mimic the exact calculation of of the random number

Use Remix IDE!

Transaction to call makeGuess() and flip() will be mined in the same block, so the value of block.number will be the same.

You merely have to run makeGuess() function 10 times in a row.

Done! 😎

Why the code uses block.number - 1

The transaction itself affects the value of blockhash, so blockhash(block.number) is fixed to be 0.

Key Takeaways

  • There's no such thing as true randomness in blockchain, every thing is deterministic!

Last updated