Използването на случайно оракул на примера на лотарията

Някое утро ми попада статия за проверявания генератор на случайни числа на блокчейн платформата Waves.

Общата картина беше ясна, но начинът на конкретната реализация — не. Какви са тези кодове, подписи, какво, къде, защо?

След няколко консултации с автора на оракула, успяхме да обединим логиката на томболата (реализирана на PHP) с алгоритъма за получаване на случайно число.

  1. В момента на започване на турнира/рунда, искаме от оракула първата част на кода (R-code).

    В този момент няма информация нито за броя на играчите, нито за броя на наградните места, нито за размера на наградите и изобщо за съществуването на лотарията. Оракулът чрез трансакция предоставя персонален случайно код, който може да бъде използван само веднъж и само от този, който го е поискал. Между другото, R-code може да бъде "закупен" (става дума за разходите по трансакцията на заявка + компенсация на оракула за отговорната трансакция, това е сума около $0.015 по текущия курс, самият код се предоставя безплатно) предварително в няколко екземпляра, за да не се чака получаването на отговорната трансакция. Направих малък регулярно попълващ се буфер в базата данни.

  2. Турнирът трае стандартно 60 блока на блокчейн платформата Waves, което в момента е около 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. Изпратихме плащания

В резултат на това имаме в блокчейн стъпкова фиксация на процедурата за теглене на наградите с възможност да я проверим по всяко време. Фалшифицирането на резултатите от страна на организатора е практически невъзможно, поне в незабележим вид вече няма да бъде възможно.

определете победителя № 1

Всички_билети:
Индекс: 1 Билет:139
Индекс: 2 Билет:141
Индекс: 3 Билет:143
Индекс: 4 Билет:145
Индекс: 5 Билет:147
Индекс: 6 Билет:149
Индекс: 7 Билет:151

1. bin -> hex ( bin2hex(sha256(S-код)) ): Ri89jHB4UXZDXY6gT1m4LBDXGMTaYzHozMk4nxiuqVXdC -> 0xdaf5802953dcb27f89972e38e8900b898733f6a613e6e1c6c5491362c1832596

2. hex -> gmp число: 0xdaf5802953dcb27f89972e38e8900b898733f6a613e6e1c6c5491362c1832596 -> 99037963059744689166154019807924045947962565922868104113173478160267437352342

3. gmp -> модуло (mod=7): 99037963059744689166154019807924045947962565922868104113173478160267437352342 -> 4

4. модуло -> билет: 4 -> 145

определете победителя № 2

Всички_билети:

Индекс: 1 Билет:139
Индекс: 2 Билет:141
Индекс: 3 Билет:143
Индекс: 4 Билет:147
Индекс: 5 Билет:149
Индекс: 6 Билет:151

1. bin -> hex ( bin2hex(sha256(предишен hex)) ): daf5802953dcb27f89972e38e8900b898733f6a613e6e1c6c5491362c1832596 -> 0x9560e77525e9ea2db92cdb8484dc52046ccafac7c719b8859ff55f0eb92834a0
2. hex -> gmp число: 0x9560e77525e9ea2db92cdb8484dc52046ccafac7c719b8859ff55f0eb92834a0 -> 67565829218838067182838043983962684143266386786567427968312120473742580659360
3. gmp -> модуло (mod=6): 67565829218838067182838043983962684143266386786567427968312120473742580659360 -> 1
4. модуло -> билет: 1 -> 139

Край.

Източник: habr.com

Купете надежден хостинг за сайтове с защита от DDoS, VPS VDS сървъри 🔥 Купете надежден хостинг за сайтове с защита от DDoS, VPS VDS сървъри | ProHoster