WEB3DEV

Cover image for Construindo um Contrato Inteligente de Sistema de Loteria com QuickNode RPC
Adriano P. Araujo
Adriano P. Araujo

Posted on

Construindo um Contrato Inteligente de Sistema de Loteria com QuickNode RPC

Pré-requisitos;

  • O que é um Sistema de Loteria?
  • Recursos-chave e componentes de um Contrato Inteligente de Sistema de Loteria.
  • Casos de uso de um Contrato Inteligente de Sistema de Loteria.
  • Como escrever um Contrato Inteligente de Sistema de Loteria.
  • Implantação com QuickNode RPC.

O QUE É UM SISTEMA DE LOTERIA?

Um sistema de loteria é uma forma de jogo de azar em que os participantes compram bilhetes ou entradas para ter a chance de ganhar um prêmio ou uma quantia em dinheiro. É um jogo de sorte, e os vencedores são selecionados aleatoriamente por meio de um sorteio ou algum outro método predeterminado.

É mais como um jogo de oportunidade e emoção em que as pessoas adquirem bilhetes ou entradas em troca de uma chance de ganhar vários prêmios ou uma quantia substancial em dinheiro. O atrativo está no elemento de imprevisibilidade, pois a seleção dos vencedores é completamente aleatória. Esse processo é realizado por meio de um sorteio ou de um método imparcial que garante a imparcialidade. Os participantes aguardam ansiosamente o sorteio, esperando que seu bilhete esteja entre os sortudos. É uma forma de entretenimento que combina a emoção da antecipação com o potencial de recompensas significativas.

RECURSOS-CHAVE E COMPONENTES DE UM CONTRATO INTELIGENTE DE SISTEMA DE LOTERIA.

  1. Gerenciamento de Bilhetes:

    • Geração de Bilhetes: O contrato gera bilhetes exclusivos para os participantes, frequentemente associados a identificadores específicos.
    • Compra de Bilhetes: Os participantes podem comprar bilhetes usando criptomoeda ou outros meios especificados.
  2. Gerenciamento de Participantes:

    • Registro: Os participantes registram seus endereços ou identidades para associá-los aos seus bilhetes.
    • Verificação: Garante que os participantes sejam elegíveis e atendam a quaisquer critérios especificados para a entrada.
  3. Prêmio Acumulado:

    • Arrecadação de Fundos: O contrato acumula os fundos das vendas de bilhetes, criando o prêmio acumulado.
    • Distribuição de Prêmios: Determina como o prêmio acumulado será distribuído (por exemplo, primeiro, segundo, terceiro lugar).
  4. Mecanismo de Sorteio:

    • Aleatoriedade: Utiliza métodos criptográficos ou oráculos para garantir uma seleção justa e imparcial dos vencedores.
    • Anúncio: Transmite os bilhetes vencedores e seus prêmios associados.
  5. Validade dos Bilhetes:

    • Vencimento: Implementa um mecanismo para a expiração de bilhetes após um período especificado.
    • Verificação: Verifica a autenticidade e a elegibilidade dos bilhetes.
  6. Transparência dos Resultados:

    • Registro Público: Fornece um registro público das vendas de bilhetes, participantes e vencedores.
    • Registro Imutável: Os resultados são registrados na blockchain para transparência e auditabilidade.
  7. Pagamentos Automatizados:

    • Verificação de Vencedores: Verifica automaticamente os bilhetes vencedores e seus endereços associados.
    • Pagamentos: Distribui os prêmios para os endereços dos participantes vencedores.
  8. Conformidade Regulatória:

    • KYC/AML: Incorpora procedimentos de Conheça Seu Cliente (KYC) e de Combate à Lavagem de Dinheiro (AML) se necessário de acordo com as regulamentações locais.
  9. Gerenciamento de Taxas:

    • Taxas de Transação: Considera quaisquer taxas associadas à compra de bilhetes e distribuição de prêmios.
  10. Ciclo de Vida do Evento:

    • Inicialização: Inicia a loteria, permitindo a venda de bilhetes.
    • Sorteio: Seleciona aleatoriamente os vencedores e distribui os prêmios.
    • Conclusão: Encerra a loteria, impedindo a compra de bilhetes adicionais.
  11. Segurança e Salvaguardas:

    • Controle de Acesso: Define funções e permissões para funções a fim de evitar acesso não autorizado.
    • Tratamento de Erros: Incorpora mecanismos para lidar com casos excepcionais ou situações errôneas.
  12. Medidas de Emergência:

    • Pausa e Retomada: Permite a suspensão temporária da loteria em caso de circunstâncias inesperadas.

