Что такое проверяемо честная игра?
Проверяемо честная означает, что результат каждой игры генерируется случайным значением, которое игроки могут независимо проверить. Это гарантирует прозрачность и честность, обеспечивая, что ни игрок, ни казино не могут манипулировать результатом.
Как это работает?
VRF (проверяемая случайная функция) для генерации действительно случайного значения, мы используем VRF. Эта функция принимает несколько входных данных, включая ID пользователя, имя игры, номер игры и секретный ключ казино. Она выполняет криптографические вычисления и выдает как случайное значение, так и доказательство. Это доказательство позволяет любому проверить, что значение было сгенерировано честно и не было подделано. Мы следуем реализации RFC6979 VRF, используя набор шифров SECP256K1_SHA256_TAI для безопасной и проверяемой случайности.
Проверка честности
Игроки могут независимо проверить случайное значение, используя следующий код:
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) }
Расчет результата игры
После проверки случайное значение преобразуется в число:
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)); }
Это преобразованное число затем используется для генерации окончательного результата игры на основе игровой логики.
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 })); }

