Was ist nachweislich fair?
Nachweislich fair bedeutet, dass das Ergebnis jedes Spiels durch einen zufälligen Wert generiert wird, den Spieler unabhängig überprüfen können. Dies garantiert Transparenz und Fairness und stellt sicher, dass weder der Spieler noch das Casino das Ergebnis manipulieren kann.
Wie funktioniert es?
VRF (verifizierbare Zufallsfunktion) Um einen wirklich zufälligen Wert zu generieren, verwenden wir VRF. Diese Funktion nimmt mehrere Eingaben, einschließlich Benutzer-ID, Spielname, Spiel-Nonce und den geheimen Schlüssel des Casinos. Sie führt kryptografische Berechnungen durch und gibt sowohl einen zufälligen Wert als auch einen Beweis aus. Dieser Beweis ermöglicht es jedem zu überprüfen, dass der Wert fair generiert wurde und nicht manipuliert wurde. Wir folgen der RFC6979 VRF-Implementierung mit der SECP256K1_SHA256_TAI-Cipher-Suite für sichere und verifizierbare Zufälligkeit.
Fairness verifizieren
Spieler können den zufälligen Wert unabhängig mit folgendem Code überprüfen:
const { verify } = require('@roamin/ecvrf') const toHex = require('string-hex') const publicKey = '03c41192ba26b7efafa9c69c941f759690d4fd46761c8424edbad1d5fc2c5c0947' const request = 'e1bc2c47-9b42-4409-8a21-d4c4f46455be|rollbit:mines|25|1234costam' const random = 'e2983665217b5aaebf11c886ef31e001c9615362b0aa6c3e49de9057f8979e1d' const proof = '03008cd333b153dddcffc64abf357222d31cd6e6f85ddbbe9227a60d2d0edcf9e6ab0f088c1f4402e6b4fa0ef430612d3ca86a686fc857ff412a8fe1553c821f47fcc21f4b2ca1d4c3b09b59a7e4fe1b8a' try { const result = verify(publicKey, proof, toHex(request)) console.log(result === random ? 'Is Verified' : 'Not Verified') } catch (error) { console.log(error) }
Spielergebnis berechnen
Sobald der zufällige Wert verifiziert ist, wird er in eine Zahl umgewandelt:
import * as crypto from 'crypto'; function bytesToUniformFloat(xs) { const hash = crypto.createHash('blake2b512').update(xs).digest(); const value = hash.readBigUInt64LE(0); return Number(value) / Number(BigInt(2 ** 64 - 1)); }
Diese umgewandelte Zahl wird dann verwendet, um das endgültige Spielergebnis basierend auf spielspezifischer Logik zu generieren.
function calcMinesIxs({ size, mines, randomValue }) { const remainingIxs = Array.from({ length: size }, (_, i) => i); const mineIxs = []; for (let i = 0; i < mines; i++) { const seedI = Buffer.from(randomValue + '-' + i, 'ascii'); const ixI = Math.floor(bytesToUniformFloat(seedI) * remainingIxs.length); mineIxs.push(remainingIxs[ixI]); remainingIxs.splice(ixI, 1); } return mineIxs; } const calcMinesWin = ({ size, mines, reveals, bet }) => { let mult = 1.0; for (let i = 0; i < reveals; i++) { const lossProbability = mines / (size - i); mult *= 1.0 / (1.0 - lossProbability); } return Math.floor(100.0 * bet * mult * 0.98) / 100.0; }; function generateBoard({ size, mines, randomValue }) { const mineIxs = calcMinesIxs({ size, mines, randomValue }); const sizeSqrt = Math.sqrt(size); const board = Array.from({ length: sizeSqrt }).map(() => Array(sizeSqrt).fill(0)); for (const index of mineIxs) { const row = Math.floor(index / sizeSqrt); const col = index % sizeSqrt; if (row < sizeSqrt && col < sizeSqrt) { board[row][col] = -1; } } console.log('Board:', board); return board; } generateBoard({ size: 25, mines: 2, randomValue: 'be87e890f696aad0aad28bef78a3f2322c7687a76ff6f86b6dadb4f2aa00eeb9' }); console.log('Multipliers:'); for (let i = 1; i < 24; i++) { console.log(i, ': ', calcMinesWin({ size: 25, mines: 2, reveals: i, bet: 1 })); }