CASOS DE USO DE UM CONTRATO INTELIGENTE DE SISTEMA DE LOTERIA.

  1. Loterias Beneficentes:

    • Organizações sem fins lucrativos podem usar contratos inteligentes para realizar loterias de caridade transparentes e automatizadas, cujas receitas vão para uma causa.
  2. Captação de Recursos para Projetos:

    • Startups ou projetos podem organizar loterias para arrecadar capital para desenvolvimento ou iniciativas específicas.
  3. Distribuição de Tokens:

    • Projetos de blockchain podem usar sistemas de loteria para distribuição justa e descentralizada de tokens entre membros da comunidade.
  4. Mecanismo de Recompensa:

    • Plataformas ou aplicativos podem usar loterias como uma maneira gamificada de distribuir recompensas ou incentivos aos usuários.
  5. Venda de Ingressos para Eventos:

    • Organizadores de eventos podem usar contratos de loteria para vender ingressos limitados para eventos de alta demanda, garantindo justiça no acesso.
  6. Leilões:

    • Sistemas de loteria podem ser usados como um mecanismo exclusivo para alocar itens de edição limitada ou colecionáveis.
  7. Recompensas para Funcionários:

    • Empresas podem usar loterias para o envolvimento dos funcionários, recompensando desempenho excepcional ou marcos.
  8. Distribuição de Ativos Tokenizados:

    • Ativos do mundo real, como propriedades ou itens de luxo, podem ser distribuídos entre detentores de tokens por meio de sistemas de loteria.
  9. Pesquisas ou Feedback Incentivados:

    • Organizações podem usar loterias para incentivar a participação em pesquisas ou mecanismos de feedback.
  10. Jogos e Entretenimento:

    • Plataformas de jogos podem utilizar loterias para distribuir ativos dentro do jogo, itens especiais ou até mesmo acesso a eventos exclusivos.
  11. Programas de Fidelidade:

    • Empresas podem implementar sistemas de loteria como parte de programas de fidelidade para recompensar consumidores ou clientes.
  12. Sorteios de Conformidade e Regulamentação:

    • As loterias podem ser usadas para selecionar indivíduos ou entidades para tarefas relacionadas à conformidade, como auditorias ou inspeções.
  13. Educação e Bolsas de Estudo:

    • Instituições educacionais ou programas de bolsas de estudo podem usar loterias para conceder bolsas de estudo ou subsídios.
  14. Construção de Comunidades:

    • Comunidades online ou fóruns podem usar loterias para envolver os membros e oferecer incentivos para a participação.
  15. Promoções e Campanhas de Marketing:

    • Empresas podem usar loterias como parte de campanhas promocionais para envolver os clientes e aumentar a conscientização da marca.

ESCREVENDO UM CONTRATO INTELIGENTE DE LOTERIA.

Ei, chega de fundamentos, é hora de entrar no aspecto técnico!

Abaixo está o código de um contrato inteligente de loteria;

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract LotterySystem {
address public manager; // Endereço do gerente que inicia a loteria
address[] public players; // Array para armazenar endereços dos participantes

event LotteryWinner(address winner, uint256 prize); // Evento emitido quando um vencedor é escolhido

constructor() {
    manager = msg.sender; // Define o criador do contrato como o gerente inicial
}

modifier onlyManager() {
    require(msg.sender == manager, "Apenas o gerente pode chamar esta função");
    _;
}

function enter() public payable {
    require(msg.value > .01 ether, "Contribuição mínima é de 0,01 ether"); // Requer uma contribuição mínima de 0,01 ether

    players.push(msg.sender); // Adiciona o endereço do participante ao array de jogadores
}

function random() private view returns (uint256) {
    return uint256(keccak256(abi.encodePacked(block.difficulty, block.timestamp, players))); // Gera um número pseudoaleatório com base nos dados do bloco e endereços dos jogadores
}

function pickWinner() public onlyManager restricted {
    uint256 index = random() % players.length; // Gera um índice aleatório dentro do intervalo do array de jogadores
    address winner = players[index]; // Obtém o endereço do vencedor
    uint256 prize = address(this).balance; // Obtém o saldo atual do contrato (prêmio acumulado)

    (bool success, ) = winner.call{value: prize}(""); // Transfere o prêmio acumulado inteiro para o vencedor
    require(success, "Transferência falhou"); // Garante que a transferência seja bem-sucedida

    emit LotteryWinner(winner, prize); // Emite um evento para anunciar o vencedor

    // Redefine o array de jogadores para a próxima rodada
    players = new address[](0);
}

modifier restricted() {
    require(msg.sender == manager, "Apenas o gerente pode chamar esta função");
    _;
}

function getPlayers() public view returns (address[] memory) {
    return players; // Retorna o array de participantes
}

function getManager() public view returns (address) {
    return manager; // Retorna o endereço do gerente
}
}
Enter fullscreen mode Exit fullscreen mode

