Plinko Provably Fair Verifier

MintDice's provably fair verifier for their plinko game. Learn more about cryptocurrency and bitcoin gambling here.

by Mint Dice

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/rollups/hmac-sha256.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/js-sha512/0.8.0/sha512.min.js"></script>
<h1> <span class="green">MintDice</span> Provably Fair Verifier</h1>
<h2>Plinko</h2>
<p>This is the <a href="https://www.mintdice.com" target="_blank" rel="noopener noreferrer">MintDice</a> provably fair verifier for their plinko game. To learn more about provably fair, <a href="https://provablyfair.org/" target="_blank" rel="noopener noreferrer">refer here</a>. </p>
<p>Color is used to calculate the multiplier, does not change the provably result</p>
<p>Each plinko roll has a 1 in 6 chance to double the multiplier.</p>
<div class="inputs group">
  <div>
    <div class="input">
      <label for="server-seed">Server Seed:</label>
      <input type="text" id="server-seed">
    </div>
    <div class="input">
      <label for="user-seed">User Seed (Nonced):</label>
      <input type="text" id="user-seed">
    </div>
    <div class="input radio">
      <label for="color">Color:</label>
      <div class="radios">
        <input type="radio" name="color" value="red"> Red 
        <input type="radio" name="color" value="green"> Green
        <input type="radio" name="color" value="blue" checked="checked"> Blue 
        <input type="radio" name="color" value="white"> White 
      </div>
    </div>
  </div>
  <button class="calculate" id="button">
    Calculate
  </button>
</div>
<br />
<div class="outputs group">
  <div class="input">
    <label for="result">Result:</label>
    <input type="text" readonly id="result">
  </div>
  <div class="input">
    <label for="multiplier">Multiplier:</label>
    <input type="text" readonly id ="multiplier">
  </div>
  <div class="input">
    <label for="doubled">Doubled:</label>
    <input type="text" readonly id ="doubled">
  </div>
  <div class="input">
    <label for="server-hash">Server Seed Hash:</label>
    <input type="text" readonly...

CSS

h1,
h2 {
  text-align: center;
}

.green {
  color: #37bd64;
}

.blue {
  color: #4fafd9;
}


.input {
  display: flex;
  justify-content: space-between;
  width: 650px;
  margin: 2px 0px;
}

.group {
  padding: 10px;
  border: 3px solid black;
  border-radius: 10px;
}

.inputs {
  border-color: #37bd64;
  display: flex;
}

.inputs label {
  cursor: pointer;
}

.outputs {
  border-color: #4fafd9;
}

.calculate {
  margin-left: 10px;
  cursor: pointer;
}

input {
  width: 500px;
}

.radios input {
  width: unset;
}

JavaScript

document.getElementById('button').onclick = calculate;

function calculate() {
  const serverSeed = document.getElementById('server-seed').value.trim();
  
  // this should be the concated userSeed + nonce with a '-' inbetween
  // so if your user seed is: "aHDF3sdf234sdf" and your nonce is: 3, the expected userSeed would be: "ahjfasdf234sdf-3"
  const userSeed = document.getElementById('user-seed').value.trim();
  const color = document.querySelector('input[name="color"]:checked').value;

  const {
    result,
    serverHash,
    hash,
    multiplier,
    doubled,
  } = provablyCalculate(serverSeed, userSeed, color);

  document.getElementById('result').value = result;
  document.getElementById('server-hash').value = serverHash;
  document.getElementById('hash').value = hash;
  document.getElementById('multiplier').value = multiplier;
  document.getElementById('doubled').value = doubled;
}

const provablyHashLength = 4;

function provablyCalculate(serverSeed, userSeed, color) {
  const serverHash = CryptoJS.SHA256(serverSeed).toString();
  
  // The library used to compute a HMAC SHA512 is here: https://github.com/emn178/js-sha512
  // While it almost certainly will always work properly, as it is not the library MintDice uses
  // to calculate the results, there is always a small chance of inconsistency between the calculated values.
  // If there are any issues, please email support@mintdice.com
  const hash = sha512.hmac.create(serverSeed).update(userSeed).hex();
  const result = provablyCalculator(hash);
  const doubled = doubledCalculator(hash.substring(provablyHashLength));
  const multiplier = multiplierCalculator(result, color);

  return {
    result,
    serverHash,
    hash,
    multiplier: doubled ? multiplier * 2 : multiplier,
    doubled,
  };
}

function provablyCalculator(hash) {
	return parseInt(hash.substring(0, provablyHashLength), 16);
}

function doubledCalculator(hash) {
	const result = zeroToHundred(hash);
  return result < 100 /...