Using a random oracle on the example of a lottery

One morning I came across an article about verifiable random number generator on the Waves platform blockchain.

The general picture was clear, but the method of specific 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.

  1. At the start of the tournament/round, we ask the oracle for the first part of the code (R-code).

    At this point, there is no information either about the number of players, or about the number of prizes, or about the amount of prize payments, 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 by those who requested it. By the way, R-code can be β€œpurchased” (meaning the cost of the request transaction + compensation to the oracle for the response transaction, this is an amount of about $ 0.015 at the current exchange rate, the code itself is issued for free) in advance at once, so as not to wait for the response transaction later. I made a small regularly updated buffer in the database.

  2. The tournament usually lasts 60 blocks of the Waves platform blockchain, at the moment it is about 1 hour. The tournament is considered completed and closed if after 60 blocks there are at least two tickets in it, otherwise the tournament activity time is extended for the next 60 blocks.
  3. Immediately after the closing of the tournament, we form and send a date transaction (we also pay a commission of approximately $0.005 for it), if necessary, several, in which all the conditions of the draw are fixed and an ordered list of players (tickets) from which we need to select winners.
  4. 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 oracle for signature as a concatenation (R-code + TXID), again we pay a commission + compensation. The oracle checks the received data for uniqueness and belonging, and in response sends us the second part of the code (S-code) in the sha256 format, which is the starting point for the random number generator.
  5. To get a random number that will indicate the serial number of the winning ticket, we convert the S-code from the sha256 binary data to a hexadecimal (HEX) representation. Then from the resulting HEX string, we get a number. We get the remainder from dividing the resulting number by the number of tickets (all_tickets) and add 1 to the result (to get the number 1 before all_tickets). As a result, we get the serial number of the winner.
  6. If, according to the conditions of the drawing, 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 remove the ticket that has already won from the list and reduce all_tickets by 1, and instead of the S-code we indicate the previous number received.

Let's analyze a specific real-life example, tournament No. 119:

Only 7 tickets (all_tickets)
Ticket price 50 coins (Bet)
Game Fee 10% (Fee)

Under the terms of the lottery, 30% go to the prize money, i.e. in this case, 2 tickets must receive a prize, the amount of which is calculated according to the formula (Bet*all_tickets-Fee)/2.

1. Received R-code: RdbAiAhKhveAtR4eyTKq75noMxdcEoxbE6BvojJjM13VE

2. After the closing of the tournament, we have a list of tickets in the form of pairs: number + address (wallet address from which the payment for participation in the tournament was made). Note that addresses can be repeated, which means that one participant bought several tickets to one tournament, this is not prohibited by the rules.

Transaction date sent: 82JTMzhHM5xEA2fQ9Qscd5QAJU3DAd8nShLjdVHTer5S

3. Requested S-code: FTF3uRyaa4F2uAyD6z5a3CNbTXbQLc7fSR6CFNVjgZYV with comment (R-code + TXID):
RdbAiAhKhveAtR4eyTKq75noMxdcEoxbE6BvojJjM13VE 82JTMzhHM5xEA2fQ9Qscd5QAJU3DAd8nShLjdVHTer5S

4. Received S-code: Ri89jHB4UXZDXY6gT1m4LBDXGMTaYzHozMk4nxiuqVXdC

5. Determined the winners.

6. Sent payments

As a result, we have a step-by-step fixation of the prize drawing procedure in the blockchain with the ability to check it at any time. It is almost impossible for the organizer to rig the results, at least it will not be possible to do it imperceptibly.

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.

Source: habr.com

Add a comment