Title: Metodologia de Cálculo dos Sorteios Post by: Adriano on February 13, 2020, 12:25:55 AM Esse tópico visa discutir os detalhes técnicos, algoritmo e assuntos correlatos à metodologia de cálculo que adotei para os sorteios do fórum (post inicial: Sorteio de Carnaval (https://bitcointalk.org/index.php?topic=5225148.0)).
Antes de começar o detalhamento, um resumo de como será a dinâmica dos sorteios:
A seguir o detalhamento do processo, com código de exemplo para validar que a geração dos tickets e sorteio são justos:
E os passos a seguir, após a discussão inicial:
Abraço, Adriano Title: Re: Metodologia de Cálculo dos Sorteios Post by: Adriano on February 13, 2020, 11:09:11 AM Primeiro dia - Abertura de um novo sorteio
Nesse dia, será postada por mim uma mensagem com os detalhes do sorteio, contendo o número do bloco utilizado para o sorteio, valor de cada ticket, hash da sequência de caracteres que será utilizada para o cálculo do sorteio e a forma de distribuição dos valores arrecadados. Exemplo (IMPORTANTE: NÃO faça depósitos nesse endereço pois o mesmo foi utilizado em um outro sorteio (https://bitcointalk.org/index.php?topic=5210659.0) e não é válido): Sorteio baseado no bloco: 610614 Endereço para apostas: bc1qak3ruahryeplk86z697r-sf5828w-44tu6t-2ph5hqn380x43emqu83duk Valor do ticket: 0.001 BTC Hash da sequência de caracteres: 95ec1d26f124c8d08323eaae796cd75f7ac13d93caab725ac6776f721af8fea3 Distribuição dos prêmios:
Title: Re: Metodologia de Cálculo dos Sorteios Post by: Adriano on February 13, 2020, 11:09:19 AM A partir da abertura até o último dia - Apostas
Apostas podem ser feitas normalmente do momento da abertura do sorteio até 3 blocos antes do sorteio (sua transação precisa ter 3 confirmações para concorrer ao sorteio) Durante esse período, qualquer usuário pode verificar as transações recebidas no endereço de apostas e validar os tickets gerados com o script fornecido neste tópico. Title: Re: Metodologia de Cálculo dos Sorteios Post by: Adriano on February 13, 2020, 11:09:26 AM Bloco do Sorteio Gerado - Sorteio
Após a geração do bloco, eu divulgarei a sequência de caracteres utilizada em conjunto com o bloco para geração dos números ganhadores. Nesse momento, qualquer pessoa pode utilizar o script de verificação para confirmar os números ganhadores e que a sequência de caracteres corresponde ao hash informado no primeiro dia. Lembrando que se forem gerados dois ou mais blocos com o mesmo número, os blocos que ficarem orfãos não são válidos Title: Re: Metodologia de Cálculo dos Sorteios Post by: Adriano on February 13, 2020, 11:15:56 AM Como validar as apostas e sorteios
Qualquer pessoa pode utilizar o seguinte script para validar tanto as apostas quanto o sorteio. Talvez você já tenha python instalado em seu computador, pode verificar digitando python --version em um terminal. Outra alternativa é utilizar um site online, por exemplo https://repl.it/languages/python3 A seguir, o script: Code: from collections import namedtuple Para validar os tickets, é necessário fornecer o hash do bloco em que a transação foi incluída na blockchain, o hash da transação e o número de tickets a serem gerados (uma transação pode gerar mais de um ticket se for enviada uma quantidade múltipla do preço de um ticket) De acordo com o exemplo dado acima, a transação caf02fb319e38b7d6bceafcda0e6f8720ebf8dcd14a1f2632fcd7baddf85a1b1 foi incluída no bloco 608637, cujo hash é 000000000000000000054faed5985e33f3281604547ad22bd035785ca8ec20d8. O valor enviado foi 0.002 e é o equivalente a dois tickets. Rodando o script com esses parâmetros temos o seguinte resultado: Code: $ python validate_lottery.py ticket 000000000000000000054faed5985e33f3281604547ad22bd035785ca8ec20d8 caf02fb319e38b7d6bceafcda0e6f8720ebf8dcd14a1f2632fcd7baddf85a1b1 2 As linha iniciando com "0 - " e "1 - " são o que realmente importa, elas indicam o número do ticket, o valor aleatório gerado para esse ticket e ao final, após o sinal de "=", os 4 números com os quais o ticket estará concorrendo. O script fornecido anteriormente mostra em detalhe o processo de geração desses números, mas em linhas gerais: - Os hashes do bloco e da transação são combinados utilizando sha256, essa sequência de caracteres possui 32 bytes (cada 2 caracteres aqui representam um número em hexadecimal - que varia de 00 a FF). Vvamos pegar o ticket 0 como exemplo: Code: 5cc6992fc5006c21d788635354515682332e45cbaba6178bf61a8a0a5a88fd75 - A primeira linha após o ticket mostra essa divisão de 2 em 2 caracteres: Code: 5c c6 99 2f c5 00 6c 21 d7 88 63 53 54 51 56 82 33 2e 45 cb ab a6 17 8b f6 1a 8a 0a 5a 88 fd 75 Code: 92 198 153 47 197 0 108 33 215 136 99 83 84 81 86 130 51 46 69 203 171 166 23 139 246 26 138 10 90 136 253 117 Code: 28 6 25 15 5 0 12 1 23 8 3 19 20 17 22 2 19 14 5 11 11 6 23 11 22 26 10 10 26 8 29 21 Finalmente, começando do final da sequência anterior, pegamos os primeiros 4 números não repetidos, resultando nos números 21, 29, 8, 26 Para validar o sorteio, o processo é exatamente o mesmo, porém os parâmetros são o hash do bloco final, a sequência de caracteres e o hash informado no post inicial (esse hash será utilizado para confirmar que a sequência de caracteres não foi alterada. Vamos ao exemplo: Code: $ python validate_lottery.py draw 0000000000000000000465da70a3247e619e478ae45bf048e33a03a09a0f8dc2 eu-ainda-nao-sei-qual-a-palavra 95ec1d26f124c8d08323eaae796cd75f7ac13d93caab725ac6776f721af8f Veja que como eu ainda não sabia a sequência de caracteres, a validação falhou visto que o hash 95ec1d26f124c8d08323eaae796cd75f7ac13d93caab725ac6776f721af8f não corresponde ao que eu forneci ao script(eu-ainda-nao-sei-qual-a-palavra). Neste caso nenhum detalhe foi gerado sobre os números sorteados. Vamos agora tentar novamente com a sequência correta: Code: $ python validate_lottery.py draw 0000000000000000000465da70a3247e619e478ae45bf048e33a03a09a0f8dc2 4b95d84c-f41f-4eea-9f49-e7d147d4fb59 95ec1d26f124c8d08323eaae796cd75f7ac13d93caab725ac6776f721af8fea3 Desta vez recebemos a mensagem que o checksum foi validado ok (Checksum validation OK!) e logo a seguir o resultado do sorteio (números 24, 10, 28 e 12) seguidos pelo detalhamento de como o número foi gerado, da mesma maneira que para a geração dos tickets (separação 2 a 2, conversão hexadecimal -> decimal, "normalização" dos números pegando o resto da divisão por 32 e finalmente pegando os 4 números não repetidos a partir do final) Title: Re: Metodologia de Cálculo dos Sorteios Post by: Adriano on February 13, 2020, 11:16:03 AM Alguns comentários
- A escolha dos números a partir do final ou do começo não faz diferença, eu só estou utilizando a partir do final porque no plano inicial eu iria utilizar apenas o hash do bloco e os primeiros caracteres são sempre 0 (e a cada aumento de dificuldade mais caracteres são 0) - A introdução da sequência aleatória de caracteres tem dois propósitos: 1) resolver o problema da dificuldade fazendo o hash tender a 0; 2) Evitar que um alguém com recursos manipule o sorteio. Imagine que um grande minerador poderia verificar o hash gerado para o bloco ganhador e decidir não publicar aquele esperando gerar um bloco que o beneficiasse - é um cenário irreal hoje em dia, mas imagine que o pote do sorteio cresça bastante, enquanto nós sabemos que a recompensa por novos blocos diminui pela metade a cada 4 anos (210000 blocos para falar a verdade) - A quantidade de números válidos (de 0 a 31) é importante... Esse método só funciona com as seguintes opções de números válidos: (2, 4, 8, 16, 32, 64, 128 e 256). Isso porque se um número diferente for utilizado, teríamos o mesmo efeito de um dado viciado no sorteio: alguns números teriam mais chance de sair do que outros. Por exemplo, se utilizássemos 10 números, os números de 0 a 5 teriam cada um 26 chances de sair, porém de 6 a 9 teriam apenas 25 chances cada. - Tenho interesse em achar uma solução para manter a transparência e reproducibilidade (se é que isso é uma palavra válida) que permita ao apostador escolher os números, se possível incorporando lightning... sugestões são bem vindas. - As chances de acertar os 4 números são relativamente baixas, então imagino que o valor acumule com frequência. Isso fará com que os prêmios de 3 e 2 acertos fiquem bem "interessantes" rapidamente, servindo de incentivo para termos mais apostadores. Title: Re: Metodologia de Cálculo dos Sorteios Post by: Adriano on February 13, 2020, 11:16:09 AM Próximos passos
Fiquem a vontade de questionar qualquer ponto que não esteja claro... O assunto é pesado para quem não tem conhecimento de programação então qualquer dúvida vai ajudar a explicar melhor o processo... E se você quiser aproveitar a oportunidade para aprender um pouco, python é relativamente simples de aprender e o script fornecido acima tem apenas 77 linhas, sem utilizar nenhuma biblioteca externa, pode ser um bom inicio :D Caso não surja nenhum problema grave na validação da idéia proposta, o próximo passo será abrir as apostas para o primeiro sorteio, visando um bloco da quarta-feira de cinzas (pra curar a ressaca do carnaval, pelo menos para os ganhadores). Os seguintes poderiam ser: Páscoa, Tiradentes, Dia do Trabalho ou Dia das Mães (ou Bitcoin Halving que deve ser bem próximo do dia das mães). Com esses concursos já poderemos fazer algumas pequenas alterações e ver se a idéia pega. Title: Re: Metodologia de Cálculo dos Sorteios Post by: alegotardo on February 13, 2020, 12:42:50 PM Boa Adriano,
Muito bem esclarecido. Mas como eu sou burro, ainda não consegui chegar ao HEX correto ;D Com certeza tem algo que eu estou esquecendo, mesmo acompanhando o código não consegui entender e chegar ao resultado, vamos lá: Code: Hash do bloco: 000000000000000000054faed5985e33f3281604547ad22bd035785ca8ec20d8 Creio que deve ter mais algum parâmetro aí e que ele seja o número do ticket que é necessário para as apostas múltiplas, mas em nenhum dos meus testes consegui encaixar ele e obter o Hex correto. Ah, o Script tá ok... os resultados dos tickets e do raw batem com a sua explanação. O problema sou eu mesmo :P Title: Re: Metodologia de Cálculo dos Sorteios Post by: Adriano on February 13, 2020, 03:37:06 PM Boa Adriano, Muito bem esclarecido. Mas como eu sou burro, ainda não consegui chegar ao HEX correto ;D Com certeza tem algo que eu estou esquecendo, mesmo acompanhando o código não consegui entender e chegar ao resultado, vamos lá: Code: Hash do bloco: 000000000000000000054faed5985e33f3281604547ad22bd035785ca8ec20d8 Creio que deve ter mais algum parâmetro aí e que ele seja o número do ticket que é necessário para as apostas múltiplas, mas em nenhum dos meus testes consegui encaixar ele e obter o Hex correto. Ah, o Script tá ok... os resultados dos tickets e do raw batem com a sua explanação. O problema sou eu mesmo :P Oi Ale, não se preocupe. O problema é que o processo é um pouco mais complicado do que só concatenar as duas informações juntas: O processo para gerar o hash pode ser explicado como assinar uma mensagem (o hash da transação) com uma chave (o hash do bloco)... O resultado é o primeiro ticket, para gerar os demais, nós adicionamos um sequencial (1, 2, 3) ao final do hash da transação e repetimos o processo quantas vezes for necessária para gerar o número de tickets necessarios. Para o sorteio é a mesma coisa, mas ao invés da transação e bloco são utilizados o bloco e a sequência de caracteres secreta. Esse site permite você fazer o mesmo cálculo para chegar no resultado correto: https://www.freeformatter.com/hmac-generator.html (tem vários outros, esse foi o primeiro que achei numa busca rápida) Espero que tenha ficado mais claro, mas qualquer coisa dá um grito. Abraço, Adriano Title: Re: Metodologia de Cálculo dos Sorteios Post by: cryptobaboon on February 13, 2020, 06:33:07 PM Sweet! Muito bem explicado, Adriano! E, como já havia mencionado no tópico anterior, gostei da metodologia. Concordo que com o tempo algumas melhorias poderiam ser feitas (o suporte à LN e a escolha dos números que você cogitou viriam bem a calhar... apesar que neste último nunca tive muita sorte, talvez a aleatoriedade seja o melhor caminho para alguns ainda... aliás, diria até que isso é um complô para diminuir minha taxa de assertividade depois da dobradinha na virada do ano ;D).
Aproveito, ainda, e deixo a sugestão de incluir um ponto aqui (https://bitcointalk.org/index.php?topic=5225410.msg53829640#msg53829640): caso a transação não seja confirmada em tempo hábil ou a transação ocorra em um período que anteceda o anúncio de novos sorteios, o montante passaria a compor o próximo pote. Penso que esse seria o caminho natural, mas acho interessante destacar para não restarem dúvidas quando houver alguma ocorrência do gênero. Ah e espero mesmo que seja uma iniciativa de sucesso ao ponto de chegarmos no suposto cenário: (...) Imagine que um grande minerador poderia verificar o hash gerado para o bloco ganhador e decidir não publicar aquele esperando gerar um bloco que o beneficiasse (...) ;D 8) Title: Re: Metodologia de Cálculo dos Sorteios Post by: alegotardo on February 13, 2020, 08:51:23 PM ~snip~ Espero que tenha ficado mais claro, mas qualquer coisa dá um grito. Ahhh, pior que nem era tão complicado assim de entender no final das contas. Consegui replicar os resultados, script auditado e aprovado :D Quanto a escolha dos números, a única forma de fazer isso de forma transparente e automatizada seria escrevendo eles na própria blockchain, mas aí infelizmente teríamos que partir para outra Coin afim de tornar isso possível para qualquer "mortal", talvez até um SmartContract na ETH ou algo do tipo. [EDIT] Vide aqui (https://bitcointalk.org/index.php?topic=5226086) um tutorial produzido pelo @Loganota que pode cair muito bem como uma solução para a escolha dos números, ou não? Title: Re: Metodologia de Cálculo dos Sorteios Post by: Adriano on December 05, 2020, 09:14:29 PM Apenas uma pequena atualização sobre a versão final que está sendo utilizada no sorteio de fim de ano 2020 (https://bitcointalk.org/index.php?topic=5296498.0):
Ao invés de escolher os números de trás pra frente, a escolha segue a ordem normal. Abaixo o novo código para validação, onde a única alteração é a remoção da função reversed: Como validar as apostas e sorteios Qualquer pessoa pode utilizar o seguinte script para validar tanto as apostas quanto o sorteio. Talvez você já tenha python instalado em seu computador, pode verificar digitando python --version em um terminal. Outra alternativa é utilizar um site online, por exemplo https://repl.it/languages/python3 A seguir, o script: Code: from collections import namedtuple |