Lição: 300: Projeto Final: Desenvolvendo um DApp Completo
Nesta aula final, vamos combinar tudo o que aprendemos sobre Solidity e Ethereum para desenvolver um Aplicativo Descentralizado (DApp) completo. Passaremos por cada etapa, focando no contrato inteligente, na sua implementação e na criação de uma interface simples para interagir com nosso DApp.
Visão Geral do Projeto
Vamos criar um DApp de votação simples, onde os usuários poderão criar uma enquete e votar nela. Os principais componentes do nosso DApp incluirão:
- Contrato Inteligente: Gerencia a criação de enquetes e a contagem de votos.
- Frontend: Uma interface HTML/JavaScript simples para os usuários interagirem com o contrato inteligente.
Etapa 1: Contrato Inteligente
Vamos começar com o contrato inteligente que será responsável pela criação de enquetes e gerenciamento de votos.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract Voting {
struct Candidate {
uint id;
string name;
uint voteCount;
}
mapping(uint => Candidate) public candidates;
mapping(address => bool) public voters;
uint public candidatesCount;
string public pollQuestion;
constructor(string memory _question) {
pollQuestion = _question;
}
function addCandidate(string memory _name) public {
candidatesCount++;
candidates[candidatesCount] = Candidate(candidatesCount, _name, 0);
}
function vote(uint _candidateId) public {
require(!voters[msg.sender], "Você já votou.");
require(_candidateId > 0 && _candidateId <= candidatesCount, "ID de candidato inválido.");
voters[msg.sender] = true;
candidates[_candidateId].voteCount++;
}
function getResult() public view returns (string memory winnerName, uint winnerVoteCount) {
uint winningVoteCount = 0;
for (uint i = 1; i <= candidatesCount; i++) {
if (candidates[i].voteCount > winningVoteCount) {
winningVoteCount = candidates[i].voteCount;
winnerName = candidates[i].name;
}
}
winnerVoteCount = winningVoteCount;
}
}
Explicação:
- O contrato
Voting
permite que os criadores configurem uma enquete com candidatos. - Cada candidato é armazenado em um mapeamento com um identificador, nome e contagem de votos.
- Os usuários podem votar em candidatos e, uma vez que votam, não podem votar novamente.
- A função
getResult
permite que qualquer um verifique o vencedor da enquete.
Etapa 2: Implementando o Contrato Inteligente
Para implementar o contrato inteligente na rede Ethereum, você pode usar ferramentas como Remix ou Truffle. Aqui está um exemplo usando Truffle:
-
Instale o Truffle:
npm install -g truffle
-
Crie um novo projeto Truffle:
mkdir VotingDApp cd VotingDApp truffle init
-
Crie o contrato Voting: Salve o código Solidity acima na pasta
contracts
comoVoting.sol
. -
Crie o script de migração: Na pasta
migrations
, crie um novo arquivo2_deploy_contracts.js
:const Voting = artifacts.require("Voting"); module.exports = function (deployer) { deployer.deploy(Voting, "Quem é seu super-herói favorito?"); };
-
Compile e migre: Execute os seguintes comandos:
truffle compile truffle migrate --network development
Certifique-se de ter uma rede Ethereum local em execução, como o Ganache.
Etapa 3: Frontend
Agora vamos construir um frontend simples usando HTML e JavaScript para interagir com nosso contrato inteligente.
Estrutura HTML
<!DOCTYPE html>
<html lang="pt-BR">
<head>
<meta charset="UTF-8">
<title>DApp de Votação</title>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="https://cdn.ethereum.org/web3.js/1.3.0/web3.min.js"></script>
</head>
<body>
<h1>DApp de Votação</h1>
<div>
<h2>Criar Candidato</h2>
<input type="text" id="candidateName" placeholder="Nome do Candidato">
<button id="addCandidateBtn">Adicionar Candidato</button>
</div>
<div>
<h2>Votar</h2>
<input type="number" id="candidateId" placeholder="ID do Candidato">
<button id="voteBtn">Votar</button>
</div>
<div>
<h2>Obter Resultado</h2>
<button id="getResultBtn">Obter Resultado</button>
<p id="result"></p>
</div>
<script src="app.js"></script>
</body>
</html>
Código JavaScript (app.js)
Para interagir com nosso contrato inteligente, vamos criar um arquivo JavaScript app.js
.
let web3;
let votingContract;
$(document).ready(async () => {
if (typeof window.ethereum !== 'undefined') {
web3 = new Web3(window.ethereum);
await window.ethereum.enable();
const networkId = await web3.eth.net.getId();
// Substitua pelo endereço do seu contrato implementado
const deployedNetwork = 'YOUR_DEPLOYED_CONTRACT_ADDRESS';
votingContract = new web3.eth.Contract(Voting.abi, deployedNetwork);
$('#addCandidateBtn').click(addCandidate);
$('#voteBtn').click(vote);
$('#getResultBtn').click(getResult);
} else {
alert('Por favor, instale o MetaMask!');
}
});
async function addCandidate() {
const candidateName = $('#candidateName').val();
const accounts = await web3.eth.getAccounts();
await votingContract.methods.addCandidate(candidateName).send({ from: accounts[0] });
}
async function vote() {
const candidateId = $('#candidateId').val();
const accounts = await web3.eth.getAccounts();
await votingContract.methods.vote(candidateId).send({ from: accounts[0] });
}
async function getResult() {
const result = await votingContract.methods.getResult().call();
$('#result').text(`Vencedor: ${result[0]}, Votos: ${result[1]}`);
}
Explicação:
- Usamos o Web3.js para conectar o frontend ao nosso contrato inteligente.
- Os usuários podem adicionar candidatos, votar e visualizar os resultados através da interface.
Conclusão
Nesta aula, você desenvolveu um DApp completo do zero. Abordamos a escrita de um contrato inteligente, sua implementação em uma rede Ethereum e a construção de um frontend para os usuários interagirem com o DApp.
Sinta-se à vontade para expandir este projeto adicionando mais recursos, como:
- Permitir que os usuários criem várias enquetes.
- Armazenar os resultados das enquetes permanentemente usando eventos.
- Implementar autenticação de usuários.
Continue experimentando com DApps e isso irá aprimorar suas habilidades e compreensão da tecnologia blockchain!