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

Uma manhã, um artigo sobre o gerador de números aleatórios testado na blockchain da plataforma Waves chamou minha atenção.

O quadro geral era compreensível, mas o método de implementação específica não era. Quaisquer códigos, assinaturas, o que, onde, por quê?

Algumas consultas com o autor do oráculo, como resultado, combinou a lógica do sorteio (implementada em PHP) com um algoritmo para obter um número aleatório.

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

    No momento, não há informações sobre o número de jogadores, nem sobre o número de prêmios, nem sobre o tamanho dos pagamentos dos prêmios e, geralmente, sobre a existência de uma loteria. O oráculo através de uma transação emite um código aleatório pessoal, que no futuro pode ser usado apenas uma vez e apenas para quem o solicitou. A propósito, o código R pode ser "comprado" (referindo-se ao custo da transação de solicitação + compensação da Oracle para a transação de resposta, este é um valor da ordem de US $ 0,015 na taxa atual, o próprio código é emitido gratuitamente) antecipadamente de uma só vez, para não esperar que a transação de resposta seja recebida posteriormente. Criei um pequeno buffer atualizado regularmente no banco de dados.
  2. O torneio dura por padrão com 60 blocos da blockchain da plataforma Waves, no momento em que é cerca de 1 hora. Um torneio é considerado suspenso e fechado se, após 60 blocos, houver pelo menos dois ingressos, caso contrário, o tempo de atividade do torneio será estendido para os próximos 60 blocos.
  3. Imediatamente após o encerramento do torneio, formamos e enviamos a data da transação (também pagamos uma comissão de aproximadamente US $ 0,005), se necessário, alguns, nos quais todas as condições do sorteio são registradas e uma lista ordenada de jogadores (bilhetes) dos quais precisamos escolher os vencedores.
  4. Nesse estágio, já temos a primeira parte do código (código R) mais o ID da data da transação (TXID). Nós os enviamos ao oráculo para assinatura na forma de concatenação (código R + TXID), novamente pagamos uma comissão + compensação. O oracle verifica os dados em busca de exclusividade e pertencimento 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 ticket vencedor, convertemos o código S de dados binários sha256 em uma representação hexadecimal (HEX). A partir da sequência HEX resultante, obtemos um número. Obtemos o restante da divisão do número resultante pelo número de tickets (all_tickets) e adicionamos ao resultado 1 (para obter o número 1 em all_tickets). Como resultado, obtemos o número de série do vencedor.
  6. Se houver vários vencedores nos termos do sorteio, repetimos as operações anteriores em um valor igual ao número de prêmios. Ao mesmo tempo, cada vez que excluímos o ticket que já ganhamos na lista, reduzimos o all_tickets em 1 e, em vez do código S, indicamos o número anterior recebido.

Vamos analisar um exemplo concreto da vida real, torneio nº 119:

Apenas 7 ingressos (all_tickets)
Preço do bilhete 50 moedas (Aposta)
Taxa do jogo 10% (taxa)

De acordo com as condições da loteria, 30% recebem o prêmio, ou seja, nesse caso, 2 bilhetes devem receber um prêmio cujo tamanho é calculado usando a fórmula (Bet * all_tickets-Fee) / 2.

1. Código R recebido: RdbAiAhKhveAtR4eyTKq75noMxdcEoxbE6BvojJjM13VE

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

Data de 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 no blockchain uma fixação passo a passo do processo de sorteio com a capacidade de verificá-lo a qualquer momento. É quase impossível manipular os resultados do organizador, pelo menos não vai funcionar silenciosamente.

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: https://habr.com/ru/post/pt454102/


All Articles