SpinlySpinly
Contrôles

🔒 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. 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. 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. 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. 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.