Выкарыстанне выпадковага аракула на прыкладзе латарэі

Неяк раніцай на вочы трапіўся артыкул пра правяраемым генератары выпадковых лікаў на блокчейне Waves platform.

Агульная карціна была зразумелая, а вось спосаб канкрэтнай рэалізацыі - не. Нейкія коды, подпісы, што, куды, навошта?

Некалькі кансультацый у аўтара аракула, у выніку атрымалася аб'яднаць логіку розыгрышу (рэалізаваная на PHP) з алгарытмам атрымання выпадковага ліку.

  1. У момант старту турніру/раўнда мы запытваем у аракула першую частку кода (R-code).

    У гэты момант няма інфармацыі ні пра колькасць гульцоў, ні пра колькасць прызавых месцаў, ні пра памер прызавых выплат і ўвогуле пра існаванне латарэі. Аракул праз транзакцыю выдае персанальны выпадковы код, які ў далейшым можа быць выкарыстаны толькі адзін раз і толькі тым, хто яго запытаў. Дарэчы, R-code можна «закупіць» (маецца на ўвазе кошт транзакцыі запыту + кампенсацыя аракулу за транзакцыю ў адказ, гэта сума парадку $ 0.015 па бягучым курсе, сам код выдаецца бясплатна) загадзя адразу некалькі, каб потым не чакаць атрымання транзакцыі ў адказ. Я зрабіў невялікі рэгулярна папаўняецца буфер у БД.

  2. Турнір доўжыцца стандартна 60 блокаў блокчейна Waves platform, на дадзены момант гэта прыкладна 1 гадзіну. Турнір лічыцца адбыўшымся і закрытым, калі пасля 60 блокаў у ім будзе не менш за два білеты, інакш час актыўнасці турніру прадаўжаецца на наступныя 60 блокаў.
  3. Адразу пасля закрыцця турніру мы фарміруем і адпраўляем дата транзакцыю (за яе таксама плацім камісію прыкладна $0.005), пры неабходнасці - некалькі, у якой зафіксаваны ўсе ўмовы розыгрышу і спарадкаваны спіс гульцоў (білетаў) з якога нам неабходна выбраць пераможцаў.
  4. На дадзеным этапе ў нас ужо ёсць першая частка кода (R-code) плюс ID дата транзакцыі (TXID). Мы дасылаем іх на подпіс аракулу ў выглядзе канкатэнацыі (R-code + TXID), зноў плацім камісію+кампенсацыю. Аракул правярае атрыманыя дадзеныя на прадмет унікальнасці і прыналежнасці, а ў адказ пасылае нам другую частку кода (S-code) у фармаце sha256, якая і з'яўляецца адпраўной кропкай для генератара выпадковых лікаў.
  5. Каб атрымаць выпадковы лік, які будзе паказваць на парадкавы нумар які перамог квітка, мы пераўтвараем S-code з бінарных дадзеных sha256 у шаснаццацірычную (HEX) паданне. Затым з атрыманага HEX радка, атрымліваем лік. Атрымліваем рэшту ад дзялення атрыманага ліку на колькасць квіткоў (all_tickets) і дадаем да выніку 1 (каб атрымаць лічбу 1 да all_tickets). У выніку мы атрымліваем парадкавы нумар пераможцы.
  6. Калі па ўмовах розыгрышу пераможцаў некалькі, то паўтараем папярэднія аперацыі ў колькасці роўнай колькасці прызавых месцаў. Пры гэтым кожны раз выдаляем са спісу квіток які ўжо выйграў і памяншаем all_tickets на 1, а замест S-code паказваем папярэдні атрыманы лік.

Разбяром канкрэтны рэальны прыклад, турнір №119:

Усяго 7 білетаў (all_tickets)
Кошт білета 50 манет (Bet)
Гульнявы ​​збор 10% (Fee)

Па ўмовах латарэі 30% трапляюць у прызавыя, г.зн. у дадзеным выпадку 2 квіткі павінны атрымаць прыз, памер якога лічыцца па формуле (Bet*all_tickets-Fee)/2.

1. Атрымалі R-code: RdbAiAhKhveAtR4eyTKq75noMxdcEoxbE6BvojJjM13VE

2. Пасля закрыцця турніру маем спіс білетаў у выглядзе пар: нумар + адрас (адрас кашалька з якога была аплата ўдзелу ў турніры). Заўважым, што адрасы могуць паўтарацца, гэта азначае, што адзін удзельнік набыў некалькі квіткоў у адзін турнір, гэта не забараняецца правіламі.

Адправілі дата транзакцыю: 82JTMzhHM5xEA2fQ9Qscd5QAJU3DAd8nShLjdVHTer5S

3. Запыталі S-code: FTF3uRyaa4F2uAyD6z5a3CNbTXbQLc7fSR6CFNVjgZYV з каментаром (R-code + TXID):
RdbAiAhKhveAtR4eyTKq75noMxdcEoxbE6BvojJjM13VE 82JTMzhHM5xEA2fQ9Qscd5QAJU3DAd8nShLjdVHTer5S

4. Атрымалі S-code: Ri89jHB4UXZDXY6gT1m4LBDXGMTaYzHozMk4nxiuqVXdC

5. Вызначылі пераможцаў.

6. Адправілі выплаты

У выніку мы маем у блокчейне пакрокавую фіксацыю працэдуры розыгрышу прызоў з магчымасцю праверыць яе ў любы час. Падтасаваць вынікі з боку арганізатара практычна немагчыма, прынамсі зрабіць гэта незаўважна ўжо не атрымаецца.

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

Дадаць каментар