Comment le provably fair fonctionne dans Roulette
Voici comment jouer à la Roulette sur Cloudbet, et comment vérifier que chaque tour est provably fair.
Comment jouer à la Roulette
La Roulette est un jeu de casino classique où vous pariez sur l'endroit où une bille en rotation s'arrêtera sur une roue numérotée. Vous placez une ou plusieurs mises sur la table de nombres, puis la roue tourne et la bille est lancée. Une fois qu'elle se stabilise dans une case numérotée, c'est le numéro gagnant — toutes les mises qui le couvrent sont payées, et le reste est perdant.
Placer des mises
Vous pouvez parier sur le résultat de plusieurs façons différentes, et vous êtes libre de combiner plusieurs mises dans la même manche. Les mises intérieures (sur des numéros précis) rapportent plus mais sont plus difficiles à atteindre ; les mises extérieures (sur des groupes plus larges) rapportent moins mais sortent plus souvent :
- Plein / Numéro simple (35:1) : pariez sur un numéro exact (0–36, ou 00 à la Roulette américaine).
- Cheval (17:1) : deux numéros adjacents.
- Transversale (11:1) : trois numéros sur une ligne.
- Carré (8:1) : quatre numéros se rejoignant à un coin.
- Les Quatre Premiers / Ligne du haut (8:1 européenne / 6:1 américaine) : couvre 0 (et 00 à l'américaine), 1, 2, 3.
- Sixain (5:1) : deux rangées adjacentes, six numéros.
- Colonne (2:1) : l'une des trois colonnes verticales.
- Douzaine (2:1) : 1–12, 13–24, ou 25–36.
- Rouge/Noir, Pair/Impair, Manque/Passe (1:1 chacun).
Roulette européenne vs. américaine
Cloudbet propose les deux versions. La Roulette européenne a un seul zéro (37 résultats possibles, 97,30 % de RTP) ; la Roulette américaine ajoute une seconde case « 00 » (38 résultats possibles, 97 % de RTP), ce qui augmente légèrement l'avantage de la maison. La version à laquelle vous jouez doit être clairement indiquée avant que vous ne placiez une mise. Les deux incluent un mode Autoplay pour des tours continus avec des valeurs de jetons et un nombre de tours prédéfinis.
Une fois vos mises placées et la manche résolue, toutes les mises gagnantes sont payées automatiquement selon leurs cotes, et la table se réinitialise pour la manche suivante.
Cette page explique comment la Roulette transforme une séquence de nombres aléatoires provably fair en un numéro gagnant. Pour savoir comment cette séquence aléatoire est générée en premier lieu — source du serveur, source du client, nonce, hachage, SHAKE256 — consultez l'explication provably fair de Cloudbet.
Transformer des nombres aléatoires en résultat de Roulette
Pour la Roulette, le système provably fair doit prouver que le numéro gagnant est choisi par un hasard vérifiable, et non déterminé après coup.
Le processus est simple : à la Roulette européenne, un nombre entier entre 0 et 36 est échantillonné à partir de la séquence de nombres aléatoires — c'est le numéro gagnant. À la Roulette américaine, le nombre échantillonné peut aller de 0 à 37, « 37 » étant associé au double zéro, « 00 » ; les résultats de 0 à 36 sont pris tels quels.
Comment le numéro gagnant est sélectionné
Les octets aléatoires générés par SHAKE256 (voir notre page provably fair) sont divisés en entiers non signés de 4 octets, allant de 0 à 2³²−1. Le numéro gagnant de la Roulette est choisi parmi 37 résultats possibles (européenne) ou 38 (américaine) — donc dans les étapes ci-dessous, P vaut 37 ou 38.
Pour choisir équitablement un numéro gagnant parmi ces P résultats, nous appliquons l'échantillonnage par rejet (voir Comment fonctionne le provably fair), puis nous prenons le nombre résultant modulo P — le reste devient le numéro gagnant (pour la Roulette américaine, « 37 » est affiché comme « 00 »).

Une fois généré, le numéro gagnant est enregistré et caché côté serveur — il ne peut pas être modifié ou altéré sans être détecté après le début de la manche. Une fois votre mise placée, elle est comparée à ce numéro prédéterminé pour clôturer la manche.
Vérifiez vos propres résultats de Roulette
Nous avons écrit un petit programme Node.js correspondant exactement à l'implémentation de la Roulette chez Cloudbet (européenne et américaine). Entrez votre Source du serveur, votre Source du client et votre Nonce pour reproduire votre résultat. (Rappel : pour révéler la Source du serveur d'une manche sur Cloudbet, vous devez avoir déjà renouvelé la paire de sources.)
Dépendances :
npm install js-sha3
Le code :
// If you are running this yourself, then you can input your own data here
// You can then compare:
// 1) Cloudbet's provided Commitment to the Commitment outputted here. This proves that the Server Seed was not altered during gameplay.
// 2) Cloudbet's provided game outcome to the game outcome outputted here. This proves that your game's outcome was determined solely by the pre-game seeds and was not altered afterwards.
const Version = Object.freeze({ AMERICAN: "american", EUROPEAN: "european" }); // Here the possible versions are listed
let myServerSeed = 'your_server_seed'; // ✍️YOUR_INPUT✍️: Enter your (unhashed) Server Seed here
let myClientSeed = 'your_client_seed'; // ✍️YOUR_INPUT✍️: Enter your Client Seed here
let myNonce = 1; // ✍️YOUR_INPUT✍️: Enter your Nonce here
let myRouletteVersion = Version.AMERICAN; // ✍️YOUR_INPUT✍️: Enter your roulette version (either Version.AMERICAN or Version.EUROPEAN)
const usingCustomData = false; // Change this to true if you are using your own data
// Load libraries
const crypto = require('crypto');
const { sha3_256, shake256 } = require('js-sha3');
// Step 1: Generate a Server Seed and Commitment
// And generate a Client Seed - either by player input or by the player's browser
function generateServerSeed() {
let seed = crypto.randomBytes(32).toString('hex');
if (usingCustomData) { seed = myServerSeed; }
const commitment = sha3_256(seed);
return { 'serverSeed': seed, 'commitment': commitment };
}
function getClientSeed() {
let seed = crypto.randomBytes(32).toString('hex');
if (usingCustomData) { seed = myClientSeed; }
return seed;
}
// Step 2: Create a Round Signature with SHA3 using a Server Seed, Client Seed and Nonce
function createRoundSignature(serverSeed, clientSeed, nonce) {
return sha3_256(`${serverSeed}:${clientSeed}:${nonce}`);
}
// Step 3: Create a SHAKE256 stream generator from a Round Signature.
// To simplify this example program, this function doesn't create a stream, but instead a sequence of custom length.
function* createRandomNumberSequence(numbersToGenerate, roundSignature) {
const numOfBytes = 4 * numbersToGenerate; // 4 bytes (32 bits) per random number we generate
const byteStream = shake256.create(8 * numOfBytes); // shake takes bits as input
byteStream.update(roundSignature); // Use the Round Signature to seed the generator
const buf = Buffer.from(byteStream.digest()); // The Buffer class lets us package every 4 bytes into one 32-bit integer
for (let i = 0; i < numbersToGenerate; i++) {
yield buf.readUInt32BE(i * 4); // Read buf in 4-byte steps
}
throw new Error("No more numbers in the random number sequence! Fix: make 'numbersToGenerate' larger.");
}
// Step 4: Draw from the random number sequence to calculate the game result
function getGameResult(rouletteVersion, rng) {
let numOfOutcomes = 0;
if (rouletteVersion === Version.EUROPEAN) {
numOfOutcomes = 37;
} else if (rouletteVersion === Version.AMERICAN) {
numOfOutcomes = 38;
}
let result = String(sample(numOfOutcomes, rng))
// Convert the result '37' to '00'
if (result === '37') {
result = '00';
}
return result;
}
// Sample a number from P number of outcomes using Rejection Sampling
function sample(P, rng) {
const maxAcceptable = Math.floor(0x100000000 / P) * P;
// Rejection sampling
let rand;
do {
rand = rng.next().value;
} while (rand >= maxAcceptable);
// Modulo operation
const sampled_number = rand % P;
return sampled_number;
}
// Example usage
(function main() {
let nonce = 1;
let rouletteVersion = Version.AMERICAN;
if (usingCustomData) { nonce = myNonce; rouletteVersion = myRouletteVersion; }
const { serverSeed, commitment } = generateServerSeed();
const clientSeed = getClientSeed();
const roundSignature = createRoundSignature(serverSeed, clientSeed, nonce);
const numbersToGenerate = 1 * 2; // We need 1 random number, but there is an improbable case we'll need two
const rng = createRandomNumberSequence(numbersToGenerate, roundSignature);
const value = getGameResult(rouletteVersion, rng);
console.log('📝 Commitment (shown before the game):', commitment);
console.log('🔒 Server Seed (revealed after the game):', serverSeed);
console.log('🎲 Client Seed:', clientSeed);
console.log('🔢 Nonce:', nonce);
console.log(`🎯 Winning Number (in the ${rouletteVersion} version):`, value);
})();

