⬅ Luckybit blog

How to Prove a Dice Bet was Fair

This is a brief step by step guide that you can follow to prove that your Dice Bet was fair. It is quite a technical post and assumes knowledge of Python and hash functions if you want to use our code snippets.

Premise of Provable Fairness

  • The outcome is known in advance
  • The outcome is hidden from you until the bet is played (the line goes up)
  • The outcome can not be manipulated by the House
  • The outcome can be reproduced, by following a series of mathematical steps, after the bet has been played
  • The reproduced outcome of the bet is the same as the outcome known in advance

Bet Inputs

To generate the outcome for a bet we take several inputs and derive a random value from them.

  • "client_seed": a random string that you can change whenever you want via your "Settings" page.
  • "server_seed_secret": pre-generated by the House. We publish the hash of this as the "server_seed" on your "Settings" page. You can rotate this whenever you want.
  • "seed_nonce": an incrementing value with each bet you play.

Proving a Bet was Fair

If you work through the following steps you can be reassured that the bet was fair.

Step 1

Take note of the "server_seed" found on your "Settings" page. You will compare a computed value to this in Step 4.

Step 2

Now refresh the "server_seed" on your "Settings" page. This will reveal the "server_seed_secret" for all your bets that used the previous "server_seed".

Step 3

Go to your "Bet Browser" page and click on a bet that you want to verify. All the information you need is presented:

dice bet details

Step 4

We have to hide the "server_seed_secret" for the active "server_seed" otherwise you could calculate the outcome for a bet ahead of time. However, you can prove that we used the correct "server_seed_secret" by comparing the hash of "server_seed_secret" to "server_seed":


This value should be the same as the "server_seed" value you wrote down in Step 1.

Step 5

Calculate the "full_seed" aka "Random base16 Integer" on the Bet Panel:

seed = client_seed.encode() + server_seed_secret.encode() + str(seed_nonce).encode()
full_seed = hashlib.sha256(seed.lower()).hexdigest()

Please note your client_seed will be lowercased in this step.

Step 6

Convert the "full_seed" to the random integer:

random_integer = int(full_seed, 16)

And divide it by the maximum possible value(int(64 * 'f', 16)):

Please note that we use Decimal types to avoid any "float" arithmetic errors. If any rounding is needed, we round in favour of players.

outcome = Decimal(random_integer) / Decimal(int(64 * 'f', 16))

To ensure the deterministic nature of this calculation we round and quantize this value with:

outcome.quantize(Decimal("0.0001"), rounding=ROUND_DOWN)

Note that ROUND_DOWN does not influence your winning since we handle the improbable event of roll_over being equal to the outcome in favour of players(see Step 7).

Step 7

Calculate your "profit".

The multiplier is based on the Roll Over and is given to you before the bet. To determine if you win check if roll_over(Your Guess) is greater or equal to the outcome.

Pseudo code:

win = roll_over <= outcome


If you can follow the steps above and reproduce the expected outcomes then you can be sure that the bet was fair.


  1. We can't control the client_seed, you do.
  2. We publish the hash of the server_seed_secret as server_seed in advance.
  3. The seed_nonce is incremental and therefore predictable.