Ús d'un oracle aleatori amb l'exemple d'una loteria

Un matí em vaig trobar amb un article sobre generador de números aleatoris verificable a la cadena de blocs de la plataforma Waves.

El panorama general era clar, però el mètode d'implementació específic no ho era. Alguns codis, signatures, què, on, per què?

Diverses consultes amb l'autor de l'oracle, com a resultat, es va poder combinar la lògica de dibuix (implementada en PHP) amb un algorisme per obtenir un nombre aleatori.

  1. A l'inici del torneig/ronda, demanem a l'oracle la primera part del codi (codi R).

    En aquest moment, no hi ha informació sobre el nombre de jugadors, el nombre de places de premi, la mida del pagament dels premis o l'existència de la loteria en general. L'oracle, a través d'una transacció, emet un codi personal aleatori, que després només pot ser utilitzat una vegada i només per qui ho sol·liciti. Per cert, el codi R es pot "comprar" (és a dir, el cost de la transacció de sol·licitud + compensació a l'oracle per la transacció de resposta, es tracta d'un import d'uns 0.015 dòlars a la tarifa actual, el codi en si s'emet gratuïtament). ) diverses vegades per endavant, per no esperar la recepció de la transacció de resposta més endavant. Vaig fer un petit buffer actualitzat regularment a la base de dades.

  2. El torneig acostuma a durar 60 blocs de la cadena de blocs de la plataforma Waves, de moment és d'aproximadament 1 hora. El torneig es considera finalitzat i tancat si després de 60 blocs hi ha almenys dues entrades, en cas contrari el temps d'activitat del torneig s'allarga als 60 blocs següents.
  3. Immediatament després del tancament del torneig, generem i enviem una transacció de data (també paguem una comissió d'aproximadament 0.005 $ per això), si cal, diverses, en què es registren totes les condicions del sorteig i una llista ordenada de jugadors (entrades). entre els quals hem de seleccionar els guanyadors.
  4. En aquesta fase, ja tenim la primera part del codi (codi R) més l'identificador de la data de la transacció (TXID). Els enviem per signar a l'oracle en forma de concatenació (codi R + TXID), de nou paguem una comissió + compensació. L'oracle comprova la singularitat i la pertinença de les dades rebudes i, com a resposta, ens envia la segona part del codi (codi S) en format sha256, que és el punt de partida del generador de números aleatoris.
  5. Per obtenir un número aleatori que indicarà el número de seqüència del bitllet guanyador, convertim el codi S de les dades binàries sha256 a una representació hexadecimal (HEX). Aleshores, a partir de la cadena HEX resultant, obtenim un número. Obtenim la resta de dividir el nombre resultant pel nombre de bitllets (all_tickets) i sumem 1 al resultat (per obtenir el número 1 abans de all_tickets). Com a resultat, obtenim el número de sèrie del guanyador.
  6. Si, segons les condicions del sorteig, hi ha diversos guanyadors, repetim les operacions anteriors en una quantitat igual al nombre de places de premi. En aquest cas, cada vegada que eliminem de la llista un bitllet que ja hagi guanyat i reduïm all_tickets en 1, i en comptes del codi S indiquem el número anterior rebut.

Vegem un exemple real concret, el torneig núm. 119:

Total de 7 entrades (all_tickets)
El bitllet costa 50 monedes (aposta)
Comissió del joc 10% (Comissió)

Segons les condicions de la loteria, el 30% es destina al premi en metàl·lic, és a dir. en aquest cas, 2 entrades han de rebre un premi, la mida del qual es calcula segons la fórmula (Aposta*all_tickets-Fee)/2.

1. Codi R rebut: RdbAiAhKhveAtR4eyTKq75noMxdcEoxbE6BvojJjM13VE

2. Després del tancament del torneig, tenim una llista d'entrades en forma de parelles: número + adreça (l'adreça de la cartera des de la qual es va fer el pagament de la participació al torneig). Tingueu en compte que les adreces es poden repetir, això significa que un participant ha comprat diverses entrades per a un torneig, això no està prohibit per les regles.

Data d'enviament de la transacció: 82JTMzhHM5xEA2fQ9Qscd5QAJU3DAd8nShLjdVHTer5S

3. Codi S sol·licitat: FTF3uRyaa4F2uAyD6z5a3CNbTXbQLc7fSR6CFNVjgZYV amb comentari (codi R + TXID):
RdbAiAhKhveAtR4eyTKq75noMxdcEoxbE6BvojJjM13VE 82JTMzhHM5xEA2fQ9Qscd5QAJU3DAd8nShLjdVHTer5S

4. Codi S rebut: Ri89jHB4UXZDXY6gT1m4LBDXGMTaYzHozMk4nxiuqVXdC

5. Es van determinar els guanyadors.

6. Pagaments enviats

Com a resultat, tenim un enregistrament pas a pas del procediment de sorteig del premi a la cadena de blocs amb la possibilitat de comprovar-ho en qualsevol moment. És gairebé impossible que l'organitzador manipuli els resultats almenys, ja no serà possible fer-ho desapercebut.

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.

Font: www.habr.com

Afegeix comentari