Among all the games that Betstrike offers we need to make a distinction between Original games and externally provided games.
Original games are those that can be found under the originals page on Betstrike and are internally developed by our team.
Externally provided games comes from game providers which offers their games to iGaming platforms such as ours. External providers have gone trough a verified lab that tests their games for RNG and fairness. Each game provider might have its own way to verify the plays on their system and therefore any problem should be reported to them.
Original games as mentioned earlier are internally developed games which can be categorized in two types, each one which its own Provably Fairness scheme.
Single-player games
Verifiable Random Functions (VRF)
A verifiable random function (VRF) is a cryptographic function that takes a series of inputs, computes them, and produces a pseudorandom output and proof of authenticity that can be verified by anyone. (chain.link article)
Games such as Dice, Plinko, Mines, Towers and Keno outcomes are generated using Verifiable Random Functions. VRFs are random functions that allow verification instantly.
All games can be validated using our public key.
VRF Public Key:
04ca6b9da769fa6836b9fb89519f19c3e9c5cfd56fd1bc5f1b4bb0f8915fd9360e9ff8b449da64f0b5ef0549b7c782a92a631003889fbca36de3fe82c2c6f714c1
This value will always be the same; you should never change it when performing outcome verification.
By using VRFs, our fairness system allows players to verify their games without having to rate their server seed. Instant proof is verifiable as soon as the bet is placed.
Verification Steps
As mentioned previously these steps are only valid for verifying single-player original games.
You can find verification details for each bet by clicking your user avatar in the top right header of the site then click Transactions > Casino Bets, while hovering a line of a bet that supports our verification system, a Verify button appears at the end of the row.
A modal will open with the details to verify the game.
Fairness Details
Prefix: it's a fixed per-game prefix
User ID: this is your user ID, it will always be the same within your account
Client Seed: this is a string that you can decide, client seed options are available above each game by clicking the icon with a shield.
Nonce: it's the bet count of your account, every time you place a bet it increases by 1.
A string joining the parameters with : symbol in between them like the one below is created and encoded in hexadecimal.
{prefix}:{userID}:{nonce}:{clientSeed}
Note: that brackets are used to mark a variable and should not be included in the final string.
The concept behind VRFs is that you know the final hexadecimal-encoded string that will be used since it's predictable and partially controllable by you (client seed).
We now need to introduce the concept of the private key which is fixed and Cryptographically tied to the public key, the private key is unknown to you and is stored on our servers.
Let's define some functions:
prove(private_key, payload) -> proof
proofToHash(proof) -> hash
verify(public_key, proof, payload) -> hash
The prove and proofToHash functions runs on our servers when you place a bet, the payload is known or at least easily predictable by the end user.
The prove function returns a proof string that you can only access after a bet is in the COMPLETED state. The proofToHash function is then called with the proof, which is the result of the previous call to the prove function, the result of this function is an hash which is the final seed used to generate the outcome of your game.
This seed allows a number generator to always generate the same number given the same input (pseudo-random).
Now it's time to finally verify the bet; you need to compute the payload string (remember to encode it to hexadecimal), and supply the public_key, the proof string and the payload string to the verify function, the result of the function will be the same hash that we provide you, which is also the seed used for RNG.
Compare the hash that we provide with the one you got from the verify function and if they match the bet is verified. To validate game outcome, follow game-specific instructions.
For the non-technical people when we mention a public key there is always a private key as they form a key pair, basic cryptography concepts might be needed to understand this topic fully.
Game-specific instructions
Make sure to read previous points as you need the seed used to generate random numbers to continue on this section. To generate numbers with a seed take a look at change library on NPM.
Dice
Parameters needed:
Direction (UNDER / OVER)
Target (A float number between 0 and 100, allowing 2 decimal places)
const chance = Chance(seed);
const rollResult = chance.floating({ min: 0, max: 100 }
Note: rollResult only accounts for the first 2 decimals.
Win / loss depends on direction:
if OVER and target > rollResult = WIN
if UNDER and target < rollResult = LOSS
All other cases result in a LOSS
Keno
An array contains the available selectable numbers sequentially ascending, n amount of integer numbers are then randomly generated where n is the amount of selected numbers by the user (max 10).
Given that different configurations are available, please check this link to see latest available configurations. If you need to access a configuration that is not available anymore reach out to support.
Note: the seed sets the starting point of generation, subsequent call will generate different numbers (still predictable in order)
Mines
Given b being the number of desired bombs and t the number of total tiles, s, the amount of safe tiles, is defined as t - b.
A list of zeros and ones is created, where 1 indicates a bomb and 0 a safe tile. The list is generated with safe tiles upfront and b tiles at the end. A shuffle function starting from the seed is then used to shuffle the list of tiles, creating the board of that bet.
const chance = Chance(seed);
const shuffledTiles = chance.shuffle(tiles);
Towers
A true/false matrix is created where a value of true means a trap and a value of false means a safe cell.
The amount of rows and columns might vary depending on the used configuration, you can check latest available configurations settings here. If you need informations about a bet with a configuration that is not publicly available anymore, please reach out to support.
A matrix in programming is seen as a list containing other lists where the elements of the outer list creates the rows and the inner lists are the cells of each row.
Similarly to Mines each row is filled with the amount of safe and trap cells based on the configuration and the list is then shuffled using the following string:
{seed}:{i}
where {seed} is the actual seed you got from the previous steps and i is the row index of the towers (starts at zero).
The row creation and shuffle process is done up until the matrix is fully created and shuffled.
Plinko
Given the seed, a floating number between 0 and 1 is generated.
Based on configuration and number of rows, each box has a probability assigned with a payout multiplier. Check available configuration details here, if you need informations about a bet using a configuration that is not publicly available anymore reach out to support.
The box index where the ball falls is determined using the method below:
private selectIndexByProbability(probabilities: number[], rng: number): number {
let cumulativeSum = 0;
for (let i = 0; i < probabilities.length; i++) {
cumulativeSum += probabilities[i];
if (rng <= cumulativeSum) {
return i;
}
}
return probabilities.length - 1;
}