Công bằng minh bạch là gì?
Công bằng minh bạch có nghĩa là kết quả của mỗi game được tạo bởi một giá trị ngẫu nhiên mà người chơi có thể xác minh độc lập. Điều này đảm bảo tính minh bạch và công bằng, đảm bảo rằng cả người chơi và casino đều không thể thao túng kết quả.
Nó hoạt động như thế nào?
VRF (verifiable random function) để tạo giá trị ngẫu nhiên thực sự, chúng tôi sử dụng VRF. Hàm này nhận nhiều đầu vào, bao gồm ID người dùng, tên game, nonce game và khóa bí mật của casino. Nó thực hiện các tính toán mật mã và xuất ra cả giá trị ngẫu nhiên và chứng minh. Chứng minh này cho phép bất kỳ ai xác minh rằng giá trị được tạo công bằng và không bị giả mạo. Chúng tôi tuân theo triển khai VRF RFC6979 sử dụng bộ mã hóa SECP256K1_SHA256_TAI để đảm bảo tính ngẫu nhiên an toàn và có thể xác minh.
Xác minh tính công bằng
Người chơi có thể xác minh độc lập giá trị ngẫu nhiên bằng mã sau:
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) }
Tính toán kết quả game
Sau khi xác minh, giá trị ngẫu nhiên được chuyển đổi thành số:
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)); }
Số đã chuyển đổi này sau đó được sử dụng để tạo kết quả game cuối cùng dựa trên logic cụ thể của game.
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 })); }

