Použitie náhodného orákula na príklade lotérie

Raz ráno som narazil na článok o overiteľný generátor náhodných čísel na blockchaine platformy Waves.

Celkový obraz bol jasný, ale konkrétna metóda implementácie nie. Nejaké kódy, podpisy, čo, kde, prečo?

V dôsledku niekoľkých konzultácií s autorom orákula bolo možné skombinovať logiku kreslenia (implementovanú v PHP) s algoritmom na získanie náhodného čísla.

  1. Na začiatku turnaja/kola si od orákula vyžiadame prvú časť kódu (R-kód).

    Momentálne nie sú k dispozícii žiadne informácie o počte hráčov, počte výherných miest, veľkosti vyplatených výhier, ani o existencii lotérie vo všeobecnosti. Oracle prostredníctvom transakcie vydá osobný náhodný kód, ktorý potom môžu použiť iba raz a iba tí, ktorí oň požiadali. Mimochodom, R-kód je možné „zakúpiť“ (čo znamená náklady na transakciu žiadosti + kompenzácia oracle za transakciu odpovede, pri aktuálnom kurze ide o sumu približne 0.015 USD, samotný kód je vydaný bezplatne ) niekoľkokrát vopred, aby ste neskôr nečakali na prijatie odpovede. V databáze som vytvoril malý pravidelne aktualizovaný buffer.

  2. Turnaj zvyčajne trvá 60 blokov blockchainu platformy Waves, momentálne je to približne 1 hodina. Turnaj sa považuje za ukončený a uzavretý, ak po 60 blokoch sú v ňom aspoň dve vstupenky, inak sa čas aktivity turnaja predlžuje o ďalších 60 blokov.
  3. Ihneď po uzavretí turnaja vygenerujeme a odošleme dátumovú transakciu (platíme za ňu aj províziu približne 0.005 $), v prípade potreby aj niekoľko, v ktorej sú zaznamenané všetky podmienky žrebovania a objednaný zoznam hráčov (vstupenky) z ktorých musíme vybrať víťazov.
  4. V tejto fáze už máme prvú časť kódu (R-kód) plus ID dátumu transakcie (TXID). Posielame ich na podpis do orákula vo forme zreťazenia (R-kód + TXID), opäť platíme províziu + kompenzáciu. Oracle skontroluje jedinečnosť a príslušnosť prijatých údajov a ako odpoveď nám pošle druhú časť kódu (S-kód) vo formáte sha256, ktorý je východiskovým bodom pre generátor náhodných čísel.
  5. Aby sme získali náhodné číslo, ktoré bude udávať poradové číslo výherného tiketu, konvertujeme S-kód z binárnych údajov sha256 do hexadecimálnej (HEX) reprezentácie. Potom z výsledného HEX reťazca dostaneme číslo. Získame zvyšok vydelením výsledného čísla počtom tiketov (all_tickets) a k výsledku pridáme 1 (aby sme dostali číslo 1 pred all_tickets). V dôsledku toho získame poradové číslo víťaza.
  6. Ak je podľa podmienok žrebovania niekoľko výhercov, zopakujeme predchádzajúce operácie v množstve, ktoré sa rovná počtu výherných miest. V tomto prípade zakaždým odstránime zo zoznamu už vyhraný tiket a znížime all_tickets o 1 a namiesto S-kódu uvedieme predchádzajúce prijaté číslo.

Pozrime sa na konkrétny reálny príklad, turnaj č. 119:

Celkom 7 vstupeniek (all_tickets)
Vstupenka stojí 50 mincí (stávka)
Poplatok za hru 10 % (poplatok)

Na prize money ide podľa podmienok lotérie 30 %, t.j. v tomto prípade musia byť odmenené 2 tikety, ktorých veľkosť sa vypočíta podľa vzorca (Bet*all_tickets-Fee)/2.

1. Prijatý R-kód: RdbAiAhKhveAtR4eyTKq75noMxdcEoxbE6BvojJjM13VE

2. Po uzávierke turnaja máme zoznam tiketov v tvare párov: číslo + adresa (adresa peňaženky, z ktorej bola realizovaná platba za účasť v turnaji). Upozorňujeme, že adresy sa môžu opakovať, to znamená, že jeden účastník si zakúpil viacero vstupeniek na jeden turnaj, čo pravidlá nezakazujú.

Dátum odoslania transakcie: 82JTMzhHM5xEA2fQ9Qscd5QAJU3DAd8nShLjdVHTer5S

3. Požadovaný S-kód: FTF3uRyaa4F2uAyD6z5a3CNbTXbQLc7fSR6CFNVjgZYV s komentárom (R-kód + TXID):
RdbAiAhKhveAtR4eyTKq75noMxdcEoxbE6BvojJjM13VE 82JTMzhHM5xEA2fQ9Qscd5QAJU3DAd8nShLjdVHTer5S

4. Prijatý S-kód: Ri89jHB4UXZDXY6gT1m4LBDXGMTaYzHozMk4nxiuqVXdC

5. Boli určení víťazi.

6. Odoslané platby

Výsledkom je záznam postupu žrebovania cien v blockchaine krok za krokom s možnosťou kedykoľvek ho skontrolovať. Pre organizátora je takmer nemožné manipulovať s výsledkami, minimálne to už nebude možné urobiť bez povšimnutia.

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.

Zdroj: hab.com

Pridať komentár