This repository contains the provably fair algorithms used in BloxCash, a Robux-based gaming platform.
Our mission is to ensure transparency and fairness. Players can independently verify every outcome using cryptographic proofs, guaranteeing that no game results can be tampered with.
Every outcome is determined by hashing three values with SHA-256 HMAC:
- Server Seed – Generated and hashed by BloxCash. The hashed seed is shown before a game starts. Once a new seed is created, the old unhashed seed is revealed for verification.
- Client Seed – Generated by your browser (or set manually).
- Nonce – A counter that increases with each bet/round.
The combination of these ensures that results are provably fair: players can calculate outcomes themselves after a round ends.
Each case opening generates a roll between 1 and 100,000, which maps to item probabilities.
const crypto = require('crypto');
const CHARSROLL = 15;
const MAXROLL = 100000;
const combine = (serverSeed, clientSeed, nonce) =>
crypto.createHmac('sha256', serverSeed)
.update(clientSeed + ':' + nonce)
.digest('hex');
const getResult = hashedValue => {
const partHash = hashedValue.slice(0, CHARSROLL);
const roll = parseInt(partHash, 16) % MAXROLL;
return roll + 1;
};
// Example usage
console.log(getResult(combine(serverSeed, clientSeed, nonce)));Roulette generates a result between 0–14 using the SHA-256 hash of the server seed and client seed.
const crypto = require('crypto');
const clientSeed = "00000000000000000003e5a54c2898a18d262eb5860e696441f8a4ebbff03697";
const getResult = serverSeed => {
const hmac = crypto.createHmac('sha256', serverSeed);
hmac.update(clientSeed);
const sha = hmac.digest('hex');
return parseInt(sha.substr(0, 8), 16) % 15;
};
// Example usage
console.log(getResult(serverSeed));Jackpot selects a winning ticket proportional to the pot size.
const crypto = require('crypto');
const combine = (serverSeed, clientSeed) =>
crypto.createHmac('sha256', serverSeed)
.update(clientSeed)
.digest('hex');
const getFloatResult = hashedValue => {
let decimalNumber = parseInt(hashedValue, 16);
let maxDecimalValue = parseInt('f'.repeat(64), 16);
return Number((decimalNumber / (maxDecimalValue - 1)).toFixed(7));
};
// Example usage
const percentageWinner = getFloatResult(combine(serverSeed, clientSeed));
const winnerTicket = Math.floor(totalTickets * percentageWinner);
console.log(winnerTicket);Coinflip determines the winning side (ice or fire) from a hash.
const crypto = require('crypto');
const combine = (serverSeed, clientSeed) =>
crypto.createHmac('sha256', serverSeed)
.update(clientSeed)
.digest('hex');
const getResult = hashedValue => {
const number = parseInt(hashedValue.charAt(1), 16);
return (number % 2 === 0) ? 'ice' : 'fire';
};
// Example usage
console.log(getResult(combine(serverSeed, clientSeed)));Mines uses cryptographic floats and the Fisher–Yates shuffle to place mines fairly.
import _ from "lodash";
// Floats generated from serverSeed, clientSeed, and nonce
const floats = _.flatten(
generateFloats(serverSeed, clientSeed, nonce, 0, mines)
).map((float, index) => float * (25 - index));
const minePositions = shuffle(
[...Array(25).keys()],
floats
).slice(0, MINES);
console.log(floats);
console.log(minePositions);This repository exists for transparency and verification purposes only. It is not intended to promote or facilitate gambling directly.