WEB3DEV

Cover image for Criando um Aplicativo Web3 de Caridade
Fatima Lima
Fatima Lima

Posted on • Atualizado em

Criando um Aplicativo Web3 de Caridade

Image description

No meu artigo anterior, eu abordei como criei um portal GIF na blockchain Solana usando um tutorial no Buildspace. Tenho passado os últimos meses, aprendendo como criar aplicativos Web3 e programar contratos inteligentes nas blockchains Ethereum e Solana. Agora, eu queria testar meus conhecimentos e criar meu próprio aplicativo Web3 que é simples o suficiente para eu fazer por conta própria, mas que ainda use todos os elementos de uma aplicação Web3.

Procurei vários casos de uso de contratos inteligentes e finalmente decidi pela criação de um aplicativo de caridade. Neste artigo, vou falar sobre como fiz isso nas últimas semanas, os desafios que enfrentei ao longo do caminho, assim como minha experiência geral e minhas conclusões.

Visão Geral

  • Funcionalidade/Requisitos
  • Projeto do meu aplicativo
  • Contrato Inteligente/Desenvolvimento Backend
  • Desenvolvimento Frontend
  • Desafios
  • Apresentação do Projeto
  • Demonstração
  • Próximos Passos
  • Considerações Finais

Funcionalidade/Requisitos

Para que este aplicativo de caridade tivesse sucesso, eu queria que funcionasse da seguinte maneira:

  • O usuário deve conectar sua carteira Metamask ao site antes de efetuar sua doação.
  • O usuário deve ser capaz de selecionar uma instituição de caridade de sua escolha a partir da lista de instituições de caridade disponíveis.
  • Para qualquer instituição de caridade selecionada, o usuário deve ser capaz de ver o endereço da instituição de caridade e o valor total doado através do site.
  • O usuário deve ser capaz de doar qualquer valor de ETH que desejar, desde que tenha fundos suficientes.
  • O botão para doar deve estar desativado inicialmente. O botão deve ser ativado somente se a instituição de caridade for selecionada juntamente com um valor de doação maior que zero e menor que o saldo ETH do usuário.
  • Uma vez que a doação seja realizada com sucesso, o usuário deve receber uma mensagem dizendo que sua doação foi bem sucedida e mostrar que o valor doado para a instituição de caridade aumentou.

Projeto do meu aplicativo

Quando decidi como meu aplicativo deveria funcionar, pensei em como deveria projetar o backend e o frontend.

Backend

Para o backend, escolhi escrever um contrato inteligente usando a Solidity com a blockchain Ethereum. Senti que tinha mais experiência com a Solidity e a Ethereum do que com outras opções como Rust e Solana. Além disso, a Ethereum é a blockchain mais amplamente utilizada para a construção de contratos inteligentes.

Frontend

Para o desenvolvimento do frontend, decidi mantê-lo simples e usar o React e o Hardhat. Eu queria ter uma lista de instituições de caridade, e tinha algumas opções de como fazer isso. Explorei várias opções, como usar botões de opção, criar uma lista suspensa, ou permitir que o próprio usuário digite o nome da instituição de caridade. Depois de pesar os prós e contras associados a todas estas opções do ponto de vista do projeto, decidi ficar com a lista suspensa. Esta é uma lista suspensa de instituições de caridade pré-selecionadas que seriam incorporadas no meu aplicativo.

Em relação à quantia a doar, foi uma simples decisão de fazer um campo de entrada no qual o usuário poderia inserir qualquer valor que desejasse doar.

Também precisaria de um botão de "doação" que habilitasse e desabilitasse dinamicamente, com base nas entradas do usuário.

Uma vez que pensei no visual e na essência do frontend, então precisei pensar no projeto estrutural do aplicativo que estabeleceria os componentes do React que eu precisaria. Isto me permitiria entrar no desenvolvimento de forma sistemática.

Contrato Inteligente/Desenvolvimento do Backend

No backend do meu contrato inteligente eu havia analisado várias maneiras de transferir fundos para outra conta, mas segui o que eu pensava ser a maneira mais simples.

Quando um usuário chama uma função (transferFunds), ele tem que enviar fundos junto com a chamada. O valor destes fundos é determinado pelo que o usuário coloca no campo de entrada para a quantia a ser doada à instituição de caridade. Essencialmente, esta etapa em que o usuário envia fundos com a função acontece automaticamente, portanto, não precisei escrever uma linha de código no contrato inteligente para isso.

