Kontrakt: jak i dlaczego to działa
Wszystkie środki i wszystkie zasady FAIRDRUM znajdują się w jednym programie w sieci Solana — smart kontrakcie. Strona tylko wysyła mu polecenia i pokazuje odpowiedź. Poniżej: co kontrakt przechowuje, jakie polecenia rozumie, jak z liczby losowej powstaje wynik oraz co może, a czego nie może administrator.
Czym jest kontrakt i gdzie się znajduje
Smart kontrakt to program wykonywany przez węzły sieci Solana, a nie na serwerze projektu. Jego kod jest taki sam dla wszystkich, a każde działanie to publiczna transakcja. Kontrakt FAIRDRUM jest napisany w Rust z biblioteką Anchor; jego kod źródłowy jest otwarty.
Adres programu pojawi się tutaj, gdy strona zostanie podłączona do kontraktu.
Ważny wniosek: jeśli strona fairdrum.to zniknie, środki graczy zostaną w kontrakcie i będzie można je wypłacić dowolnym programem, który potrafi wysłać polecenie wypłaty z podpisem twojego portfela.
Co kontrakt przechowuje
- Skarbiec. Jedno konto w opakowanym SOL, którym dysponuje wyłącznie sam program. Leży w nim wszystko: salda graczy, bank nagród, jackpoty, rezerwa i jeszcze nieodebrany udział administratora.
- Wspólne konto gry. Zapis tego, jak podzielona jest kwota w skarbcu: bank nagród, jackpot, mini-jackpot, superjackpot, rezerwa na kwoty startowe, udział administratora, kwoty startowe jackpotów, liczniki rund w poszczególnych grach.
- Konto gracza. Tworzy je polecenie register, które strona wysyła razem z pierwszą wpłatą; jest powiązane z adresem portfela: saldo gry, czas ostatniej wpłaty, niedokończona runda, niewypłacona część jackpota.
- Konto sesji (jeśli włączono „grę bez podpisów”): tymczasowy klucz, termin i limit stawek.
Księgowanie jest zbudowane tak, że suma wszystkich sald i pul równa się kwocie w skarbcu. Test sprawdza tę równość po każdej z dziesiątek tysięcy losowych operacji.
Jakie polecenia rozumie kontrakt
| Polecenie | Kto może wywołać | Co robi |
|---|---|---|
register | gracz | Tworzy konto gracza. Strona wysyła je razem z pierwszą wpłatą. |
deposit | gracz | Wpłata na saldo gry. Zapamiętuje czas: od niego liczy się 12 godz. do wypłaty. |
withdraw | gracz | Wypłata na własny portfel. Jest odrzucana, dopóki od ostatniej wpłaty nie minęło 12 godz. |
spin_commit | gracz lub jego klucz sesji | Stawka: pobiera rundę z salda, zapamiętuje grę i obowiązujące szanse, prosi wyrocznię o liczbę losową. |
spin_settle | każdy | Rozliczenie: odczytuje liczbę wyroczni, oblicza wypłatę i zapisuje ją na saldo gracza. Wywołać może każdy — wynik od tego nie zależy. |
spin_expire | każdy | Zamyka rundę, której nie rozliczono w ciągu 20 minut. Jeśli wyrocznia nie odpowiedziała, stawka wraca do gracza w całości. Jeśli wyrocznia odpowiedziała, a runda jest przypieczętowana, wypłaca zwykłe nagrody bez losowania jackpotów. |
spin_seal | każdy | Pieczętuje rundę: zapisuje hash bloku stawki, dopóki jest dostępny (około 3,5 minuty). Jest potrzebna tylko wtedy, gdy wyrocznia odpowiada dłużej; zwykle wywołuje ją usługa dyżurna. Runda, której nie rozliczono ani nie przypieczętowano na czas, zamyka się bez wyniku. |
skip_nonce | gracz | Przesuwa numer następnego zapytania o losowość, jeśli adres zapytania okazał się zajęty. |
session_open / session_close | gracz | Pozwala tymczasowemu kluczowi stawiać w granicach terminu i limitu; klucz nie może ani wypłacać, ani wpłacać. |
donate | każdy | Wnosi SOL do rezerwy na kwoty startowe jackpotów. Polecenia odwrotnego nie ma. |
set_jackpot_starts | administrator | Ustala nowe kwoty startowe jackpota i superjackpota; zaczynają obowiązywać po 24 godz. |
rescale_pools | administrator | Przenosi część rezerwy na kwoty startowe do banku nagród gier. Tylko w tę stronę; do jackpotów przenosić nie można — uzupełniają się z rezerwy same, po wygranej. |
set_paused | administrator | Wstrzymuje lub wznawia przyjmowanie nowych stawek — na wypadek awarii wyroczni. Postawione już stawki są rozliczane, wypłaty nagród i wypłata środków działają jak zwykle. |
set_guardian / guard_pause | administrator | Administrator wyznacza strażnika — klucz usługi dyżurnej, który potrafi tylko jedno: wstrzymać przyjmowanie nowych stawek, jeśli wyrocznia przestała odpowiadać. Pauzę może zdjąć tylko administrator. |
propose_dev_authority / accept_dev_authority | administrator | Przekazanie uprawnień administratora innemu kluczowi w dwóch krokach: obecny klucz wskazuje nowy, a nowy sam to potwierdza. |
roll_epoch / checkin | każdy | Polecenia pomocnicze: aktualizują statystykę tygodniową i znacznik dnia. Nie przenoszą środków. |
claim_dev | administrator | Odbiera zgromadzony udział administratora — i tylko jego. |
initialize / fund_pools | administrator | Jednorazowe uruchomienie. initialize tworzy konta (podpisuje posiadacz uprawnienia do aktualizacji programu); fund_pools jeden raz rozpisuje wniesiony bank startowy na pule, a nadwyżkę ponad niego — do osobnej pozycji, którą administrator może odebrać poleceniem promo_pay. |
Polecenia, które przekazywałoby administratorowi bank nagród, jackpoty lub salda graczy, w kodzie nie ma.
Runda krok po kroku
- Stawka. Polecenie spin_commit pobiera rundę z twojego salda i w tej samej transakcji tworzy u wyroczni ORAO zapytanie o liczbę losową. Adres zapytania jest wyliczany z twojego portfela i numeru rundy, dlatego nie da się podstawić cudzego zapytania.
- Liczba. Kilka niezależnych węzłów ORAO podpisuje liczbę losową i zapisuje ją w sieci. Do chwili tego zapisu nie zna jej nikt: ani ty, ani projekt, ani pojedynczy węzeł.
- Rozliczenie. Polecenie spin_settle odczytuje liczbę z zapisu wyroczni, sprawdza, czy to zapytanie właśnie twojej rundy, i oblicza wypłatę. Strona wysyła je sama; jeśli strona jest zamknięta, zrobi to program dyżurny projektu albo ty przy następnej wizycie.
- Prezentacja. Karty, miny, rakieta, kamienie to sposób pokazania już obliczonej wypłaty. Kliknięcia w grze na nią nie wpływają.
Dlaczego wyniku nie da się poznać z góry ani sfałszować. Ostateczna liczba rundy to liczba wyroczni zmieszana z hashem bloku, w którym zapisano stawkę. W chwili stawki ten hash jeszcze nie istnieje, a liczba wyroczni przychodzi później i od strony trzeciej: wyniku nie może z góry obliczyć nikt — ani gracz, ani projekt, ani sama wyrocznia. Gra, kwoty startowe jackpotów i limit nagrody są zapisywane w chwili stawki, a wzór rozliczenia jest w otwartym kodzie. Spóźnione rozliczenie nigdy nie jest korzystniejsze od terminowego. Zasady można zmienić tylko przez wymianę kodu programu, a to widzą wszyscy (zob. część o administratorze).
Jak z liczby losowej powstaje wynik
Runda to od 1 do 100 stawek po 0,01 SOL (na bębnie do 1000). Liczba wyroczni jest rozwijana w niezależną wartość losową dla każdej stawki i dla każdej z nich kontrakt po kolei odpowiada na pytania:
- Superjackpot, jackpot, mini-jackpot? Szansa każdej puli równa się wkładowi stawki do niej podzielonemu przez kwotę startową puli. Pula jest losowana tylko wtedy, gdy jest w niej co najmniej 25% kwoty startowej.
- Nagroda gry? Każda gra ma własną szansę na nagrodę i własną tabelę sześciu stopni z wagami. Na przykład na bębnie nagroda wypada w 10% stawek. Tabele wszystkich gier są pokazane na ich stronach.
- „Jeszcze raz”? Z szansą 11,6% stawka jest powtarzana bezpłatnie na koszt banku nagród.
- W przeciwnym razie stawka jest bez nagrody. Dzieli się ją tak samo jak każdą inną: bank nagród, jackpoty i udział administratora.
Tabele gier są różne, a oczekiwana wypłata jest w nich taka sama (z dokładnością do setnych części procenta; przy banku nagród od 40 SOL, gdy nagrody nie dochodzą do limitu): około 77,5% stawki w zwykłych nagrodach, a razem z powtórkami „Jeszcze raz” — około 88% opłaconych stawek. Równość sprawdza kompilator: jeśli w którejś grze wartość oczekiwana okaże się wyższa niż na bębnie albo niższa o więcej niż pół procenta, program się nie zbuduje.
Gdzie kontrakt odkłada każdą stawkę
| Dokąd | Udział w opłaconej stawce | Po co |
|---|---|---|
| Bank nagród | ≈88% | zwykłe nagrody wszystkich gier |
| Jackpot, mini-jackpot, superjackpot i kwota startowa | 2% | trzy wspólne pule |
| Administrator | 10% | dochód projektu; innego nie ma |
W kodzie udziały są zapisane od każdej wykonanej stawki, łącznie z bezpłatnymi powtórkami, dlatego widnieje tam 8,84% i 1,77%: w przeliczeniu na opłacone stawki to średnio 10% i 2%.
Reguły ograniczające i po co są
- Jedna nagroda — nie więcej niż ćwierć banku nagród. Kontrakt nie może obiecać więcej, niż ma, a jedna duża wygrana nie opróżnia banku dla pozostałych. Niedopłacona kwota zostaje w banku.
- Wypłata po 12 godz. od ostatniej wpłaty. Reguła jest jednakowa dla wszystkich i zapisana jako stała: zmienić ją można tylko nową wersją programu.
- Kwoty startowe jackpotów zmieniają się z opóźnieniem 24 godz. Szanse rundy są ustalane w chwili stawki, dlatego nie da się ich zmienić „pod już postawioną stawkę”.
- 20 minut na rozliczenie. Jeśli wyrocznia nie odpowiedziała, stawka wraca do gracza w całości: dopóki nie ma liczby, nikt nie zna wyniku, więc nie da się w ten sposób uchylić od przegranej. Jeśli odpowiedziała, ale rozliczenie się spóźniło, zwykłe nagrody są wypłacane, a jackpoty nie są w tej rundzie losowane. Ochrona skarbca. Przed każdą wypłatą i po każdym rozliczeniu kontrakt sprawdza, czy w skarbcu jest nie mniej, niż jest winien graczom i pulom; w przeciwnym razie operacja zostaje odrzucona. Strażnik. Jeśli wyrocznia przestała odpowiadać, przyjmowanie nowych stawek zostaje automatycznie wstrzymane; rozliczenia i wypłata środków działają dalej.
- Jackpot jest wypłacany w ratach: zwycięzcy należy się 95% puli, z tego 20% od razu i po 8% tygodniowo. Niewypłacona część jest zapisana na koncie zwycięzcy.
- Jedna niedokończona runda na gracza. Dopóki runda nie jest rozliczona, nowa stawka nie jest przyjmowana.
Co może, a czego nie może administrator
Może
- odbierać swój udział — 10% opłaconych stawek;
- wnosić SOL do rezerwy i przenosić je z rezerwy do banku nagród;
- odebrać nadwyżkę, która przy uruchomieniu znalazła się w skarbcu ponad bank startowy;
- zmieniać kwoty startowe jackpotów — z opóźnieniem i w określonych granicach;
- wstrzymać przyjmowanie nowych stawek, jeśli wyrocznia nie odpowiada, oraz przekazać swoje uprawnienia innemu kluczowi.
Nie może
- wypłacić banku nagród, jackpotów, rezerwy ani sald graczy (jako gracz wygrywa na ogólnych zasadach);
- zmieniać tabel nagród, szansy na nagrodę w grach ani udziałów stawki: to stałe w kodzie;
- poznać liczby losowej rundy przed stawką ani jej wybrać;
- zatrzymać rozliczenia postawionych stawek ani wypłaty: pauza dotyczy tylko nowych stawek.
Uczciwe zastrzeżenie. Program ma uprawnienie do aktualizacji: dopóki nie zostało odwołane, jego posiadacz może zastąpić kod nową wersją i wtedy wszystko, co napisano wyżej, będzie dotyczyć już nowego kodu. Stan tego uprawnienia i każdą aktualizację widać w eksploratorze Solana. Niezależnego audytu kontraktu nie ma.
Jak to sprawdzono
- Testy kontraktu: udział administratora 10% w każdej grze, zbliżony zwrot wszystkich gier przy banku 50 SOL, reguła ćwierci banku i limit nagrody z chwili stawki, blokada wypłaty, odroczona zmiana kwot startowych, późne rozliczenie nie jest korzystniejsze od terminowego.
- Sprawdzenie zachowania środków: dziesiątki tysięcy losowych operacji, po każdej kwota w skarbcu jest porównywana z sumą sald i pul.
- Długie przebiegi: po dwa miliony stawek na każdą grę — ile wypłacono graczom, ile otrzymał administrator.
- Prawdziwe transakcje na lokalnym węźle Solana: wpłata, odmowa wypłaty przed terminem, wniesienie do rezerwy, zmiana kwot startowych.
- Testy strony: strona liczy szanse tymi samymi wzorami co kontrakt i porównuje wyniki z wzorcami zapisanymi przez kontrakt.
Co nie zostało sprawdzone ani zrobione, wymieniono bez upiększeń na stronie „Dlaczego FAIRDRUM”. Jak samodzielnie sprawdzić dowolną rundę — na stronie „Sprawdź rundę”.
Parametry kontraktu w jednej tabeli
- Pojedyncza stawka
- 0,01 SOL
- Runda
- do 100 stawek w grach, do 1000 na bębnie
- Gier (trybów)
- 16
- Szansa na „Jeszcze raz”
- 11,6%
- Limit jednej nagrody
- 1/4 banku nagród
- Najmniejsza kwota startowa
- jackpot 0,2 SOL, superjackpot 2 SOL
- Mini-jackpot
- startuje od 1/10 jackpota
- Dla zwycięzcy jackpota
- 95% · 5% trafia do superjackpota
- Dla zwycięzcy superjackpota
- 90%
- Blokada wypłaty
- 12 godz. po ostatniej wpłacie
- Termin rozliczenia rundy
- 3000 slotów sieci, około 20 minut
- Opłata sieci i wyroczni
- 0,005 SOL za rundę, nie pobiera jej projekt