Skip to main content
All CollectionsFairness
Coin flip game - PvP
Coin flip game - PvP
Nootiih avatar
Written by Nootiih
Updated over a week ago

PvP uses a system of provable fairness whereby the public seed is not known to anyone until the bets have already been committed and the game has started. This ensures that nobody can know the result in advance, not even us, since a part of the three-part seed used to generate the final result is unknown until after the bets have been committed.

We offer verification which allows users to check the integrity of every game and confirm that the results are not manipulated. Every randomly generated result is calculated from a three-part seed based on a seed pair and a nonce. The seed pair is made up of a public seed and a server seed. This pair is "nonced" with a unique number to generate a random final result.

NONCE

For Coin Flip, we use the numerical ID of the PvP round as the nonce, this ID is a unique sequential number which is incremented each time a new PvP round is played by anyone on the site. The nonces used are also published and committed to before the EOS Hash (public seed) is known to us. The nonces are visible in the Provably Fair modal from the PvP Duel Page and can be seen before the round has been started or the public seed (EOS Hash) has been generated.

PUBLIC SEED (EOS HASH)

The public seed (EOS Hash) is known only when all of the players in the round have committed their bets. We achieve this by committing to an EOS Block that is not yet mined but will be in the near future, and we then use its hash as the public seed. This way, we can prove that we had no way of knowing what the seed would be in advance before the game starts.

SERVER SEED

The server seed is a random string which is generated at the beginning of a new PvP Round. We commit to this seed as soon as the round is created and we immediately display the SHA256 hash of this seed. As soon as the round has been played, we then reveal the unhashed version of the seed. You can confirm that the seed was unmodified and no manipulation was done on our end by comparing the original SHA256 hash (the one that was displayed at the beginning) with the revealed seed shown after. This can be verified independently in a programming language such as JavaScript, by applying the SHA256 hashing function to the revealed seed and comparing the output with the hash which was shown earlier. It can also easily be confirmed online using tools such ashttps://xorbin.com/tools/sha256-hash-calculator

INDEPENDENT VERIFICATION

Each game result can be verified independently using the algorithmic formula that we use to generate the result. We have created an easy way for you toexecute this code directly from your browser. It runs the exact same code which is shown below, without the hassle of having to set up Node.js on your home computer.

Just pass in the three parts of the seed mentioned above (the EOS Hash, the server seed and the nonce) along with the "selections" JSON and your user ID. These elements are all best retrieved from the Provably Fair popup dialog found on the PvP Duel page, as you can easily copy and paste each of them.

const crypto =require('crypto');// --- BEGIN: Fill these values// Hash (ID) of the mined EOS block in the future (assigned at the start of the round)const clientSeed ='0f2dcb93531d97031767d8b3d5e1d3efac5d7f75820f1027d6501c8a1ee0539d';// Numeric ID of the specific round (used as the nonce)const roundId =10000;// Selection each user made and when it was made (as timestamp)const selections ={"1":{"userId":5,"selection":1,"selectedAt":1656499361766},"2":{"userId":23,"selection":2,"selectedAt":1656499447803}};// Server seed created when new round is createdconst serverSeed ='15f9347890e5a9aecc8341f61be3f16b9f773c1e18261bc0de7952b7be59df4c';// Your user IDconst yourUserId =5;// --- END: Fill these values// With example values ^ it will output `Roll value: 0 --- Winning selection: 1 --- You won`// Turn this on if you want to see all the messagesconst verboseMode =false;// Get all selections by their selected at dateconst sortedSelections =sortedSelectionsAsArray(selections);log(`Sorted selections: ${JSON.stringify(sortedSelections)}`);const selectionsForRoll = sortedSelections.map(ss=> ss.selection);log(`Selections for roll: ${selectionsForRoll}`);// Get seedconst game =undefined;const seed =getCombinedSeed(game, serverSeed, clientSeed, roundId);// Get random roll value using provided informationconst max = selectionsForRoll.length;const rollValue =getRandomInt({ max, seed }); console.log(`Roll value: ${rollValue}`);// Find out which selection wonconst winningSelection = selectionsForRoll[rollValue];if(verboseMode){ console.log(`Selecting element at index "${rollValue}" from zero-indexed array "[${selectionsForRoll}]"`); console.table(selectionsForRoll);} console.log(`Winning selection: ${winningSelection}`);// Get a winner of the selectionconst winner = selections[winningSelection].userId;log(`Winner: ${winner}`); console.log(winner === yourUserId ?'You won':'You lost');/** * Below this line are algorithmic functions used for calculating a roll value * ============================================================================= */functionlog(message){if(verboseMode){ console.log(message);}}functionsortedSelectionsAsArray(selections){return Object.values(selections).sort((a, b)=> a.selectedAt > b.selectedAt ?1:-1);}functiongetRandomInt({ max, seed }){// Get hash from seedlog(`Seed value: ${seed}`);const hash = crypto.createHmac('sha256', seed).digest('hex');// Get value from hashconst subHash = hash.slice(0,13);const valueFromHash = Number.parseInt(subHash,16);// Get dynamic result for this rollconst e = Math.pow(2,52);const result = valueFromHash / e;return Math.floor(result * max);}functiongetCombinedSeed(game, serverSeed, clientSeed, nonce){// Add main parametersconst seedParameters =[serverSeed, clientSeed, nonce];// Add game parameter if neededif(game){ seedParameters.unshift(game);}// Combine parameters to get seed valuereturn seedParameters.join('-')}

Note:Our Random Number Generator algorithm was updated on 19th Oct 2022.
For all games playedbefore PvP Bet ID #201,649,313, please usethis codefor independent verification instead.

If you have any further questions about our provably fair system, please do not hesitate to contact our support team for more help and information.

Did this answer your question?