Você pode pensar nisso, como se o contrato inteligente tivesse sua própria carteira. Quando a função é executada, os fundos são enviados primeiro para o contrato inteligente, depois, a partir daí, precisamos escrever uma linha de código para enviar os fundos do contrato inteligente to.transferir(msg.value)para o receptor, que neste caso é a instituição de caridade para a qual o usuário quis doar.

Image description

Desenvolvimento do Frontend

Achei o desenvolvimento do frontend bastante difícil, especialmente porque eu também tive que conectá-lo ao contrato inteligente ABI e ao endereço. Entretanto, usando o Remix consegui obter a ABI completa para o contrato inteligente, bem como seu endereço na testnet Rinkeby.

React

Para o frontend, decidi usar o React porque ele me ajudaria a realizar dinamicamente várias coisas que eu precisava fazer neste aplicativo. Por exemplo, ele me ajudou a programar a habilitação e desabilitação do botão doar com base nas entradas de diferentes campos, e também me ajudou a mostrar uma mensagem de sucesso quando a transação foi realizada.

Image description

Image description

Eu usei React com ganchos/componentes funcionais e não componentes de classe, porque isso proporciona uma experiência mais fácil para o desenvolvedor e faz o código parecer mais limpo. Leia mais aqui.

Desafios

Conectando a Carteira Metamask

Eu estava tendo um pouco de dificuldade para programar a lógica de verificar se uma carteira está conectada e, se não estiver, solicitar à Metamask que a conecte. Eventualmente, encontrei uma solução online sobre como fazer isso.

Image description

Aqui estou usando uma função chamada ethereum.request(). Esta função envia um pedido para verificar as contas atuais da Ethereum conectadas ao site.

Image description

Aqui, eu verifico se a lista de contas tem algo nela, e se não tem, então eu chamo a função para conectar com a carteira Metamask. Entretanto, se houver uma lista de contas devolvidas, mas a conta atual que está em uso não for a primeira da lista, então ela muda a conta atual para a primeira da lista.

Image description

Aqui, eu uso novamente a função ethereum.request() mas em vez de tentar chamar a lista de contas, ela tenta solicitar mais contas. Depois disso, ela verifica novamente se há uma conta na lista de contas. Se a Metamask não estiver no navegador, então ela verifica outras carteiras, mas se não houver carteiras Ethereum no navegador/extensões do navegador, um alerta será mostrado ao usuário.

Image description

Finalmente eu chamo a função checkIfWalletIsConnected() enquanto a página é carregada.

Image description

Se um endereço Ethereum estiver conectado ao site, ele apresentará o CharityApp.

Exibindo o Saldo Atualizado do Beneficiário de Caridade

Após a realização das doações, eu queria encontrar uma maneira de atualizar o saldo da caridade sem atualizar a página. O problema era que a lógica de saber quando a transação foi realizada estava no componente DonateButton.jsx. Então, eu precisava escrever um código que recuperasse o novo valor do saldo da Metamask e o atualizasse em Recipient.jsx , mas o problema era que os arquivos não estavam diretamente relacionados. Ao invés disso, ambos tinham um arquivo pai de CharityApp.jsx .

Então, eu tive que passar o novo saldo de DonateButton.jsx para CharityApp.jsx e para Recipient.jsx . Eis como eu superei este problema.

Image description

Ao receber uma mensagem de transação bem sucedida, solicito o novo saldo para o endereço atual do destinatário. Então, chamo uma função que passa este saldo com props (propriedades) e envia o valor para o componente pai.

Image description

Como você pode ver, em updateRecipientBalance, estou chamando uma função no arquivo CharityApp.jsx.

Image description

Depois, eu atualizo o estado chamado recipient. Conservo os mesmos valores, exceto no último campo, onde passo o novo saldo do endereço.

Image description

Em seguida, eu passo este estado como props para o meu arquivo recipient.jsx.

Image description

Finalmente, eu converto o número em base 10, porque ethereum.request({ "eth_getBalance" }) retorna um valor hexadecimal.

Habilitação/Desabilitação Automática do Botão Doação

Inicialmente, eu configurei o botão doação para ser desativado, e eu o ativaria somente se as condições abaixo fossem cumpridas.

