Uporaba naključnega oraklja na primeru loterije

Nekega jutra sem naletel na članek o preverljiv generator naključnih števil na verigi blokov platforme Waves.

Celotna slika je bila jasna, konkretna metoda izvajanja pa ne. Neke kode, podpisi, kaj, kje, zakaj?

Več posvetovanj z avtorjem orakula je bilo mogoče združiti logiko risanja (izvedeno v PHP) z algoritmom za pridobivanje naključnega števila.

  1. Na začetku turnirja/kroga od oraklja zahtevamo prvi del kode (R-code).

    V tem trenutku ni podatkov o številu igralcev, številu nagradnih mest, velikosti izplačil nagrad ali sploh o obstoju loterije. Orakelj s transakcijo izda osebno naključno kodo, ki jo nato lahko uporabi le enkrat in samo tisti, ki jo zahteva. Mimogrede, R-kodo je mogoče "kupiti" (kar pomeni stroške transakcije zahteve + nadomestilo oraklju za transakcijo odgovora, to je znesek približno 0.015 USD po trenutnem tečaju, sama koda se izda brezplačno ) večkrat vnaprej, da ne boste pozneje čakali na prejem odgovora na transakcijo. V bazi podatkov sem naredil majhen medpomnilnik, ki se redno posodablja.

  2. Turnir običajno traja 60 blokov verige blokov platforme Waves, trenutno traja približno 1 uro. Turnir se šteje za zaključen in zaključen, če sta po 60 blokih v njem vsaj dve vstopnici, sicer se čas turnirske aktivnosti podaljša za naslednjih 60 blokov.
  3. Takoj po zaključku turnirja generiramo in pošljemo datumsko transakcijo (zanjo plačamo tudi provizijo cca 0.005 $), po potrebi več, v kateri so zabeleženi vsi pogoji žrebanja in urejen seznam igralcev (vstopnice) med katerimi moramo izbrati zmagovalce.
  4. Na tej stopnji že imamo prvi del kode (R-code) in ID datuma transakcije (TXID). Pošljemo jih v podpis oraklju v obliki veriženja (R-code + TXID), spet plačamo provizijo + nadomestilo. Orakel prejete podatke preveri glede unikatnosti in pripadnosti ter nam v odgovor pošlje drugi del kode (S-code) v formatu sha256, ki je izhodišče za generator naključnih števil.
  5. Za pridobitev naključnega števila, ki bo označevalo zaporedno številko zmagovalnega listka, pretvorimo S-kodo iz binarnih podatkov sha256 v šestnajstiško (HEX) predstavitev. Nato iz nastalega HEX niza dobimo številko. Dobimo ostanek deljenja dobljenega števila s številom vstopnic (vse_vstopnice) in rezultatu dodamo 1 (da dobimo število 1 pred vsemi_vstopnicami). Kot rezultat dobimo zaporedno številko zmagovalca.
  6. Če je v skladu s pogoji žrebanja več zmagovalcev, ponovimo prejšnje operacije v količini, ki je enaka številu nagradnih mest. V tem primeru vsakič odstranimo s seznama že zmagovalni listek in zmanjšamo all_tickets za 1, namesto kode S pa navedemo prejšnje prejeto število.

Poglejmo konkreten resničen primer, turnir št. 119:

Skupaj 7 vstopnic (vse_vstopnice)
Vstopnica stane 50 kovancev (stava)
Provizija za igro 10 % (provizija)

V skladu s pogoji loterije gre 30% za denarno nagrado, tj. v tem primeru morata 2 listka prejeti dobitek, katerega velikost se izračuna po formuli (Stava*vse_vstopnice-Provizija)/2.

1. Prejeta R-koda: RdbAiAhKhveAtR4eyTKq75noMxdcEoxbE6BvojJjM13VE

2. Po zaključku turnirja imamo seznam vstopnic v obliki parov: številka + naslov (naslov denarnice, iz katere je bilo izvedeno plačilo za sodelovanje na turnirju). Upoštevajte, da se naslovi lahko ponavljajo, kar pomeni, da je en udeleženec kupil več vstopnic za en turnir, kar ni prepovedano s pravili.

Datum poslane transakcije: 82JTMzhHM5xEA2fQ9Qscd5QAJU3DAd8nShLjdVHTer5S

3. Zahtevana S-koda: FTF3uRyaa4F2uAyD6z5a3CNbTXbQLc7fSR6CFNVjgZYV s komentarjem (R-koda + TXID):
RdbAiAhKhveAtR4eyTKq75noMxdcEoxbE6BvojJjM13VE 82JTMzhHM5xEA2fQ9Qscd5QAJU3DAd8nShLjdVHTer5S

4. Prejeta S-koda: Ri89jHB4UXZDXY6gT1m4LBDXGMTaYzHozMk4nxiuqVXdC

5. Zmagovalci so bili določeni.

6. Poslana plačila

Posledično imamo v blokovni verigi posnetek postopka žrebanja nagrad po korakih z možnostjo, da ga kadarkoli preverimo. Skoraj nemogoče je, da bi organizator prirejal rezultate, vsaj neopazno ne bo več mogoče.

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.

Vir: www.habr.com

Dodaj komentar