3

I'm playing Ethernaut (https://ethernaut.openzeppelin.com/).

I'm currently on level 3 (Coin Flip).

This is the Coin Flip contract:

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

import '@openzeppelin/contracts/math/SafeMath.sol';

contract CoinFlip {

  using SafeMath for uint256;
  uint256 public consecutiveWins;
  uint256 lastHash;
  uint256 FACTOR = 57896044618658097711785492504343953926634992332820282019728792003956564819968;

  constructor() public {
    consecutiveWins = 0;
  }

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

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

    lastHash = blockValue;
    uint256 coinFlip = blockValue.div(FACTOR);
    bool side = coinFlip == 1 ? true : false;

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

I deployed this code in the Remix IDE.

However, whenever I call flip(), I get:

transact to CoinFlip.flip errored: NotFoundError: Key not found in database [h n]

I searched for this problem online, but most related questions involve Web3, Ganache, RPCs or something of the sort. And the answers aren't really what I'm looking for.

I tried:

  • flip()
  • flip(0)
  • flip(1)
  • flip(false)
  • flip(true)
  • flip("false")
  • flip("true")
  • increasing the gasLimit
  • refreshing the page

Nothing fixed it. Same error gets thrown.

Am I doing something wrong? Is the problem in the Smart Contract? Or is it in Remix?

Secondary Question: What's the proper way to pass in a bool parameter to a function?

0 and 1? false and true? "false" and "true"?

Thanks.

1 Answer 1

5

I encountered the same error when solving the same Ethernaut level. I'm using Remix IDE. When I changed from deploying with JavaScript VM to deploying with Injected Web3 (there's a dropdown menu in DEPLOY & RUN TRANSACTIONS in Remix and you need MetaMask to deploy this way), the error disappeared.

I added the following function to the contract:

  function blockValue() view public returns (uint256) {
      return uint256(blockhash(block.number - 1));
  }

and it was still throwing the error when calling blockValue instead of flip. So I think the reason is that the simulation of blocks in JavaScript VM isn't realistic enough for blockhash to work properly.

Answer to secondary question: I passed true and it incremented consecutiveWins, so true and false should be correct.

2
  • Encountered and figured the same: blockhash(block.number - 1) seems to be the issue, probably because there is no previous block in a fresh network.
    – gadget
    Nov 17, 2021 at 12:00
  • Yes, blockhash() does not work properly on the remix testnet
    – Lynn Han
    Mar 7, 2022 at 8:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.