Usando um oráculo aleatório usando o exemplo de uma loteria

Certa manhã, encontrei um artigo sobre gerador de números aleatórios verificável no blockchain da plataforma Waves.

O quadro geral era claro, mas o método de implementação específico não. Alguns códigos, assinaturas, o quê, onde, por quê?

Várias consultas ao autor do oráculo, como resultado, foi possível combinar a lógica de desenho (implementada em PHP) com um algoritmo para obtenção de um número aleatório.

  1. No início do torneio/rodada, solicitamos a primeira parte do código (código R) ao oráculo.

    No momento, não há informações sobre o número de apostadores, o número de premiações, o valor do pagamento dos prêmios ou a existência da loteria em geral. O oráculo, por meio de uma transação, emite um código aleatório pessoal, que poderá então ser utilizado apenas uma vez e somente por quem o solicitou. A propósito, o código R pode ser “comprado” (ou seja, o custo da transação de solicitação + compensação ao oráculo pela transação de resposta, este é um valor de cerca de US$ 0.015 na taxa atual, o código em si é emitido gratuitamente ) várias vezes com antecedência, para não esperar posteriormente o recebimento da transação de resposta. Criei um pequeno buffer atualizado regularmente no banco de dados.

  2. O torneio costuma durar 60 blocos do blockchain da plataforma Waves, no momento é de aproximadamente 1 hora. O torneio é considerado concluído e encerrado se após 60 blocos contiver pelo menos dois ingressos, caso contrário o tempo de atividade do torneio é estendido para os próximos 60 blocos.
  3. Imediatamente após o encerramento do torneio, geramos e enviamos uma transação de data (também pagamos uma comissão de aproximadamente $ 0.005 por isso), se necessário, várias, nas quais ficam registradas todas as condições do sorteio e uma lista ordenada de jogadores (ingressos) a partir do qual precisamos selecionar os vencedores.
  4. Nesta fase já temos a primeira parte do código (código R) mais o ID da data da transação (TXID). Enviamos para assinatura ao oráculo em forma de concatenação (código R + TXID), novamente pagamos comissão + compensação. O oráculo verifica a exclusividade e pertencimento dos dados recebidos e, em resposta, nos envia a segunda parte do código (código S) no formato sha256, que é o ponto de partida para o gerador de números aleatórios.
  5. Para obter um número aleatório que indicará o número de sequência do bilhete vencedor, convertemos o código S dos dados binários sha256 em uma representação hexadecimal (HEX). Então, da string HEX resultante, obtemos um número. Obtemos o restante da divisão do número resultante pelo número de ingressos (all_tickets) e adicionamos 1 ao resultado (para obter o número 1 antes de all_tickets). Como resultado, obtemos o número de série do vencedor.
  6. Se, de acordo com as condições do sorteio, houver vários vencedores, repetimos as operações anteriores em valor igual ao número de lugares premiados. Neste caso, cada vez retiramos da lista um bilhete que já ganhou e reduzimos all_tickets em 1, e em vez do código S indicamos o número anterior recebido.

Vejamos um exemplo real específico, o torneio nº 119:

Total de 7 ingressos (all_tickets)
O bilhete custa 50 moedas (aposta)
Taxa de jogo 10% (Taxa)

De acordo com as condições do sorteio, 30% vai para o prêmio em dinheiro, ou seja, neste caso, 2 bilhetes deverão receber um prêmio, cujo valor é calculado de acordo com a fórmula (Aposta*todos_ingressos-Taxa)/2.

1. Código R recebido: RdbAiAhKhveAtR4eyTKq75noMxdcEoxbE6BvojJjM13VE

2. Após o encerramento do torneio, temos uma lista de ingressos em forma de pares: número + endereço (endereço da carteira a partir da qual foi feito o pagamento pela participação no torneio). Observe que os endereços podem ser repetidos, isso significa que um participante comprou vários ingressos para um torneio; isso não é proibido pelas regras.

Data da transação enviada: 82JTMzhHM5xEA2fQ9Qscd5QAJU3DAd8nShLjdVHTer5S

3. Código S solicitado: FTF3uRyaa4F2uAyD6z5a3CNbTXbQLc7fSR6CFNVjgZYV com comentário (código R + TXID):
RdbAiAhKhveAtR4eyTKq75noMxdcEoxbE6BvojJjM13VE 82JTMzhHM5xEA2fQ9Qscd5QAJU3DAd8nShLjdVHTer5S

4. Código S recebido: Ri89jHB4UXZDXY6gT1m4LBDXGMTaYzHozMk4nxiuqVXdC

5. Os vencedores foram determinados.

6. Pagamentos enviados

Como resultado, temos um registro passo a passo do procedimento de sorteio do prêmio no blockchain com a possibilidade de verificá-lo a qualquer momento. É quase impossível para o organizador manipular os resultados; pelo menos, não será mais possível fazê-lo despercebido.

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.

Fonte: habr.com

Adicionar um comentário