Image description

Estas condições são:

  • É escolhida uma instituição de caridade válida (o endereço não é igual a null)
  • A quantia que o usuário deseja doar deve ser maior do que 0
  • A quantia que o usuário quer doar deve ser menor do que o saldo do usuário

O desafio nesta seção era garantir que toda a lógica fosse colocada no lugar certo, e que todos os cenários possíveis fossem incluídos.

Apresentação do Projeto

Image description

Estrutura de pastas de alto nível

Aqui está a principal estrutura de pastas do meu projeto:

  • A pasta artifacts contém todos os metadados, funções que podem ser chamadas e ABI do contrato inteligente.
  • A pasta cache contém uma lista de todos os contratos inteligentes de Solidity compilados para que eles possam ser facilmente acessados quando executados.
  • A pasta contracts contém todos os contratos inteligentes que são utilizados no aplicativo, que neste caso é apenas um.
  • A pasta node_modules contém todas as dependências que são necessárias para o projeto.
  • A pasta public contém um arquivo HTML que é fornecido por padrão.
  • A pasta scripts contém arquivos de script que podem ser usados para chamar funções diretamente do contrato inteligente.
  • A pasta src contém todos os arquivos fonte, que incluem os componentes React, assim como os arquivos do módulo CSS para alguns componentes.
  • A pasta test contém arquivos de teste para garantir que o contrato inteligente funcione como esperado.
  • O arquivo hardhat.config.js contém algumas declarações de linha de comando para facilitar o uso do Hardhat.
  • Os arquivos package-lock.json e package.json contêm detalhes de todas as dependências que estão sendo utilizadas para o projeto. No entanto, o arquivo package-lock.json é mais específico.

Image description

Aqui está um olhar mais detalhado sobre a pasta src:

  • A pasta components contém todos os componentes do React.
  • A pasta styles contém todos os arquivos do módulo CSS.
  • O arquivo index.jsé de onde começa toda a produção do React. Ele, juntamente com App.jsx, são os únicos arquivos JSX que são apresentados por padrão no projeto.

Demonstração

Próximos Passos

Embora eu tenha completado a funcionalidade básica para a aplicativo, ainda há algumas coisas em que posso trabalhar, como por exemplo:

  • Converter usando a função Wei(): Atualmente, converto de Wei para Ether, dividindo por 10¹⁸. Isto porque eu estava tendo problemas para importar a função do módulo Web3.
  • Prever o gas necessário para a transação: Atualmente, assumo que o gas total necessário para executar a transação é 0,0001 ETH. Em vez disso, eu gostaria de utilizar um número que leve em conta o gas exato necessário para a execução da transação, na instrução if que verifica todos os campos a fim de ativar o botão doar.
  • Mostrar o valor total doado: Atualmente, meu código procura o saldo do endereço do destinatário para mostrar o quanto foi doado. Entretanto, existe uma falha porque se a instituição de caridade decidir converter todo o ETH que foi doado a eles em dólares, então o saldo será reajustado para 0. Em vez disso, o que posso fazer é programar um mapeamento no lado do contrato inteligente que é atualizado a cada transação para mostrar o valor total real doado.
  • Obter o histórico de transações para um usuário ou instituição de caridade: O que eu gostaria de fazer é permitir que o usuário veja todas as doações que fez para instituições de caridade através do meu site, e também gostaria de exibir todas as doações feitas para uma determinada instituição de caridade por todos os usuários.
  • Estilo da página: Atualmente minha página utiliza o estilo básico e não é muito atraente visualmente para o usuário.

Considerações finais

Desenvolvi este aplicativo totalmente por conta própria. Isso me deu uma experiência de aprendizado significativa com o uso da Solidity para fazer um contrato inteligente, com React e Hardhat para fazer o frontend. Embora o produto final seja simples, ele me permitiu uma grande avaliação do tipo de esforço que está envolvido na construção de um aplicativo Web3 totalmente funcional. Criá-lo sozinho me deu uma enorme sensação de realização e satisfação, e me motiva a desenvolver mais com a Web3.

Se você chegou até aqui, obrigado por ler e nos vemos no próximo artigo!

Este artigo foi escrito por Sohum Padhye e traduzido por Fátima Lima. O original pode ser lido aqui.

Latest comments (0)