Uma explicação detalhada do código:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract LotterySystem {
address public manager; // Endereço do gerente que inicia a loteria
address[] public players; // Array para armazenar os endereços dos participantes

event LotteryWinner(address winner, uint256 prize); // Evento emitido quando um vencedor é escolhido

constructor() {
    manager = msg.sender; // Define o criador do contrato como o gerente inicial
}
}
Enter fullscreen mode Exit fullscreen mode
  • pragma solidity ^0.8.0;: Isso especifica que o código-fonte deve ser compilado usando uma versão do compilador Solidity igual ou superior a 0.8.0.
  • contract LotterySystem { ... }: Isso define um novo contrato inteligente chamado LotterySystem.
  • address public manager;: Isso cria uma variável pública chamada manager do tipo address, que armazenará o endereço do gerente que inicia a loteria.
  • address[] public players;: Isso cria um array público e dinâmico chamado players do tipo address, que armazenará os endereços dos participantes.
  • event LotteryWinner(address winner, uint256 prize);: Isso declara um evento chamado LotteryWinner com dois parâmetros - winner do tipo address e prize do tipo uint256. Eventos são usados para registrar informações que podem ser acessadas externamente a partir da blockchain.
  • constructor() { ... }: Esta é a função construtora. Ela é executada apenas uma vez quando o contrato é implantado. Neste caso, ela define a variável manager como o endereço que implanta o contrato.
modifier onlyManager() {
        require(msg.sender == manager, "Only manager can call this function");
        _;
    }
Enter fullscreen mode Exit fullscreen mode
  • modifier onlyManager() { ... }: Isso define um modificador chamado onlyManager. Modificadores são usados para alterar o comportamento das funções. Este modificador restringe o acesso às funções apenas ao gerente.
  • require(msg.sender == manager, "Only manager can call this function");: Isso verifica se o endereço que chama a função (msg.sender) é igual ao endereço do gerente. Se não for, ele gera uma exceção com a mensagem "Apenas o gerente pode chamar esta função".
  • _ ;: Este é um espaço reservado para o código real da função. Indica onde o código da função modificada será executado.
function enter() public payable {
        require(msg.value > .01 ether, "Minimum contribution is 0.01 ether"); // Requer uma contribuição mínima de 0.01 ether

        players.push(msg.sender); // Adiciona os endereços dos participantes para o array players
    }
Enter fullscreen mode Exit fullscreen mode
  • function enter() public payable { ... }: Isso define uma função chamada enter. Ela pode ser chamada por qualquer pessoa e permite que o chamador participe na loteria ao enviar ether com a transação.
  • require(msg.value > .01 ether, "Minimum contribution is 0.01 ether");: Isso verifica se o valor enviado com a transação (msg.value) é maior do que 0,01 ether. Se não for, gera uma exceção com a mensagem "Contribuição mínima é de 0,01 ether".
  • players.push(msg.sender);: Isso adiciona o endereço do chamador (msg.sender) ao array players.

function random() private view returns (uint256) {
        return uint256(keccak256(abi.encodePacked(block.difficulty, block.timestamp, players))); // Gera um número pseudoaleatório com base nos dados do bloco e nos endereços dos jogadores.
    }
Enter fullscreen mode Exit fullscreen mode
  • function random() private view returns (uint256) { ... }: Isso define uma função privada chamada random que retorna um uint256. Usa a palavra-chave view para indicar que não modifica variáveis de estado.
  • keccak256(...): Esta é uma função de hash criptográfico que gera um número hexadecimal de 256 bits (32 bytes).
  • abi.encodePacked(...): Essa função compacta seus argumentos de forma eficiente para fins de hash.
  • block.difficulty: Esta é uma propriedade do bloco atual que representa a dificuldade do algoritmo de prova de trabalho usado.
  • block.timestamp: Esta é uma propriedade do bloco atual que representa o timestamp (marca de tempo) do bloco.
  • players: Este é um array de endereços de jogadores, o que contribui para tornar o resultado pseudoaleatório.
function pickWinner() public onlyManager restricted {
    uint256 index = random() % players.length; // Gera um índice aleatório dentro do intervalo do array de jogadores
    address winner = players[index]; // Obtém o endereço do vencedor
    uint256 prize = address(this).balance; // Obtém o saldo atual do contrato (prêmio acumulado)

    (bool success, ) = winner.call{value: prize}(""); // Transfere o valor total do prêmio acumulado para o vencedor
    require(success, "Transfer failed"); // Certifica se a transferência foi  bem-sucedida

    emit LotteryWinner(winner, prize); // Emite um evento para anunciar o vencedor

    // Redefine o array de jogadores para a próxima rodada
    players = new address[](0);
}

