⬅ Luckybit blog

Plinko´s Provable Fairness

This is a brief step by step guide that you can follow to prove that your Plinko 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 coin falls)
  • 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 a bet you have played 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.

Change your "client_seed" if you want to, and then play some bets.

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:


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":

server_seed = hashlib.sha256(server_seed_secret.encode()).hexdigest()

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 string" 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 falling coin's path, and the multiplier it lands on.

binary_string = bin(int(full_seed, 16))[-16:]
path = [int(char) for char in binary_string]

"path" will be a list of '0's and '1's like [0,0,1,0,1,1,0,1,0,1,0,0,1,0,1,0]

'0' represents "left", and '1' represents "right" as you look at the Plinko board.

multiplier_position = sum(path) # value between 0 and 16

So we get the "multiplier" from the position: 0 is left-most, 16 is right-most.

"Row" tells us which colour band you chose to play: 0 is top-most, ie Blue.

Step 7

Calculate your "profit".

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

Pseudo code:

outcome_amount = bet_amount * multiplier

profit = outcome_amount - bet_amount


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.