Egy reggel rábukkantam egy cikkre, ami a a Waves platform blokkláncán.
Az általános kép világos volt, de a konkrét megvalósítás módszere nem. Kódok, aláírások, miért, hova, miért?
Néhány konzultáció után az oracle szerzőjével sikerült ötvözni a sorsolás logikáját (PHP-ben megvalósítva) a véletlenszám-generálási algoritmussal.
- A verseny/kör kezdetekor kérjük az oracle-tól a kód első részét (R-kód).
Ebben a pillanatban nincs információnk sem a játékosok számáról, sem a nyereményhelyek számáról, sem a nyeremények összegéről, és egyáltalán a lottó létezéséről. Az oracle tranzakció révén egy személyes véletlen kódot ad, amelyet később csak egyszer használhatunk fel, és csak annak, aki kérte. Egyébként az R-kódot "meg lehet venni" (ez a tranzakciós kérési költség + az oracle választranzakciójáért járó kompenzáció, ez körülbelül $0,015 az aktuális árfolyamon, maga a kód ingyenes) előre, akár több darabot is, hogy később ne kelljen várni a választranzakció megérkezésére. Készítettem egy kis, rendszeresen frissített buffert az adatbázisban.
- A verseny standard módon 60 blokkig tart a Waves platform blokkláncán, ez jelenleg körülbelül 1 órát jelent. A verseny akkor tekinthető lezártnak, ha 60 blokk után legalább két jegy van benne, különben a verseny aktivitási ideje a következő 60 blokkra meghosszabbodik.
- Közvetlenül a verseny lezárása után tranzakciós adatokat generálunk és küldünk el (ezért is fizetünk egy körülbelül $0,005-os díjat), ha szükséges, többet is, amely rögzíti az összes sorsolási feltételt és a játékosok (jegyek) rendezett listáját, amelyből ki kell választanunk a győzteseket.
- Ez idő tájt már rendelkeznünk kell az R-kód első részével plusz a tranzakciós adat ID-val (TXID). Ezeket az oracle-nak küldjük aláírásra a concatenáció formájában (R-kód + TXID), ismét díjat + kompenzációt fizetve. Az oracle ellenőrzi az adatokat az egyediség és tulajdonjog szempontjából, majd válaszként küldi el nekünk a kód második részét (S-kód), amely sha256 formátumban található, és ez lesz az alapja a véletlenszám-generátornak.
- A véletlenszám megkapásához, amely a nyertes jegy sorszámát jelöli, a S-kódot bináris adatból sha256 hexadecimális (HEX) reprezentációra alakítjuk át. Az így kapott HEX sztringből számot nyerünk. Az eredményül kapott számot a jegyek számával (all_tickets) osztva kapott maradékhoz 1-et adunk (hogy 1-et kapjunk all_tickets-ig). Végül megkapjuk a nyertes sorszámát.
- Ha a sorsolás feltételei szerint több nyertes van, akkor a korábbi műveleteket annyiszor ismételjük meg, ahány nyeremény hely van. Minden alkalommal eltávolítjuk a nyertes listából a már nyert jegyet, és csökkentjük az all_tickets számot 1-el, míg a S-kód helyett az előzőleg kapott számot adjuk meg.
Nézzünk meg egy konkrét valós példát, a 119. számú tornát:
Összesen 7 jegy (all_tickets)
A jegy ára 50 érme (Bet)
Játékos díj 10% (Fee)
A lottó feltételei szerint a 30% nyereménybe kerül, tehát ebben az esetben 2 jegynek kell nyernie, aminek mértéke a következő képlet segítségével számolható: (Bet*all_tickets-Fee) / 2.
1. Megkaptuk az R-kódot:
2. A torna lezárása után a jegyek listáját párok formájában kapjuk meg: szám + cím (az a pénztárca címe, ahonnan a tornára való részvételért a díjat kifizették). Érdemes megjegyezni, hogy a címek ismétlődhetnek, ez azt jelenti, hogy egy résztvevő több jegyet vásárolt egy tornára, ami a szabályok szerint megengedett.
Küldtük a tranzakció dátumát:
3. Kértük az S-kódot: megjegyzéssel (R-kód + TXID):
RdbAiAhKhveAtR4eyTKq75noMxdcEoxbE6BvojJjM13VE 82JTMzhHM5xEA2fQ9Qscd5QAJU3DAd8nShLjdVHTer5S
4. Megkaptuk az S-kódot:
5. Meghatároztuk a nyerteseket.
6.
Eredményeként lépésről lépésre rögzítjük a nyereményjáték folyamatát a blokkláncon, amit bármikor ellenőrizhetünk. A szervező részéről a találatok manipulálása gyakorlatilag lehetetlen, legalábbis észrevétlenül már nem fog sikerülni.
határozza meg a győztest № 1
Minden_jegyek:
Index: 1 Jegy:139
Index: 2 Jegy:141
Index: 3 Jegy:143
Index: 4 Jegy:145
Index: 5 Jegy:147
Index: 6 Jegy:149
Index: 7 Jegy:151
1. bin -> hex ( bin2hex(sha256(S-kód)) ): Ri89jHB4UXZDXY6gT1m4LBDXGMTaYzHozMk4nxiuqVXdC -> 0xdaf5802953dcb27f89972e38e8900b898733f6a613e6e1c6c5491362c1832596
2. hex -> gmp szám: 0xdaf5802953dcb27f89972e38e8900b898733f6a613e6e1c6c5491362c1832596 -> 99037963059744689166154019807924045947962565922868104113173478160267437352342
3. gmp -> modulo (mod=7): 99037963059744689166154019807924045947962565922868104113173478160267437352342 -> 4
4. modulo -> jegy: 4 -> 145
határozza meg a győztest № 2
Minden_jegyek:
Index: 1 Jegy:139
Index: 2 Jegy:141
Index: 3 Jegy:143
Index: 4 Jegy:147
Index: 5 Jegy:149
Index: 6 Jegy:151
1. bin -> hex ( bin2hex(sha256(előző hex)) ): daf5802953dcb27f89972e38e8900b898733f6a613e6e1c6c5491362c1832596 -> 0x9560e77525e9ea2db92cdb8484dc52046ccafac7c719b8859ff55f0eb92834a0
2. hex -> gmp szám: 0x9560e77525e9ea2db92cdb8484dc52046ccafac7c719b8859ff55f0eb92834a0 -> 67565829218838067182838043983962684143266386786567427968312120473742580659360
3. gmp -> modulo (mod=6): 67565829218838067182838043983962684143266386786567427968312120473742580659360 -> 1
4. modulo -> jegy: 1 -> 139
Vége.Forrás: habr.com