Enter fullscreen mode Exit fullscreen mode
  • function pickWinner() public onlyManager restricted { ... }: Isso define uma função chamada pickWinner. Ela pode ser chamada apenas pelo gerente e está restrita pelo modificador restricted.
  • uint256 index = random() % players.length;: Isso gera um índice aleatório dentro do intervalo do array de players.
  • address winner = players[index];: Isso obtém o endereço do vencedor com base no índice gerado aleatoriamente.
  • uint256 prize = address(this).balance;: Isso obtém o saldo atual (prêmio acumulado) do contrato.
  • (bool success, ) = winner.call{value: prize}("");: Isso envia o valor total do prêmio acumulado para o endereço do vencedor e captura se a chamada foi bem-sucedida na variável success.
  • require(success, "Transfer failed");: Isso verifica se a transferência foi bem-sucedida. Se não foi, gera uma exceção com a mensagem "Transferência falhou".
  • emit LotteryWinner(winner, prize);: Isso emite um evento para anunciar o vencedor e o valor do prêmio.
  • players = new address[](0);: Isso redefine o array de players para a próxima rodada.
modifier restricted() {  
require(msg.sender == manager, "Only manager can call this function");  
_;  
}
Enter fullscreen mode Exit fullscreen mode
  • modifier restricted() { ... }: Isso define um modificador chamado restricted. Ele restringe o acesso a certas funções apenas ao gerente.
function getPlayers() public view returns (address[] memory) {  
return players; // Retorna um array de participantes
}
Enter fullscreen mode Exit fullscreen mode
  • function getPlayers() public view returns (address[] memory) { ... }: Isso define uma função chamada getPlayers que retorna um array de endereços.
function getManager() public view returns (address) {  
return manager; //Retorna o endereço do gerente  
}  
}
Enter fullscreen mode Exit fullscreen mode
  • function getManager() public view returns (address) { ... }: Isso define uma função chamada getManager que retorna o endereço do gerente.

Este contrato cria um sistema de loteria básico onde os participantes podem entrar enviando uma contribuição mínima de 0,01 ether. O gerente pode escolher um vencedor e o valor total do prêmio é transferido para o vencedor. O contrato também mantém o registro dos participantes e do endereço do gerente.

Vamos escrever este código em nosso ambiente de desenvolvimento REMIX.



IMPLEMENTAÇÃO COM QUICKNODE RPC.

PASSO 1.

Crie um novo nó Sepolia na QuickNode. Você terá que navegar até o Painel de Controle da QuickNode e clicar em "Create".


Em seguida, certifique-se de clicar na cadeia Ethereum. Verifique uma captura de tela abaixo:


Clique em Sepolia

Depois clique em "continue" para seguir. Finalmente clique em "create endpoint" para acessar sua url Sepolia

PASSO 2

Clique em "Add network". Siga as instruções sobre como adicionar a url RPC a sua carteira no navegador.

Clique em “Add network manually”.

PASSO 3

Digite um nome (qualquer um) já que você está usando o QuickNode, você pode usar 'QKN'; copie/cole seu ponto de extremidade Web3 (certifique-se de incluir a barra final "/"), insira o ChainID e clique em "Save".

Estamos usando a Sepolia Testnet, então é aconselhável usar o Chain ID da Sepolia, que é '11155111'.

Finalmente , você pode obter o resultado abaixo.

Perfeito! Estamos quase terminando. Agora vamos solicitar um pouco de Ether da Sepolia Testnet para que possamos implantar nosso contrato inteligente.

PASSO 4

Agora, para obter taxas de gás, vamos usar https://faucet.quicknode.com/drip. Abaixo está o procedimento.

Em seguida, conecte a carteira e obtenha algum Ether.

Após fazer isso, você receberá o resultado abaixo:

Com isso, estamos prontos para implantar nosso contrato inteligente de loteria.

Implantando o código do contrato inteligente na rede de teste Sepolia.

Clique em 'confirmar' para finalizar as transações.

Conclusão

Parabéns por criar com sucesso seu próprio contrato inteligente de loteria na rede Ethereum!

Assine anewsletter da QuickNode para obter mais artigos e guias sobre Ethereum. Se tiver algum feedback, sinta-se à vontade para entrar em contato conosco pelo Twitter. Você também pode conversar conosco em nosso servidor de comunidade no Discord, que apresenta alguns dos desenvolvedores mais legais que você já conheceu :)


Este artigo foi escrito por Playboi.eth e traduzido por Adriano P. de Araujo. O original em inglês pode ser encontrado aqui.

Top comments (0)