Jednog jutra naišao sam na članak o 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.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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:
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:
3. Zatraženi S-kod: s komentarom (R-kod + TXID):
RdbAiAhKhveAtR4eyTKq75noMxdcEoxbE6BvojJjM13VE 82JTMzhHM5xEA2fQ9Qscd5QAJU3DAd8nShLjdVHTer5S
4. Primljeni S-kod:
5. Pobjednici su bili određeni.
6.
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
