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

Jednog jutra naišao sam na članak o provjerljivi generator slučajnih brojeva na blockchainu platforme Waves.

Ukupna slika je bila jasna, ali specifična metoda implementacije nije bila. Neki kodovi, potpisi, što, gdje, zašto?

Nakon nekoliko konzultacija s autorom proročišta, uspio sam kombinirati logiku crtanja (implementiranu u PHP-u) s algoritmom generiranja slučajnih brojeva.

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

    U ovom trenutku nema informacija o broju igrača, broju dobitnih mjesta, veličini isplata nagrada, pa čak ni o postojanju lutrije. Oracle izdaje personalizirani slučajni kod putem transakcije, koji zatim može koristiti samo jednom i samo podnositelj zahtjeva. Usput, nekoliko R-kodova može se "kupiti" unaprijed (što znači trošak transakcije zahtjeva plus naknada Oracleu za povratnu transakciju, što je otprilike 0.015 USD po trenutnom tečaju; sam kod se izdaje besplatno), tako da ne morate kasnije čekati povratnu transakciju. Napravio sam mali, redovito ažurirani međuspremnik u bazi podataka.

  2. Turnir obično traje 60 Waves Platform blockchain blokova, što je trenutno otprilike jedan sat. Turnir se smatra završenim i zatvorenim ako nakon 60 blokova postoje barem dvije karte. U suprotnom, turnir se produžuje za dodatnih 60 blokova.
  3. Odmah nakon zatvaranja turnira generiramo i šaljemo podatkovnu transakciju (za nju plaćamo i proviziju od otprilike 0.005 USD), ili nekoliko ako je potrebno, koja bilježi sve uvjete izvlačenja i uređeni popis igrača (ulaznica) s kojih trebamo odabrati pobjednike.
  4. U ovoj fazi već imamo prvi dio koda (R-kod) plus datum ID-a transakcije (TXID). Šaljemo ih orakulu na potpis kao spajanje (R-kod + TXID), ponovno plaćajući naknadu i kompenzaciju. Oracle provjerava primljene podatke na jedinstvenost i vlasništvo te nam kao odgovor šalje drugi dio koda (S-kod) u sha256 formatu, što je početna točka za generator slučajnih brojeva.
  5. Za dobivanje slučajnog broja koji označava serijski broj dobitne srećke, pretvaramo S-kod iz binarnih podataka sha256 u heksadecimalni (HEX) prikaz. Zatim, iz rezultirajućeg HEX niza dobivamo broj. Uzimamo ostatak dijeljenja rezultirajućeg broja s brojem srećki (sve_srećke) i dodajemo 1 rezultatu (kako bismo dobili znamenku 1 prije svih_sve_srećke). To rezultira serijskim brojem dobitnika.
  6. Ako pravila izvlačenja određuju više dobitnika, ponavljamo prethodne korake za broj jednak broju dobitnih mjesta. Svaki put uklanjamo već dobitni listić s popisa, smanjujemo sve_listićke za 1 i zamjenjujemo S-kod prethodno primljenim brojem.

Pogledajmo konkretan primjer iz stvarnog života, turnir #119:

Samo 7 ulaznica (all_tickets)
Cijena listića je 50 novčića (Oklada)
Naknada za igru ​​10% (Naknada)

Prema pravilima lutrije, 30% dobitka ide u nagradni fond, što znači da u ovom slučaju 2 listića moraju osvojiti nagradu, čiji se iznos izračunava pomoću formule (Oklada*sve_listići-Naknada)/2.

1. Primljeni R-kod: RdbAiAhKhveAtR4eyTKq75noMxdcEoxbE6BvojJjM13VE

2. Nakon završetka turnira, imamo popis ulaznica u parovima: broj + adresa (adresa novčanika s kojeg je plaćena kotizacija za turnir). Imajte na umu da se adrese mogu duplicirati, što znači da je jedan sudionik kupio više ulaznica za isti turnir; to nije zabranjeno pravilima.

Datum poslane transakcije: 82JTMzhHM5xEA2fQ9Qscd5QAJU3DAd8nShLjdVHTer5S

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

4. Primljeni S-kod: Ri89jHB4UXZDXY6gT1m4LBDXGMTaYzHozMk4nxiuqVXdC

5. Pobjednici su bili određeni.

6. Uplate su poslane

Kao rezultat toga, imamo detaljan zapis procesa izvlačenja nagrada na blockchainu, koji se može provjeriti u bilo kojem trenutku. Organizatoru je gotovo nemoguće namjestiti rezultate, ili barem ne neotkriveno.

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