Aula 205: Implementando Sistemas de Multi-Contratos em Solidity
Nesta aula, vamos explorar como implementar sistemas de multi-contratos em Solidity. Sistemas de multi-contratos permitem uma melhor organização, modularidade e separação de preocupações em seus contratos inteligentes. Vamos criar um exemplo simples que demonstra os conceitos principais.
Compreendendo a Arquitetura de Multi-Contratos
Um sistema de multi-contratos consiste em vários contratos que podem interagir entre si. Essa arquitetura é útil para:
- Reusabilidade: Contratos podem ser reutilizados em diferentes projetos.
- Modularidade: Funções distintas podem ser organizadas em contratos separados.
- Atualizabilidade: Contratos específicos podem ser atualizados sem alterar todo o sistema.
Exemplo: Sistema de Votação com Multi-Contratos
Neste exemplo, vamos construir um sistema de votação simples que consiste em dois contratos: Votacao
e Eleitor
. O contrato Votacao
gerencia a lógica de votação, enquanto o contrato Eleitor
mantém o registro das informações dos eleitores.
Passo 1: Definindo o Contrato Eleitor
O contrato Eleitor
armazenará o endereço do eleitor e se ele já votou ou não.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract Eleitor {
struct InformacaoEleitor {
bool jaVotou;
uint256 voto;
}
mapping(address => InformacaoEleitor) public eleitores;
function registrarVoto(uint256 _idCandidato) public {
require(!eleitores[msg.sender].jaVotou, "Você já votou!");
eleitores[msg.sender].jaVotou = true;
eleitores[msg.sender].voto = _idCandidato;
}
}
Passo 2: Definindo o Contrato de Votação
O contrato Votacao
gerenciará os candidatos e coletará os votos.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "./Eleitor.sol";
contract Votacao {
struct Candidato {
string nome;
uint256 contagemVotos;
}
mapping(uint256 => Candidato) public candidatos;
Eleitor contratoEleitor;
uint256 public contagemCandidatos;
constructor(address _enderecoContratoEleitor) {
contratoEleitor = Eleitor(_enderecoContratoEleitor);
}
function adicionarCandidato(string memory _nome) public {
candidatos[contagemCandidatos] = Candidato(_nome, 0);
contagemCandidatos++;
}
function votar(uint256 _idCandidato) public {
contratoEleitor.registrarVoto(_idCandidato);
candidatos[_idCandidato].contagemVotos++;
}
}
Passo 3: Implantando os Contratos
Ao implantar esses contratos, precisamos primeiro implantar o contrato Eleitor
e depois passar seu endereço ao contrato Votacao
.
const Eleitor = artifacts.require("Eleitor");
const Votacao = artifacts.require("Votacao");
module.exports = async function (deployer) {
await deployer.deploy(Eleitor);
const instanciaEleitor = await Eleitor.deployed();
await deployer.deploy(Votacao, instanciaEleitor.address);
};
Passo 4: Interagindo com os Contratos
Agora que temos o sistema de multi-contratos configurado, vamos ver como podemos interagir com eles.
- Adicionando Candidatos
Certifique-se de chamar adicionarCandidato
do contrato Votacao
.
const instanciaVotacao = await Votacao.deployed();
await instanciaVotacao.adicionarCandidato("Alice");
await instanciaVotacao.adicionarCandidato("Bob");
- Votando
Quando um usuário vota, o contrato Votacao
chamará a função registrarVoto
do contrato Eleitor
.
const enderecoEleitor = '0x123...'; // endereço do eleitor
const idCandidato = 0; // id do candidato (Alice)
await instanciaVotacao.votar(idCandidato, { from: enderecoEleitor });
Conclusão
Nesta aula, vimos como implementar um sistema de multi-contratos em Solidity com um cenário simples de votação. Ao separar a gestão dos eleitores e a lógica da votação em dois contratos, criamos uma estrutura modular e reutilizável que pode ser facilmente estendida ou atualizada.
À medida que você construir aplicações mais complexas, considere usar uma arquitetura de multi-contratos para promover a manutenibilidade e clareza em seu código.