Jednoho rána jsem narazil na článek o
Celkový obrázek byl jasný, ale konkrétní způsob implementace nikoli. Nějaké kódy, podpisy, co, kde, proč?
Po několika konzultacích s autorem orákula bylo možné zkombinovat kreslicí logiku (implementovanou v PHP) s algoritmem pro získání náhodného čísla.
- Na začátku turnaje/kola požadujeme od orákula první část kódu (R-kód).
V tuto chvíli nejsou k dispozici žádné informace o počtu hráčů, počtu výherních míst, velikosti výplat cen, ani o existenci loterie obecně. Orákulum prostřednictvím transakce vydá osobní náhodný kód, který pak mohou použít pouze jednou a pouze ti, kteří o něj požádali. Mimochodem, R-kód lze „zakoupit“ (což znamená náklady na transakci požadavku + kompenzaci orákulu za transakci odpovědi, jedná se o částku asi 0.015 $ při aktuálním kurzu, samotný kód je vydán zdarma ) několikrát předem, abyste nečekali na přijetí transakce s odpovědí později. Udělal jsem malý pravidelně aktualizovaný buffer v databázi.
- Turnaj obvykle trvá 60 bloků blockchainu platformy Waves, v tuto chvíli je to přibližně 1 hodina. Turnaj je považován za ukončený a uzavřený, pokud jsou v něm po 60 blocích alespoň dvě vstupenky, v opačném případě se čas turnajové aktivity prodlužuje o dalších 60 bloků.
- Ihned po uzavření turnaje vygenerujeme a odešleme datovou transakci (platíme za ni i provizi cca 0.005 $), v případě potřeby i několik, ve které jsou zaznamenány všechny podmínky losování a objednaný seznam hráčů (ticketů) ze kterých musíme vybrat vítěze.
- V této fázi již máme první část kódu (R-kód) plus ID data transakce (TXID). Zasíláme je k podpisu orákulu ve formě zřetězení (R-kód + TXID), opět platíme provizi + kompenzaci. Oracle kontroluje přijatá data na jedinečnost a sounáležitost a jako odpověď nám zašle druhou část kódu (S-kód) ve formátu sha256, což je výchozí bod pro generátor náhodných čísel.
- Abychom získali náhodné číslo, které bude udávat pořadové číslo výherního tipu, převedeme S-kód z binárních dat sha256 na hexadecimální (HEX) reprezentaci. Potom z výsledného HEX řetězce dostaneme číslo. Dostaneme zbytek vydělením výsledného čísla počtem tipů (all_tickets) a k výsledku přičteme 1 (pro získání čísla 1 před all_tickets). V důsledku toho získáme sériové číslo vítěze.
- Pokud je podle podmínek slosování více výherců, opakujeme předchozí operace v množství rovnajícím se počtu výherních míst. V tomto případě pokaždé odstraníme ze seznamu tiket, který již vyhrál, a snížíme all_tickets o 1 a místo S-kódu uvedeme předchozí přijaté číslo.
Podívejme se na konkrétní reálný příklad, turnaj č. 119:
Celkem 7 vstupenek (all_tickets)
Vstupenka stojí 50 mincí (sázka)
Poplatek za hru 10 % (poplatek)
Na prize money jde dle podmínek loterie 30 %, tzn. v tomto případě musí cenu obdržet 2 tikety, jejichž velikost se vypočítá podle vzorce (Sázka*vse_vstupenky-Poplatek)/2.
1. Přijatý R-kód:
2. Po uzavření turnaje máme seznam tiketů ve tvaru párů: číslo + adresa (adresa peněženky, ze které probíhala platba za účast v turnaji). Upozorňujeme, že adresy se mohou opakovat, to znamená, že si jeden účastník zakoupil více vstupenek na jeden turnaj, což pravidla nezakazují.
Datum odeslání transakce:
3. Požadovaný S-kód:
RdbAiAhKhveAtR4eyTKq75noMxdcEoxbE6BvojJjM13VE 82JTMzhHM5xEA2fQ9Qscd5QAJU3DAd8nShLjdVHTer5S
4. Přijatý S-kód:
5. Byli určeni vítězové.
Díky tomu máme krok za krokem záznam postupu losování cen v blockchainu s možností kdykoli jej zkontrolovat. Pro pořadatele je téměř nemožné manipulovat s výsledky, minimálně to již nebude možné dělat bez povšimnutí.
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: www.habr.com