O que é comprovadamente justo?
Comprovadamente justo significa que o resultado de cada jogo é gerado por um valor aleatório que os jogadores podem verificar independentemente. Isso garante transparência e justiça, assegurando que nem o jogador nem o cassino possam manipular o resultado.
Como funciona?
VRF (função aleatória verificável) para gerar um valor verdadeiramente aleatório, usamos um VRF. Esta função recebe várias entradas, incluindo o ID do usuário, nome do jogo, nonce do jogo e a chave secreta do cassino. Ela realiza cálculos criptográficos e produz tanto um valor aleatório quanto uma prova. Esta prova permite que qualquer pessoa verifique que o valor foi gerado de forma justa e não foi adulterado. Seguimos a implementação VRF RFC6979 usando o conjunto de cifras SECP256K1_SHA256_TAI para aleatoriedade segura e verificável.
Verificando a justiça
Os jogadores podem verificar independentemente o valor aleatório usando o seguinte código:
const { verify } = require('@roamin/ecvrf') const toHex = require('string-hex') const publicKey = '02bf185c865baa18e7e1c8e5ee3f313c2fad62208b3f6ff2abdfb9ba858f12bd14'; const request = 'cm7bzfgwl0000yl0whlt8es3f-MINES-244'; const random = '63b63a1c1411b35e0aac628fa7013ee65fd52d2ea9b03015a614318422db4d38'; const proof = '03087f523c2fe9de7ec4f08e6ed2c74d414724d3743f9e4f2fba4df695dd87b9f8b25566213101887fc21f0124c55e24de43a6c6b47e65a4c0dec22168279d3e30ba44ccbbc32c7623905e747b7921c00f' try { const result = verify(publicKey, proof, toHex(request)) console.log(result === random ? 'Is Verified' : 'Not Verified') } catch (error) { console.log(error) }
Calculando o resultado do jogo
Uma vez verificado o valor aleatório, ele é convertido em um número:
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)); }
Este número convertido é então usado para gerar o resultado final do jogo com base na lógica específica do jogo.
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 })); } Board: [ [ -1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, -1 ], [ 0, 0, 0, 0, 0 ] ] Multipliers: 1 : 1.06 2 : 1.16 3 : 1.27 4 : 1.4 5 : 1.54 6 : 1.71 7 : 1.92 8 : 2.16 9 : 2.44 10 : 2.79 11 : 3.23 12 : 3.76 13 : 4.45 14 : 5.34 15 : 6.53 16 : 8.16 17 : 10.49 18 : 13.99 19 : 19.59 20 : 29.39 21 : 48.99 22 : 97.99 23 : 293.99

