One morning, I came across an article about a
checked random number generator on the Waves platform blockchain.
The overall picture was clear, but the method of concrete implementation was not. Some codes, signatures, what, where, why?
Several consultations with the author of the oracle, as a result, it turned out to combine the logic of the draw (implemented in PHP) with the algorithm for obtaining a random number.
- At the time of the start of the tournament / round, we request the first part of the code (R-code) from the oracle.
')
At this moment, there is no information about the number of players, nor about the number of prizes, nor about the size of the prize payouts and in general about the existence of the lottery. The oracle, through a transaction, issues a personal random code, which can later be used only once and only to those who have requested it. By the way, R-code can be “purchased” (meaning the cost of a request transaction + compensation to an oracle for a response transaction, this is an amount of about $ 0.015 at the current rate, the code itself is issued free of charge) in advance at once, so as not to wait for the receipt of a response transaction. I made a small regularly updated buffer in the database. - The tournament lasts a standard 60 blocks of the blockchain Waves platform, at the moment it is about 1 hour. The tournament is considered to be held and closed, if after 60 blocks there will be at least two tickets in it, otherwise the activity of the tournament is extended to the next 60 blocks.
- Immediately after the tournament is closed, we form and send a transaction date (we also pay a commission of about $ 0.005 for it), if necessary, several, which contain all the conditions of the draw and an ordered list of players (tickets) from which we need to choose the winners.
- At this stage, we already have the first part of the code (R-code) plus the transaction date ID (TXID). We send them to the signature of the oracle in the form of concatenation (R-code + TXID), again we pay a commission + compensation. The Oracle checks the data for uniqueness and belonging, and in response it sends us the second part of the code (S-code) in the sha256 format, which is the starting point for the random number generator.
- To get a random number that indicates the number of the winning ticket, we convert the S-code from the sha256 binary data into a hexadecimal (HEX) representation. Then from the resulting HEX string, we get a number. We get the remainder of dividing the resulting number by the number of tickets (all_tickets) and add 1 to the result (to get the number 1 to all_tickets). As a result, we get the serial number of the winner.
- If under the terms of the draw there are several winners, then we repeat the previous operations in an amount equal to the number of prizes. At the same time, each time we delete a ticket from the list that has already won and reduce all_tickets by 1, and instead of S-code we indicate the previous received number.
Let us examine a concrete real-life example, tournament number 119:
Total 7 tickets (all_tickets)
Ticket price 50 coins (Bet)
Game collection 10% (Fee)
Under the terms of the lottery, 30% get into the prize, ie in this case, 2 tickets must receive a prize, the size of which is calculated by the formula (Bet * all_tickets-Fee) / 2.
1. Received R-code:
RdbAiAhKhveAtR4eyTKq75noMxdcEoxbE6BvojJjM13VE2. After the tournament is closed, we have a list of tickets in the form of pairs: number + address (the address of the wallet from which payment for participation in the tournament was paid). Note that the addresses can be repeated, this means that one participant has bought several tickets in one tournament, this is not forbidden by the rules.
Sent transaction date:
82JTMzhHM5xEA2fQ9Qscd5QAJU3DAd8nShLjdVHTer5S3. Requested S-code:
FTF3uRyaa4F2uAyD6z5a3CNbTXbQLc7fSR6CFNVjgZYV with a comment (R-code + TXID):
RdbAiAhKhveAtR4eyTKq75noMxdcEoxbE6BvojJjM13VE 82JTMzhHM5xEA2fQ9Qscd5QAJU3DAd8nShLjdVHTer5S
4. Received S-code:
Ri89jHB4UXZDXY6gT1m4LBDXGMTaYzHozMk4nxiuqVXdC5. Determined the winners.
6.
Sent paymentsAs a result, we have step-by-step fixation of the prize drawing procedure in the blockchain with the ability to check it at any time. It’s almost impossible to juggle the results on the part of the organizer, at least it can’t be done inconspicuously.
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.