Come funziona il provably fair in Dice

Ecco come giocare a Dice su Cloudbet, e come verificare che ogni lancio sia provably fair.

Come giocare a Dice

Dice è un gioco veloce in cui scommetti se un numero generato casualmente sarà superiore o inferiore a un obiettivo che scegli tu. Scegli un numero obiettivo e decidi se scommettere che il risultato sarà Roll Over (sopra) o Roll Under (sotto) rispetto ad esso. Più il tuo obiettivo è vicino al bordo dell'intervallo, minori sono le probabilità di vincere — ma maggiore è la vincita se ci riesci. Una volta piazzata la scommessa, il risultato viene rivelato istantaneamente.

Cloudbet Originals Dice

Il Dice degli Originals di Cloudbet utilizza un intervallo obiettivo da 0,00 a 100,00, un RTP del 99%, un moltiplicatore massimo di x9.800 e accetta scommesse da 0,01 $ a 10.000 $. È disponibile la funzione Auto Bet per automatizzare più round.

Questa pagina spiega come Dice trasforma un numero casuale verificato nel tuo lancio. Per sapere come viene generata e protetta la casualità di base — server seed, client seed, nonce, hashing — consulta la nostra pagina sul provably fair. Stai giocando a Dice: Golden Ticket? Il suo valore del dado viene campionato allo stesso modo descritto qui, con l'aggiunta di un valore e un moltiplicatore Golden Ticket.

Trasformare i numeri casuali in un risultato di Dice

Il risultato di Dice deve essere legato in modo dimostrabile alla stessa casualità verificabile di ogni altro Cloudbet Original. Una volta generata la sequenza di numeri casuali di un round (tramite SHAKE256 — vedi il processo del provably fair per i dettagli), Dice la utilizza così:

Viene campionato dalla sequenza un numero intero compreso tra 0 e 10.000 (inclusi), poi diviso per 100 — ottenendo un valore tra 0 e 100 con due cifre decimali. Questo è il tuo risultato di Dice.

Come funziona il campionamento

Dice ha 10.001 esiti possibili (da 0,00 a 100,00 in incrementi di 0,01), quindi per questo gioco P = 10.001.

Per scegliere in modo equo tra questi 10.001 esiti, Dice utilizza lo stesso metodo di rejection sampling descritto nella nostra guida al provably fair — viene generato un numero casuale a 32 bit, poi rifiutato e ricampionato se distorcerebbe il risultato, finché non se ne trova uno equo. Quel numero viene poi sottoposto a un'operazione modulo rispetto a 10.001 per ottenere un valore da 0 a 10.000, che viene diviso per 100 per ottenere il risultato finale.

Il gioco

Il risultato viene generato e bloccato sul server prima che tu piazzi la tua scommessa — non può essere cambiato o alterato senza essere rilevato una volta iniziato il round. Dopo aver scommesso, la soglia da te scelta viene confrontata con questo numero pre-generato per determinare se hai previsto correttamente.

Codice per la verifica indipendente del provably fair di Dice

Questo programma è fedele all'implementazione di Dice su Cloudbet. Inserisci il tuo Server Seed, Client Seed e Nonce per verificare i tuoi risultati. Nota: per rivelare il Server Seed di una partita su Cloudbet, devi prima ruotare verso un nuovo Server Seed.

Dipendenze:

npm install js-sha3

Il codice:

// 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.
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
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 getDiceResult(rng) {
  const diceMinValue = 0;
  const diceMaxValue = 10000;
  let number = sampleFromRange(diceMinValue, diceMaxValue, rng);
  number = number / 100; // So that the dice's value ranges from 0 to 100
  return number;
}
// Sample a number between 'min' to 'max' (inclusive) using Rejection Sampling
function sampleFromRange(min, max, rng) {
  const P = max - min + 1
  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 + min;
}

// Example usage
(function main() {
  let nonce = 1;
  if (usingCustomData) { nonce = myNonce; }

  const { serverSeed, commitment } = generateServerSeed();
  const clientSeed = getClientSeed();

  const roundSignature = createRoundSignature(serverSeed, clientSeed, nonce);
  const numbersToGenerate = 1 * 2; // We need 1 random number, however due to rejection sampling we may need more
  const rng = createRandomNumberSequence(numbersToGenerate, roundSignature);

  const diceValue = getDiceResult(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('🔁 Round Signature (can be verified after the game):', roundSignature);
  console.log('🎯 Dice landed on:', diceValue);
})();

Altre spiegazioni sul provably fair per i vari giochi:

  1. Provably fair Mines
  2. Provably fair Pump
  3. Provably fair Plinko
  4. Provably fair Dice: Golden Ticket
  5. Provably fair Limbo
  6. Provably fair Roulette
  7. Provably fair Keno