🔒 Provably Fair
Chaque résultat sur Spinly est vérifiable mathématiquement. Ni le serveur ni le joueur ne peut tricher.
Comment ça fonctionne ?
- 1
Server seed (secret)
Avant chaque partie, notre serveur génère une graine aléatoire secrète (server seed). Il t'en envoie le hachage SHA-256 — la graine reste cachée jusqu'à la fin du bet.
- 2
Client seed (toi)
Tu fournis ta propre graine aléatoire (client seed). Le résultat dépend des deux graines. Même nous ne pouvons pas prédire le résultat sans ta graine.
- 3
Nonce
Un compteur incrémental qui garantit que chaque bet produit un résultat différent, même avec les mêmes graines.
- 4
Résultat déterministe
Le résultat est calculé par HMAC-SHA256(serverSeed, clientSeed:nonce). Le hachage est découpé en bytes pour produire un flottant dans [0, 1).
Algorithme
import * as crypto from "crypto";
// Génère un float dans [0, 1) à partir des seeds + nonce
function seededFloat(serverSeed: string, clientSeed: string, nonce: number): number {
const hmac = crypto.createHmac("sha256", serverSeed);
hmac.update(`${clientSeed}:${nonce}`);
const hash = hmac.digest();
// Prends 4 bytes → entier 32 bits → divise par 2^32
const int32 = hash.readUInt32BE(0);
return int32 / 0x100000000;
}
// Dé classique (1–6)
function rollDie(serverSeed: string, clientSeed: string, nonce: number): number {
return Math.floor(seededFloat(serverSeed, clientSeed, nonce) * 6) + 1;
}
// Multi-dés (1–4 dés, cible ≥ N faces)
function rollMultiDice(
serverSeed: string, clientSeed: string, nonce: number,
diceCount: number, diceTarget: number
) {
const faces = Array.from({ length: diceCount }, (_, i) =>
Math.floor(seededFloat(serverSeed, clientSeed, nonce * 100 + i) * 6) + 1
);
const won = faces.every((f) => f >= diceTarget);
const winProb = Math.pow((7 - diceTarget) / 6, diceCount);
const multiplier = (1 / winProb) * (1 - 0.025); // RTP 97.5%
return { faces, won, multiplier };
}Vérifier un résultat
Après chaque bet, tu reçois le serverSeed, serverSeedHash, clientSeed et nonce.
Tu peux vérifier en ligne de commande :
# Vérifie que le serverSeedHash correspond au serverSeed révélé
echo -n "SERVER_SEED" | sha256sum
# Recalcule le résultat
node -e "
const crypto = require('crypto');
const h = crypto.createHmac('sha256', 'SERVER_SEED');
h.update('CLIENT_SEED:NONCE');
const buf = h.digest();
const v = buf.readUInt32BE(0) / 0x100000000;
console.log('Float:', v);
// Pour un dé: face = Math.floor(v * 6) + 1
"Avantage de la maison
2.5%
House edge
97.5%
RTP théorique
Chaque multiplicateur est calculé comme (1 / probabilité) × 0.975. Sur le long terme, pour 100 jetons misés, le joueur récupère en moyenne 97.5 jetons.