Usando un oráculo aleatorio usando el ejemplo de una lotería

Una mañana me encontré con un artículo sobre generador de números aleatorios verificable en la cadena de bloques de la plataforma Waves.

El panorama general era claro, pero el método de implementación específico no lo era. Algunos códigos, firmas, ¿qué, dónde, por qué?

Después de varias consultas con el autor del oráculo, como resultado, fue posible combinar la lógica de dibujo (implementada en PHP) con un algoritmo para obtener un número aleatorio.

  1. Al comienzo del torneo/ronda, solicitamos la primera parte del código (código R) al oráculo.

    En este momento, no hay información sobre el número de jugadores, el número de premios, el tamaño de los pagos de premios o la existencia de la lotería en general. El oráculo, a través de una transacción, emite un código aleatorio personal, que luego puede ser utilizado una sola vez y sólo por quien lo solicitó. Por cierto, el código R se puede "comprar" (es decir, el costo de la transacción de solicitud + compensación al oráculo por la transacción de respuesta, esta es una cantidad de aproximadamente $ 0.015 al tipo de cambio actual, el código en sí se emite de forma gratuita ) varias veces por adelantado, para no esperar más tarde a recibir la transacción de respuesta. Creé un pequeño búfer actualizado periódicamente en la base de datos.

  2. El torneo suele tener una duración de 60 bloques de la blockchain de la plataforma Waves, actualmente dura aproximadamente 1 hora. El torneo se considera completado y cerrado si después de 60 bloques hay al menos dos boletos en él, en caso contrario el tiempo de actividad del torneo se extiende para los siguientes 60 bloques.
  3. Inmediatamente después del cierre del torneo, generamos y enviamos una transacción de fecha (también pagamos una comisión de aproximadamente $0.005 por ello), si es necesario, varias, en las que se registran todas las condiciones del sorteo y una lista ordenada de jugadores (boletos). del cual debemos seleccionar a los ganadores.
  4. En esta etapa, ya tenemos la primera parte del código (código R) más el ID de la fecha de la transacción (TXID). Los enviamos para que los firme al oráculo en forma de concatenación (código R + TXID), nuevamente pagamos una comisión + compensación. Oracle verifica la unicidad y pertenencia de los datos recibidos y, en respuesta, nos envía la segunda parte del código (código S) en formato sha256, que es el punto de partida para el generador de números aleatorios.
  5. Para obtener un número aleatorio que indique el número de secuencia del boleto ganador, convertimos el código S de los datos binarios sha256 a una representación hexadecimal (HEX). Luego, de la cadena HEX resultante, obtenemos un número. Obtenemos el resto de dividir el número resultante por el número de entradas (all_tickets) y sumamos 1 al resultado (para obtener el número 1 antes de all_tickets). Como resultado, obtenemos el número de serie del ganador.
  6. Si según las condiciones del sorteo hay varios ganadores, entonces repetimos las operaciones anteriores en una cantidad igual al número de plazas del premio. En este caso, cada vez eliminamos de la lista un boleto que ya ganó y reducimos all_tickets en 1, y en lugar de S-code indicamos el número anterior recibido.

Veamos un ejemplo real concreto, el torneo nº 119:

Total de 7 entradas (all_tickets)
El billete cuesta 50 monedas (apuesta)
Tarifa del juego 10% (Tarifa)

Según las condiciones de la lotería, el 30% se destina al premio en metálico, es decir en este caso, 2 boletos deben recibir un premio, cuyo tamaño se calcula según la fórmula (Bet*all_tickets-Fee)/2.

1. Código R recibido: RdbAiAhKhveAtR4eyTKq75noMxdcEoxbE6BvojJjM13VE

2. Una vez cerrado el torneo, tenemos una lista de boletos en forma de pares: número + dirección (la dirección de la billetera desde donde se realizó el pago por la participación en el torneo). Tenga en cuenta que las direcciones pueden repetirse, esto significa que un participante compró varias entradas para un torneo, esto no está prohibido por las reglas.

Fecha de envío de la transacción: 82JTMzhHM5xEA2fQ9Qscd5QAJU3DAd8nShLjdVHTer5S

3. Código S solicitado: FTF3uRyaa4F2uAyD6z5a3CNbTXbQLc7fSR6CFNVjgZYV con comentario (código R + TXID):
RdbAiAhKhveAtR4eyTKq75noMxdcEoxbE6BvojJjM13VE 82JTMzhHM5xEA2fQ9Qscd5QAJU3DAd8nShLjdVHTer5S

4. Código S recibido: Ri89jHB4UXZDXY6gT1m4LBDXGMTaYzHozMk4nxiuqVXdC

5. Se determinaron los ganadores.

6. Pagos enviados

Como resultado, tenemos un registro paso a paso del procedimiento de sorteo de premios en la cadena de bloques con la posibilidad de comprobarlo en cualquier momento. Es casi imposible que el organizador manipule los resultados; al menos, ya no será posible hacerlo desapercibido.

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.

Fuente: habr.com

Añadir un comentario