Dowodliwa uczciwość
Wynik każdej gry jest przesądzony jeszcze przed zakładem i każdy może go przeliczyć — nie musisz wierzyć nam na słowo.
Jak to działa
W kasynie na żywo widzisz, jak odwraca się karta, jak padają kości, jak kręci się ruletka. W grze online dzieje się to wewnątrz programu — i to program trzeba sprawdzić.
Przed zakładem serwer publikuje hash SHA-256 swojego tajnego ziarna. Podmiana ziarna po fakcie jest niemożliwa: hash by ją zdradził. Po zmianie pary ziaren stare ziarno serwera zostaje ujawnione — i każdy rzut wykonany tą parą przeliczysz wzorem poniżej.
Prowizja kasyna to 1%. Wypłata liczy się jako zakład × 99 ÷ szansa w procentach, czyli do gracza wraca 99% wartości oczekiwanej. To jedyna rzecz, która odróżnia tę grę od rzutu uczciwą monetą; nic poza tym nie jest potrącane.
Ziarna
Para ziaren to jedno Twoje i jedno nasze. Ziarno serwera losujemy i od razu pokazujemy jego hash: samo ziarno pozostaje tajne do zmiany pary, inaczej przyszłe rzuty byłyby znane z góry. Ziarno klienta ustawiasz Ty i bez niego rzutu nie da się policzyć — wynik zależy od obu stron.
Trzeci składnik to nonce, numer zakładu w bieżącej parze. Rośnie o jeden z każdą grą, więc dwa rzuty tą samą parą nie mogą mieć tych samych danych wejściowych.
Jak powstaje liczba
Ziarno serwera, ziarno klienta i nonce zwijamy w HMAC-SHA512. Powstałe 128 znaków hex czytamy oknami po pięć: pierwszą wartość mniejszą niż 1 000 000 bierzemy modulo 10 000 — wychodzi rzut od 0 do 9999, czyli od 0.00 do 99.99.
Próg odrzucenia jest tu dla uczciwości: okno z pięciu znaków hex daje liczby do 1 048 575, a ten zakres nie dzieli się równo przez 10 000 — bez odrzucania małe wyniki wypadałyby częściej niż duże. 1 000 000 dzieli się równo, więc wszystkie 10 000 wyników są jednakowo prawdopodobne. Prawdopodobieństwo, że odpadną wszystkie 25 okien, jest rzędu 10⁻³³.
hex = HMAC_SHA512(key = serverSeed, msg = clientSeed + "-" + nonce) Czytamy hex kolejnymi oknami po 5 znaków (0-4, 5-9, …): pierwsza wartość < 1 000 000 → roll = wartość % 10000 (jeśli odrzucono wszystkie 25 okien — roll = 9999) Poniżej: wygrana przy roll < target · Powyżej: wygrana przy roll > target Wypłata = zakład × 9900 / chanceUnits (zaokrąglenie w dół) · prowizja 1%
Kod silnika
Dokładnie to, co liczy rzuty na serwerze, i dokładnie to, co przelicza je w Twojej przeglądarce. Zgodności obu stron pilnuje test.
const WINDOW = 5; // znaków hex w oknie: 20 bitów, 0..1048575
const REJECT = 1_000_000; // największa wielokrotność 10000 mieszcząca się w oknie
function roll(serverSeed, clientSeed, nonce) {
const hex = createHmac("sha512", serverSeed)
.update(`${clientSeed}-${nonce}`)
.digest("hex"); // 128 znaków
// okna po 5 znaków hex z rzędu: 0-4, 5-9, ... 120-124
for (let i = 0; i * WINDOW + WINDOW <= hex.length; i++) {
const lucky = parseInt(hex.slice(i * WINDOW, i * WINDOW + WINDOW), 16);
if (lucky < REJECT) return lucky % 10000; // 0..9999
}
// odrzucone wszystkie 25 okien (prawdopodobieństwo ~1e-33)
return 9999;
}
// wypłata: prowizja 1%, zaokrąglenie w dół
const payout = (amount, chanceUnits) => amount * 9900n / BigInt(chanceUnits);
Jak sprawdzić własną grę
W mini-aplikacji: Uczciwość w dolnym pasku albo „Sprawdź grę” w karcie dowolnego zakładu.
- Zakładka „Ziarna” — tu jest hash działającego ziarna serwera. Został zapisany przed Twoimi zakładami.
- Zmień parę ziaren. Poprzednie ziarno serwera zostanie ujawnione; Twoje ziarno klienta pozostaje Twoje.
- Zakładka „Ujawnione” — ujawnione ziarno leży obok swojego hasha. Sprawdź: SHA-256 ziarna musi zgadzać się z tym, co pokazywaliśmy przed zakładami.
- Zakładka „Sprawdź” — wklej ziarno serwera, ziarno klienta i nonce interesującego Cię zakładu. Rzut przeliczy się prosto w przeglądarce i porówna z wynikiem gry.
Obliczenia idą na Twoim urządzeniu i nie sięgają naszego serwera. Ze wzorem powyżej powtórzysz je w dowolnym języku — HMAC-SHA512 jest wszędzie.