Jedného rána sa mi do rúk dostal článok o na blockchaine platformy Waves.
Celkový obraz bol jasný, ale samotný spôsob realizácie - to nie. Akési kódy, podpisy, čo, kam, prečo?
Po niekoľkých konzultáciách s autorom orákula sa mi podarilo kombinovať logiku žrebovania (realizovanú v PHP) s algoritmom pre získavanie náhodného čísla.
- V momente štartu turnaja/kola žiadame od orákula prvú časť kódu (R-code).
V tomto momente nemáme informácie ani o počte hráčov, ani o počte víťazných miest, ani o výške výhier a vlastne o existencii lotérie. Orákul prostredníctvom transakcie vydáva osobný náhodný kód, ktorý môže byť použitý len raz a len tým, ktorí ho požiadali. Mimochodom, R-code si môžete "zakúpiť" (myslí sa tým cena transakcie žiadosti + kompenzácia orákulu za odpovedajúcu transakciu, táto suma je približne $0.015 podľa aktuálneho kurzu, samotný kód sa poskytuje zdarma) vopred, aby ste nestrácali čas s čakánim na odpovedajúcu transakciu. Vytvoril som si malý pravidelne dopĺňaný buffer v DB.
- Turnaj trvá štandardne 60 blokov blockchainu platformy Waves, to je momentálne približne 1 hodina. Turnaj sa považuje za uskutočnený a uzavretý, ak bude po 60 blokoch v ňom aspoň dve lístky, inak sa čas aktivity turnaja predlžuje na ďalších 60 blokov.
- Ihneď po uzavretí turnaja vytvárame a odosielame dátovú transakciu (za ktorú tiež platíme poplatok približne $0.005), ak je to potrebné - niekoľko transakcií, v ktorých sú zaznamenané všetky podmienky žrebovania a usporiadaný zoznam hráčov (lístkov), z ktorého musíme vybrať víťazov.
- V tomto štádiu už máme prvú časť kódu (R-code) plus ID dátovej transakcie (TXID). Odosielame ich na podpis orákulu vo forme konkatenácie (R-code + TXID), opäť platíme poplatok + kompenzáciu. Orákul kontroluje prijaté údaje na jedinečnosť a príslušnosť a na oplátku nám posiela druhú časť kódu (S-code) vo formáte sha256, ktorá je východiskovým bodom pre generátor náhodných čísel.
- Aby sme získali náhodné číslo, ktoré určuje poradové číslo víťazného lístka, prekonvertujeme S-kód z binárnych údajov sha256 do hexadecimálneho (HEX) formátu. Následne z získaného HEX reťazca dostaneme číslo. Získame zvyšok po delení tohto čísla celkovým počtom lístkov (all_tickets) a k výsledku pridáme 1 (aby sme získali číslo od 1 do all_tickets). Nakoniec získame poradové číslo víťaza.
- Ak v podmienkach žrebovania existuje viac víťazov, opakujeme predchádzajúce operácie rovnaký počet krát, ako je počet výherných miest. Pri každom kroku z od zoznamu odstránime lístok, ktorý už vyhral, a znížime all_tickets o 1, pričom namiesto S-kódu použijeme predchádzajúce získané číslo.
Rozoberieme konkrétny reálny príklad, turnaj č. 119:
Celkovo 7 lístkov (all_tickets)
Cena lístka 50 mincí (Bet)
Herný poplatok 10% (Fee)
Podľa pravidiel lotérie sa 30% dostáva do výherných, t.j. v tomto prípade 2 lístky by mali získať cenu, ktorej výška sa počíta podľa vzorca (Bet * all_tickets - Fee) / 2.
1. Získali sme R-kód:
2. Po uzavretí turnaja máme zoznam lístkov vo forme párov: číslo + adresa (adresa peňaženky, z ktorej boli zaplatené náklady na účasť v turnaji). Všimnite si, že adresy sa môžu opakovať, čo znamená, že jeden účastník kúpil niekoľko lístkov na jeden turnaj, čo nie je proti pravidlám.
Poslali sme dátum transakcie:
3. Požiadali sme o S-kód: s komentárom (R-kód + TXID):
RdbAiAhKhveAtR4eyTKq75noMxdcEoxbE6BvojJjM13VE 82JTMzhHM5xEA2fQ9Qscd5QAJU3DAd8nShLjdVHTer5S
4. Získali sme S-kód:
5. Určili sme víťazov.
6.
Výsledkom je, že máme v blockchaine krok za krokom záznam postupu žrebovania cien s možnosťou overiť ho kedykoľvek. Podvádzať výsledky zo strany organizátora je prakticky nemožné, aspoň to už nebude možné urobiť nenápadne.
určte víťaza č. 1
Všetky_lístky:
Index: 1 Lístok:139
Index: 2 Lístok:141
Index: 3 Lístok:143
Index: 4 Lístok:145
Index: 5 Lístok:147
Index: 6 Lístok:149
Index: 7 Lístok:151
1. bin -> hex ( bin2hex(sha256(S-kód)) ): Ri89jHB4UXZDXY6gT1m4LBDXGMTaYzHozMk4nxiuqVXdC -> 0xdaf5802953dcb27f89972e38e8900b898733f6a613e6e1c6c5491362c1832596
2. hex -> gmp číslo: 0xdaf5802953dcb27f89972e38e8900b898733f6a613e6e1c6c5491362c1832596 -> 99037963059744689166154019807924045947962565922868104113173478160267437352342
3. gmp -> modulo (mod=7): 99037963059744689166154019807924045947962565922868104113173478160267437352342 -> 4
4. modulo -> lístok: 4 -> 145
určte víťaza č. 2
Všetky_lístky:
Index: 1 Lístok:139
Index: 2 Lístok:141
Index: 3 Lístok:143
Index: 4 Lístok:147
Index: 5 Lístok:149
Index: 6 Lístok:151
1. bin -> hex ( bin2hex(sha256(prechádzajúci hex)) ): daf5802953dcb27f89972e38e8900b898733f6a613e6e1c6c5491362c1832596 -> 0x9560e77525e9ea2db92cdb8484dc52046ccafac7c719b8859ff55f0eb92834a0
2. hex -> gmp číslo: 0x9560e77525e9ea2db92cdb8484dc52046ccafac7c719b8859ff55f0eb92834a0 -> 67565829218838067182838043983962684143266386786567427968312120473742580659360
3. gmp -> modulo (mod=6): 67565829218838067182838043983962684143266386786567427968312120473742580659360 -> 1
4. modulo -> lístok: 1 -> 139
Koniec.Zdroj: habr.com
