Неяк раніцай на вочы трапіўся артыкул пра
Агульная карціна была зразумелая, а вось спосаб канкрэтнай рэалізацыі - не. Нейкія коды, подпісы, што, куды, навошта?
Некалькі кансультацый у аўтара аракула, у выніку атрымалася аб'яднаць логіку розыгрышу (рэалізаваная на PHP) з алгарытмам атрымання выпадковага ліку.
- У момант старту турніру/раўнда мы запытваем у аракула першую частку кода (R-code).
У гэты момант няма інфармацыі ні пра колькасць гульцоў, ні пра колькасць прызавых месцаў, ні пра памер прызавых выплат і ўвогуле пра існаванне латарэі. Аракул праз транзакцыю выдае персанальны выпадковы код, які ў далейшым можа быць выкарыстаны толькі адзін раз і толькі тым, хто яго запытаў. Дарэчы, R-code можна «закупіць» (маецца на ўвазе кошт транзакцыі запыту + кампенсацыя аракулу за транзакцыю ў адказ, гэта сума парадку $ 0.015 па бягучым курсе, сам код выдаецца бясплатна) загадзя адразу некалькі, каб потым не чакаць атрымання транзакцыі ў адказ. Я зрабіў невялікі рэгулярна папаўняецца буфер у БД.
- Турнір доўжыцца стандартна 60 блокаў блокчейна Waves platform, на дадзены момант гэта прыкладна 1 гадзіну. Турнір лічыцца адбыўшымся і закрытым, калі пасля 60 блокаў у ім будзе не менш за два білеты, інакш час актыўнасці турніру прадаўжаецца на наступныя 60 блокаў.
- Адразу пасля закрыцця турніру мы фарміруем і адпраўляем дата транзакцыю (за яе таксама плацім камісію прыкладна $0.005), пры неабходнасці - некалькі, у якой зафіксаваны ўсе ўмовы розыгрышу і спарадкаваны спіс гульцоў (білетаў) з якога нам неабходна выбраць пераможцаў.
- На дадзеным этапе ў нас ужо ёсць першая частка кода (R-code) плюс ID дата транзакцыі (TXID). Мы дасылаем іх на подпіс аракулу ў выглядзе канкатэнацыі (R-code + TXID), зноў плацім камісію+кампенсацыю. Аракул правярае атрыманыя дадзеныя на прадмет унікальнасці і прыналежнасці, а ў адказ пасылае нам другую частку кода (S-code) у фармаце sha256, якая і з'яўляецца адпраўной кропкай для генератара выпадковых лікаў.
- Каб атрымаць выпадковы лік, які будзе паказваць на парадкавы нумар які перамог квітка, мы пераўтвараем S-code з бінарных дадзеных sha256 у шаснаццацірычную (HEX) паданне. Затым з атрыманага HEX радка, атрымліваем лік. Атрымліваем рэшту ад дзялення атрыманага ліку на колькасць квіткоў (all_tickets) і дадаем да выніку 1 (каб атрымаць лічбу 1 да all_tickets). У выніку мы атрымліваем парадкавы нумар пераможцы.
- Калі па ўмовах розыгрышу пераможцаў некалькі, то паўтараем папярэднія аперацыі ў колькасці роўнай колькасці прызавых месцаў. Пры гэтым кожны раз выдаляем са спісу квіток які ўжо выйграў і памяншаем all_tickets на 1, а замест S-code паказваем папярэдні атрыманы лік.
Разбяром канкрэтны рэальны прыклад, турнір №119:
Усяго 7 білетаў (all_tickets)
Кошт білета 50 манет (Bet)
Гульнявы збор 10% (Fee)
Па ўмовах латарэі 30% трапляюць у прызавыя, г.зн. у дадзеным выпадку 2 квіткі павінны атрымаць прыз, памер якога лічыцца па формуле (Bet*all_tickets-Fee)/2.
1. Атрымалі R-code:
2. Пасля закрыцця турніру маем спіс білетаў у выглядзе пар: нумар + адрас (адрас кашалька з якога была аплата ўдзелу ў турніры). Заўважым, што адрасы могуць паўтарацца, гэта азначае, што адзін удзельнік набыў некалькі квіткоў у адзін турнір, гэта не забараняецца правіламі.
Адправілі дата транзакцыю:
3. Запыталі S-code:
RdbAiAhKhveAtR4eyTKq75noMxdcEoxbE6BvojJjM13VE 82JTMzhHM5xEA2fQ9Qscd5QAJU3DAd8nShLjdVHTer5S
4. Атрымалі S-code:
5. Вызначылі пераможцаў.
У выніку мы маем у блокчейне пакрокавую фіксацыю працэдуры розыгрышу прызоў з магчымасцю праверыць яе ў любы час. Падтасаваць вынікі з боку арганізатара практычна немагчыма, прынамсі зрабіць гэта незаўважна ўжо не атрымаецца.
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.
Крыніца: habr.com