Korištenje slučajnog proročišta na primjeru lutrije

Jednog jutra naišao sam na članak o tome provjerljivi generator slučajnih brojeva na platformi Waves blockchain.

Ukupna slika je bila jasna, ali konkretan metod implementacije nije. Neke šifre, potpisi, šta, gdje, zašto?

Nekoliko konsultacija sa autorom orakula, kao rezultat, bilo je moguće kombinovati logiku crtanja (primenjenu u PHP-u) sa algoritmom za dobijanje slučajnog broja.

  1. Na početku turnira/runda tražimo prvi dio koda (R-kod) od proročišta.

    U ovom trenutku nema informacija o broju igrača, broju nagradnih mjesta, veličini isplata nagrada, niti o postojanju lutrije općenito. Proročanstvo, putem transakcije, izdaje lični slučajni kod, koji onda mogu koristiti samo jednom i samo oni koji su to zatražili. Usput, R-kod se može "kupiti" (što znači trošak transakcije zahtjeva + kompenzacija proročanstvu za odgovornu transakciju, to je iznos od oko 0.015 USD po trenutnom kursu, sam kod se izdaje besplatno ) nekoliko puta unaprijed, kako se kasnije ne bi čekalo prijem odgovorne transakcije. Napravio sam mali redovno ažuriran bafer u bazi podataka.

  2. Turnir obično traje 60 blokova platforme Waves blockchain, trenutno je otprilike 1 sat. Turnir se smatra završenim i zatvorenim ako nakon 60 blokova postoje najmanje dvije karte u njemu, u suprotnom se vrijeme aktivnosti turnira produžava za sljedećih 60 blokova.
  3. Odmah po zatvaranju turnira generišemo i šaljemo transakciju datuma (takođe plaćamo proviziju od cca 0.005$ za nju), ako je potrebno, nekoliko, u kojima su zabeleženi svi uslovi izvlačenja i naručena lista igrača (karte) od kojih treba da izaberemo pobednike.
  4. U ovoj fazi već imamo prvi dio koda (R-code) plus ID datuma transakcije (TXID). Šaljemo ih na potpis orakulu u obliku konkatenacije (R-code + TXID), opet plaćamo proviziju + kompenzaciju. Proročište provjerava jedinstvenost i pripadnost primljenih podataka i kao odgovor nam šalje drugi dio koda (S-code) u formatu sha256, koji je polazna tačka za generator slučajnih brojeva.
  5. Da bismo dobili nasumični broj koji će označavati redni broj dobitnog tiketa, pretvaramo S-kod iz binarnih podataka sha256 u heksadecimalni (HEX) prikaz. Zatim iz rezultujućeg HEX niza dobijamo broj. Dobijamo ostatak dijeljenja rezultirajućeg broja brojem karata (sve_ulaznice) i rezultatu dodamo 1 (da dobijemo broj 1 prije svih_karata). Kao rezultat, dobijamo serijski broj pobjednika.
  6. Ako, prema uslovima izvlačenja, ima više dobitnika, onda ponavljamo prethodne operacije u iznosu jednakom broju nagradnih mjesta. U ovom slučaju, svaki put uklonimo sa liste tiket koji je već osvojio i smanjimo all_tickets za 1, a umjesto S-koda navedemo prethodni primljeni broj.

Pogledajmo konkretan pravi primjer, turnir br. 119:

Ukupno 7 ulaznica (sve_ulaznice)
Cijena ulaznice 50 kovanica (Oklada)
Naknada za igru ​​10% (naknada)

Prema uslovima lutrije, 30% ide na novčanu nagradu, tj. u tom slučaju 2 tiketa moraju dobiti nagradu, čija se veličina izračunava prema formuli (Bet*all_tickets-Fee)/2.

1. Primljeni R kod: RdbAiAhKhveAtR4eyTKq75noMxdcEoxbE6BvojJjM13VE

2. Nakon zatvaranja turnira, imamo listu ulaznica u obliku parova: broj + adresa (adresa novčanika iz kojeg je izvršena uplata za učešće na turniru). Napominjemo da se adrese mogu ponavljati, što znači da je jedan učesnik kupio više karata za jedan turnir, što nije zabranjeno pravilima.

Poslan datum transakcije: 82JTMzhHM5xEA2fQ9Qscd5QAJU3DAd8nShLjdVHTer5S

3. Traženi S kod: FTF3uRyaa4F2uAyD6z5a3CNbTXbQLc7fSR6CFNVjgZYV sa komentarom (R-kod + TXID):
RdbAiAhKhveAtR4eyTKq75noMxdcEoxbE6BvojJjM13VE 82JTMzhHM5xEA2fQ9Qscd5QAJU3DAd8nShLjdVHTer5S

4. Primljeni S kod: Ri89jHB4UXZDXY6gT1m4LBDXGMTaYzHozMk4nxiuqVXdC

5. Određeni su pobjednici.

6. Poslane uplate

Kao rezultat, imamo postupno snimanje postupka izvlačenja nagrada u blockchain-u s mogućnošću provjere u bilo kojem trenutku. Gotovo je nemoguće da organizator manipuliše rezultatima, barem to više neće biti moguće učiniti neprimijećeno.

determine the winner № 1

All_tickets:
Index: 1 Ticket:139
Index: 2 Ticket:141
Index: 3 Ticket:143
Index: 4 Ticket:145
Index: 5 Ticket:147
Index: 6 Ticket:149
Index: 7 Ticket:151

1. bin -> hex ( bin2hex(sha256(S-code)) ): Ri89jHB4UXZDXY6gT1m4LBDXGMTaYzHozMk4nxiuqVXdC -> 0xdaf5802953dcb27f89972e38e8900b898733f6a613e6e1c6c5491362c1832596

2. hex -> gmp number: 0xdaf5802953dcb27f89972e38e8900b898733f6a613e6e1c6c5491362c1832596 -> 99037963059744689166154019807924045947962565922868104113173478160267437352342

3. gmp -> modulo (mod=7): 99037963059744689166154019807924045947962565922868104113173478160267437352342 -> 4

4. modulo -> ticket: 4 -> 145

determine the winner № 2

All_tickets:

Index: 1 Ticket:139
Index: 2 Ticket:141
Index: 3 Ticket:143
Index: 4 Ticket:147
Index: 5 Ticket:149
Index: 6 Ticket:151

1. bin -> hex ( bin2hex(sha256(previous hex)) ): daf5802953dcb27f89972e38e8900b898733f6a613e6e1c6c5491362c1832596 -> 0x9560e77525e9ea2db92cdb8484dc52046ccafac7c719b8859ff55f0eb92834a0
2. hex -> gmp number: 0x9560e77525e9ea2db92cdb8484dc52046ccafac7c719b8859ff55f0eb92834a0 -> 67565829218838067182838043983962684143266386786567427968312120473742580659360
3. gmp -> modulo (mod=6): 67565829218838067182838043983962684143266386786567427968312120473742580659360 -> 1
4. modulo -> ticket: 1 -> 139

End.

izvor: www.habr.com

Dodajte komentar