Lição: 134: Construindo um Contrato de Votação
Nesta aula, aprenderemos como construir um contrato de votação simples em Solidity. Contratos de votação são uma aplicação essencial de contratos inteligentes, permitindo uma forma transparente e inviolável de coletar e rastrear votos em várias propostas.
Conceitos Chave
Antes de mergulharmos no código, vamos revisar alguns conceitos importantes:
- Variáveis de Estado: Variáveis que mantêm o estado do contrato.
- Structs: Tipos de dados personalizados que podem agrupar diferentes tipos de dados.
- Mappings: Um armazenamento de chave-valor que nos ajuda a gerenciar dados de forma eficiente.
- Modificadores: Funções que modificam o comportamento de outras funções.
Estrutura do Contrato
Aqui está uma visão geral de como nosso contrato de votação será estruturado:
- Teremos candidatos para os quais os usuários poderão votar.
- Cada usuário poderá votar apenas uma vez.
- O contrato contabilizará os votos e fornecerá uma forma de verificar os resultados.
Implementação
Vamos começar a implementar nosso contrato de votação passo a passo.
Passo 1: Definir o Contrato e as Variáveis de Estado
Começaremos criando nosso contrato, definindo variáveis de estado para armazenar os candidatos, os votos e se um eleitor já votou.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract Votacao {
struct Candidato {
uint id;
string nome;
uint contagemVotos;
}
mapping(uint => Candidato) public candidatos;
mapping(address => bool) public eleitores;
uint public contagemCandidatos;
constructor() {
adicionarCandidato("Alice");
adicionarCandidato("Bob");
}
function adicionarCandidato(string memory _nome) private {
contagemCandidatos++;
candidatos[contagemCandidatos] = Candidato(contagemCandidatos, _nome, 0);
}
}
Passo 2: Implementar a Funcionalidade de Votação
Em seguida, implementaremos uma função que permite aos usuários votarem em um candidato. Vamos garantir que um usuário possa votar apenas uma vez.
function votar(uint _idCandidato) public {
require(!eleitores[msg.sender], "Você já votou.");
require(_idCandidato > 0 && _idCandidato <= contagemCandidatos, "ID de candidato inválido.");
eleitores[msg.sender] = true;
candidatos[_idCandidato].contagemVotos++;
}
Passo 3: Recuperar Resultados
Nós também queremos fornecer uma maneira de recuperar o total de votos para cada candidato.
function obterCandidato(uint _idCandidato) public view returns (uint, string memory, uint) {
require(_idCandidato > 0 && _idCandidato <= contagemCandidatos, "ID de candidato inválido.");
Candidato memory candidato = candidatos[_idCandidato];
return (candidato.id, candidato.nome, candidato.contagemVotos);
}
function obterTotalVotos() public view returns (uint) {
uint total;
for (uint i = 1; i <= contagemCandidatos; i++) {
total += candidatos[i].contagemVotos;
}
return total;
}
Código Completo do Contrato
Colocando tudo junto, aqui está o contrato de votação completo:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract Votacao {
struct Candidato {
uint id;
string nome;
uint contagemVotos;
}
mapping(uint => Candidato) public candidatos;
mapping(address => bool) public eleitores;
uint public contagemCandidatos;
constructor() {
adicionarCandidato("Alice");
adicionarCandidato("Bob");
}
function adicionarCandidato(string memory _nome) private {
contagemCandidatos++;
candidatos[contagemCandidatos] = Candidato(contagemCandidatos, _nome, 0);
}
function votar(uint _idCandidato) public {
require(!eleitores[msg.sender], "Você já votou.");
require(_idCandidato > 0 && _idCandidato <= contagemCandidatos, "ID de candidato inválido.");
eleitores[msg.sender] = true;
candidatos[_idCandidato].contagemVotos++;
}
function obterCandidato(uint _idCandidato) public view returns (uint, string memory, uint) {
require(_idCandidato > 0 && _idCandidato <= contagemCandidatos, "ID de candidato inválido.");
Candidato memory candidato = candidatos[_idCandidato];
return (candidato.id, candidato.nome, candidato.contagemVotos);
}
function obterTotalVotos() public view returns (uint) {
uint total;
for (uint i = 1; i <= contagemCandidatos; i++) {
total += candidatos[i].contagemVotos;
}
return total;
}
}
Conclusão
Nesta aula, construímos um contrato de votação simples que permite que os usuários votem em candidatos e visualizem os resultados. Aprendemos sobre a importância das variáveis de estado, mappings e como lidar com interações simples de usuários usando funções.
Sinta-se à vontade para expandir este contrato adicionando mais recursos, como a capacidade de encerrar a votação, ou implementando funcionalidade para permitir apenas endereços específicos a criar candidatos. Boa programação!