Introdução
Neste artigo, mergulharemos na arquitetura das Aplicações Descentralizadas Web3, ou DApps, e você também terá a oportunidade de construir uma com um tutorial bônus no final.
Até agora, você provavelmente já ouviu falar da Web3 e seu potencial para revolucionar a internet como a conhecemos. A demanda por DApps Web3 está aumentando continuamente ao longo do tempo. Uma compreensão aprofundada das aplicações Web3 e como elas funcionam será sem dúvida útil para os desenvolvedores à medida que eles constroem a internet do futuro.
Os DApps são executados na blockchain como parte de uma rede distribuída ou descentralizada ponto a ponto (peer-to-peer). Os participantes da rede, também conhecidos como nós, estão conectados em público e muitas vezes em código aberto, visando reduzir a influência do controle centralizado sobre a rede.
Três Componentes Principais
A internet que moldou nossas vidas modernas, para melhor ou para pior, até a chegada da tecnologia blockchain, é conhecida como Web2. Ela é comumente referida como a web de leitura e escrita, e sua arquitetura consiste em três componentes principais:
Frontend – A interface do usuário (UI) de uma aplicação. Consiste em elementos como menus de navegação, barras laterais e outros elementos visíveis ao usuário final. O frontend de uma aplicação pode ser escrito em HTML, CSS e JavaScript, ou qualquer outro framework como React, Vue e Angular.
Backend – Onde a lógica subjacente da aplicação é definida. É usado para realizar tarefas como autenticação, notificações e praticamente qualquer forma de automação que você possa imaginar. O backend da aplicação é normalmente escrito em Python, Go ou Ruby.
Database – Um lugar de armazenamento para todos os seus dados. Este é o lugar onde a aplicação mantém e busca informações do usuário e outros dados operacionais relevantes. Você encontrará MongoDB, SQL e MariaDB como algumas das opções de banco de dados mais usadas.
A Arquitetura Web3
Os DApps, por outro lado, no entanto, têm uma arquitetura completamente diferente que consiste em uma gama mais ampla de elementos. E até o final deste artigo, você deve ter adquirido um entendimento muito mais profundo das aplicações Web3 e de como elas funcionam.
Então, comecemos com o componente frontend.
Frontend dos DApps
Tanto os frontends da Web2 quanto da Web3 têm características semelhantes. Normalmente, os desenvolvedores usam as mesmas linguagens web (HTML, CSS e JavaScript) e frameworks (React, Angular, etc.) para construir o frontend de um DApp como fariam para um aplicativo web padrão. Mesmo assim, existem outros aspectos que diferem quando se trata de funcionalidade. À medida que avança neste artigo, você ganhará uma compreensão mais profunda de como esses componentes funcionam.
Figura 1: Processo de interação do DApp
Blockchain
Ao contrário de suas contrapartes Web3, as aplicações Web2 dependem de servidores ou bancos de dados centralizados para armazenar dados. Estes podem ser, por exemplo, AWS, Google Cloud Platform e Microsoft Azure, como algumas das alternativas mais notáveis.
Em vez de redes centralizadas, a tecnologia blockchain é usada para criar aplicativos em uma máquina de estado distribuída ou descentralizada. A operação bem-sucedida de tal máquina é suportada pelos próprios nós que participam da rede. Mas, ao contrário das redes Web2 típicas, há um maior grau de anonimato e descentralização a ser encontrado aqui.
Uma blockchain é uma estrutura de dados que armazena um estado particular, como saldo de carteira e dados de transação. Como o nível de descentralização é muito maior em uma estrutura de blockchain, a integridade da rede é melhor protegida de ações hostis, já que não há um ponto central de falha que detém as chaves do reino. Isso proporciona uma camada extra de segurança que torna atividades como hacking ou alteração de dados principalmente inviáveis. Além disso, os usuários da rede geralmente têm uma maior participação na governança da cadeia, pois mantêm algum nível de propriedade em vez de uma única entidade fazer isso.
Como mencionado acima, você pode armazenar dados na blockchain, mas não pode alterar ou remover nenhum dado dela, em geral.
Alguns dos protocolos de blockchain mais notáveis são Ethereum, Polygon e Optimism, entre muitos outros.
Figura 2: Processo de interação na blockchain
Contratos Inteligentes para DApps
Os contratos inteligentes fornecem a funcionalidade para os DApps Web3. Eles são programas definidos pela lógica de negócios executados na blockchain. Eles respondem a dados e executam quando um conjunto específico de condições é atendido. Os possíveis casos de uso para contratos inteligentes são robustos e eles são uma parte integral das aplicações Web3. Solidity, Vyper e Rust são linguagens comuns para contratos inteligentes.
O seguinte código mostra o exemplo de um simples contrato inteligente "Hello World" em Solidity.
// SPDX-License-Identifier: MIT
pragma solidity 0.8.13;
contract HelloWorld {
// Essa função pode ser chamada por qualquer pessoa, não altera o estado da blockchain e retorna uma string.
function sayHelloWorld() public pure returns (string memory) {
return "Hello World";
}
}
Máquina Virtual Ethereum (EVM)
A Máquina Virtual Ethereum (EVM) é o ambiente de execução de contratos inteligentes da Ethereum. Seu propósito é executar código como um programa típico, mas simultaneamente em uma ampla gama de participantes da rede. Ao fazer isso, ela se torna essencialmente um computador global que usa nós como hardware e contratos inteligentes como seu software.
Linguagens de programação de alto nível, como Solidity e Vyper, são usadas para escrever o código executável que roda na EVM. E embora o código Solidity seja legível por humanos, ele se transforma em bytecode durante as interações, para que a máquina que o lê possa processá-lo de forma mais eficiente. O ecossistema Ethereum deve todo o seu sucesso à EVM, que trouxe o conceito de dinheiro programável para o público em geral.
Você pode aprender mais sobre a EVM e os clientes Ethereum explorando nosso artigo dedicado sobre os clientes Geth e Erigon.
Figura 3: EVM por dentro de um processo de interação blockchain
Comunicação entre frontend e contrato inteligente
Ao contrário de muitos aplicativos Web2, a interface do usuário precisa interagir com um nó para se comunicar com o contrato inteligente, em vez de usar APIs REST ou GraphQL. O termo "Nó" refere-se a um computador que executa software Ethereum e se interconecta com outros nós em uma rede peer-to-peer para ajudar a protegê-la.
Encontre uma análise aprofundada do que são os nós explorando nosso guia sobre fornecedores de nós de blockchain: o que, como e por quê.
Configurar um nó por conta própria pode ser um processo muito complexo, demorado e caro. Por causa disso, provedores de nós de blockchain como o Chainstack desempenham um papel importante em aliviar os encargos de cuidar de tudo sozinho.
O Chainstack fornece nós rápidos e escaláveis como um serviço, o que permite configurar um nó em minutos e parar de se preocupar com sua manutenção. Esta é também uma das principais razões pelas quais muitos DApps notáveis escolhem executar seus serviços em plataformas como o Chainstack.
Você pode implantar um nó e acessar seu ponto de extremidade RPC em três passos simples:
1.Inscreva-se no Chainstack e configure uma conta
2.Implante um nó no Chainstack
3.Adicione o novo ponto de extremidade do nó Chainstack à sua MetaMask
Figura 4: provedor de nó dentro de um processo de interação blockchain
Os provedores fornecem pontos de extremidade de Chamada de Procedimento Remoto (RPC) e WebSocket (WSS). Os usuários podem acessar dados na blockchain e enviar transações para várias redes. Um RPC é a API mais fácil de usar para se comunicar com servidores e executar programas remotamente. Além disso, os DApps requerem nós RPC para interagir com a blockchain, tornando-os uma peça de tecnologia crítica.
Como mencionado acima, você pode ler dados da blockchain usando RPC, mas precisa assinar uma mensagem para armazenar qualquer dado na blockchain. Isso significa que os usuários devem usar sua chave privada para realizar tal operação. Aqui reside o papel de uma conta de propriedade externa, ou EOA, como a carteira MetaMask. É uma das carteiras de blockchain mais usadas, facilitando aos usuários a interação com DApps, acesso a ferramentas vitais de gerenciamento de chaves e assinatura de transações.
Geralmente, os DAPPs interagem por meio de 'bibliotecas Web3'. Essas ferramentas permitem que você use linguagens como JavaScript e Python para se comunicar com um nó e recuperar dados, interagir com métodos de contrato inteligentes e enviar transações. Usar essas bibliotecas é a maneira mais eficiente de implementar a lógica do seu DApp, ao mesmo tempo que consegue criar interfaces amigáveis ao usuário.
As bibliotecas JavaScript mais comuns são web3.js e ethers.js, enquanto a biblioteca web3.py faz isso para Python.
Figura 5: carteira dentro de um processo de interação blockchain
Armazenamento
O armazenamento também desempenha um papel vital nos DApps. No entanto, como armazenar imagens, vídeos ou qualquer outro tipo de arquivo em uma blockchain não é ideal, por ser caro e não escalável, muitos usuários usam serviços de armazenamento descentralizados como IPFS, Arweave, e outros.
O IPFS é um sistema de arquivos descentralizado para armazenar e acessar dados. O protocolo IPFS distribui e armazena dados em uma rede peer-to-peer, em vez de fazê-lo num banco de dados centralizado.
Por outro lado, o Arweave permite a criação de um banco de dados descentralizado imutável, permitindo que qualquer pessoa avalie e debata a validade dos dados. Além disso, armazena arquivos permanentemente em uma vasta rede de máquinas.
Figura 6: armazenamento dentro de um processo de interação blockchain
Embora a maioria das aplicações descentralizadas utilize essa arquitetura porque ela é adequada quando sua aplicação cresce, é difícil para blockchains como Bitcoin e Ethereum executar milhares de transações por segundo, o que as torna lentas e caras. É aqui que as soluções de camada 2 são úteis; elas ajudam a escalar a blockchain já existente.
Escalabilidade
A expressão "Camada 2", ou L2, refere-se a um protocolo baseado em uma blockchain existente e aborda os problemas de escalabilidade das blockchains da Camada 1 (L1). Existem muitas soluções de escalabilidade – cadeias da camada 2 como Polygon, Optimism, e Arbitrum podem servir como uma extensão para Ethereum para aliviar sua carga de rede e tornar as transações mais rápidas e mais baratas.
Embora as cadeias da camada 2 realizariam a maior parte do trabalho desta maneira, a camada 1 ainda serve como a cadeia principal e oferece segurança adicional. Em contraste, a camada 2 oferece transações rápidas, taxas de transação baixas, e a capacidade de processar milhares de transações por segundo.
Figura 7: camada 2 dentro de um processo de interação blockchain
Construir DApps Simples
Agora que você tem uma boa compreensão da estrutura dos DApps, é hora de construir um, para que você possa obter alguma experiência prática. Desta vez você criará um usando ferramentas "vanilla" como HTML e CSS para a interface. O DApp interage com o contrato inteligente usando um arquivo JavaScript por meio da biblioteca ethers.
O DApp que você construirá aproveita as poderosas capacidades de armazenamento de dados da tecnologia blockchain, e embora este seja um projeto simples, ele ajudará você a praticar os fundamentos.
Vamos construir uma aplicação que permite aos usuários conectar sua carteira MetaMask à página, inserir uma string em uma caixa de texto, que pode ser uma palavra, número, ou frase, e salvá-la no contrato inteligente como uma variável usando a MetaMask para assinar a transação. Depois disso, apenas esse mesmo endereço pode recuperar a string salva, exibida na tela como uma caixa de alerta.
Você pode encontrar a base de código completa com explicações neste repositório do GitHub.
Requisitos
Antes de começar, você deve considerar alguns requisitos básicos para a página da web.
Para servir a página, você pode usar um servidor Node.js simples. Então, vamos começar instalando o Node.js e a biblioteca lite-server para visualizar a página.
Siga estas instruções:
1.Instale o Node.js (download e instruções)
2.Instale o lite-server (com NPM em um terminal / prompt de comando)
npm install -g lite-server
Agora, você tem as ferramentas para servir uma página web no localhost.
1.Crie um novo diretório de projeto, clone o repositório ou crie cada arquivo separadamente e cole o código manualmente
2.Sirva a página web via terminal / prompt de comando a partir do diretório que tem o arquivo index.html nele e execute:
lite-server
Agora, sua página da web estará disponível em http://127.0.0.1:3000/, e você pode visualizá-la e usá-la a partir do seu navegador.
Como ambiente de desenvolvimento, eu recomendo o uso do Visual Studio Code.
O Contrato Inteligente
Finalmente, é hora de mergulhar no código. Vamos começar com o contrato inteligente. A lógica é simples:
- Um mapeamento associa o endereço que salva a string com ele
- Uma função chamada saveString recebe uma string como parâmetro e salva a string no mapeamento associando-a ao endereço que chama a função
- Uma função chamada getString que permite recuperar a string salva
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract SaveString {
// este mapeamento (mapping) permite associar um endereço a uma string
mapping(address => string) public savedStrings;
// Função para salvar uma string no mapeamento com o endereço chamando a função
function saveString(string memory _string) public {
savedStrings[msg.sender] = _string;
}
// Função para recuperar uma string do mapeamento, com base em qual endereço está chamando
function getString() public view returns(string memory) {
return savedStrings[msg.sender];
}
}
Crie um arquivo chamado SaveString.sol no diretório do projeto. Para simplificar, você pode testar e implantar o contrato inteligente usando o Remix IDE. Você encontrará uma seção dedicada a isso no repositório. Em um ambiente mais avançado, você pode usar um framework de desenvolvimento de contrato inteligente como Foundry ou Hardhat, Brownie ou Ape.
Se você não quiser implantar um novo contrato, pode usar o contrato inteligente que já implantamos e verificamos na rede de teste Fantom.
Para interagir com ele, você precisará de alguns tokens de teste Fantom (FTM); você pode obtê-los na torneira (faucet) Fantom.
A Interface (Front-end)
Depois de configurar o contrato inteligente, podemos prosseguir e construir a interface. Como mencionei, vamos construí-la com as ferramentas básicas.
Comece criando um arquivo HTML chamado index.html e cole o seguinte código nele.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" type="text/css" href="./style.css" />
<script src="https://cdn.ethers.io/lib/ethers-5.2.umd.min.js" type="application/javascript"></script>
<script src="script.js"></script>
<title>Save a string on the blockchain</title>
</head>
<body>
<div class="parent">
<div class="div1">
<h1 class="center">Save a word on the blockchain</h1>
<h2 class="center">This DApp allows you to save a word, a sentence, or a code on the blockchain.</h2>
<p>Blockchain technology is more than just DeFi applications, the possibilities are endless, and this website was created to demonstrate that. Blockchains are a great system to store information.</p>
<p>The smart contract linked to this website allows an address to store a sentence, can be a word, a code, or anything else you would like to save. And only that same address can retrieve and read that information.</p>
<p class="center">Smart contract address <a href="https://testnet.ftmscan.com/address/0x0287f57a1a17a725428689dfd9e65eca01d82510#code" target="_blank">0x0287f57A1a17a725428689dfD9E65ECA01d82510</a>, on the Fantom Testnet</p>
<p class="center">Get some test FTM here: <a href="https://faucet.fantom.network/" target="_blank">Test FTM faucet</a></p>
<h3 class="center">Warning!</h3>
<p><b>Keep in mind that this DApp is created for educational purposes, it is not designed with any security measure, and because of the blockchain's nature, everyone can see the information you pass through the functions. You should avoid storing actual sensitive information, the idea is just to show a use case.</b></p>
<p class="center">Any time you save a new string from the same address, the previous one is overwritten!</p>
<p class="center">The areas to interact with are divided by very distinct colors.</p>
</div>
<div class="div2">
<h3>Click the button to connect MetaMask to the website</h3>
<button onclick="connect()">Connect Wallet</button>
</div>
<div class="div3"><label>Input sentence to save </label>
<input type="text" id="input" /><br>
<button onclick="saveString()">Save Sentence</button>
</div>
<div class="div4"> <label>Get your sentence back</label>
<button onclick="getString()">Retrieve Sentence</button><br>
</div>
</div>
</div>
</body>
</html>
Se você olhar na seção <head>
, notará esta linha:
<script src="https://cdn.ethers.io/lib/ethers-5.2.umd.min.js" type="application/javascript"></script>
Isso injeta a biblioteca ethers.js diretamente no navegador sem instalar dependências extras. Note que isso é bom para nosso ambiente de teste/aprendizado. No entanto, não é recomendado fazer isso em ambientes de produção, pois pode expor alguns riscos de segurança.
Também importamos o arquivo script.js e o arquivo style.css, que iremos construir a seguir.
<script src="script.js"></script>
<link rel="stylesheet" type="text/css" href="./style.css" />
O <body>
do arquivo HTML mantém a estrutura da página. Este exemplo é simples no geral; tem alguns parágrafos explicando o DApp, um campo de entrada e três botões.
O Estilo
A interface já estaria totalmente funcional, então esta parte é tecnicamente opcional, mas podemos adicionar algum estilo para torná-la mais organizada. Por favor, note que o meu estilo é o oposto do sofisticado. Isso é proposital, pois quero destacar principalmente as diferentes seções.
No diretório do projeto, crie um arquivo chamado style.css e cole o seguinte:
body {
text-align: left;
font-family: Arial, Helvetica, sans-serif;
}
.center {
text-align: center;
}
.parent {
display: grid;
grid-template-columns: repeat(2, 1fr);
}
.div1 {
grid-area: 1 / 1 / 2 / 3;
}
.div2 {
grid-area: 2 / 1 / 3 / 3;
background-color: #FFD700;
height: 120px;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
}
.div3 {
grid-area: 3 / 1 / 4 / 2;
background-color: DodgerBlue;
height: 150px;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
}
.div4 {
grid-area: 3 / 2 / 4 / 3;
background-color: Tomato;
height: 150px;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
}
button {
width: 150px;
padding: 8px;
border-radius: 10px;
}
label {
padding: 20px;
}
Isso aplicará o estilo à página, e se você tentar executá-la em seu navegador, a página ficará assim.
Você pode servir no navegador executando lite-server no terminal.
A Lógica do JavaScript
Agora é a hora da parte importante, até agora, temos uma interface funcional, mas todos esses botões bonitos ainda não fazem nada. Vamos consertar isso.
Crie um arquivo chamado script.js e cole este código:
// Endereço do contrato inteligente
const contractAddress = "0x0287f57a1a17a725428689dfd9e65eca01d82510";
// ABI do contrato inteligente
const contractABI = [{
"inputs": [{
"internalType": "string",
"name": "_string",
"type": "string"
}],
"name": "saveString",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "getString",
"outputs": [{
"internalType": "string",
"name": "",
"type": "string"
}],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [{
"internalType": "address",
"name": "",
"type": "address"
}],
"name": "savedStrings",
"outputs": [{
"internalType": "string",
"name": "",
"type": "string"
}],
"stateMutability": "view",
"type": "function"
}
]
// Identifique as contas e conecte a MetaMask ao site.
async function connect() {
const provider = new ethers.providers.Web3Provider(window.ethereum, "any");
// Solicitar ao usuário a conexão da conta
await provider.send("eth_requestAccounts", []);
// definir o endereço de assinatura das transações (conta selecionada)
const signer = provider.getSigner();
console.log("Account:", await signer.getAddress());
// criar instância de contrato inteligente usando endereço e ABI
smartContract = new ethers.Contract(
contractAddress,
contractABI,
signer);
}
// chame a função saveString do contrato inteligente, use o campo de entrada como parâmetro
async function saveString() {
const string = document.getElementById("input").value;
smartContract.saveString(string);
}
// chame a função getString do contrato inteligente
async function getString() {
const getSPromise = smartContract.getString();
const string = await getSPromise;
alert("Your saved string is: " + string);
}
Observe que o endereço do contrato inteligente aqui é o mesmo que o contrato que já implantamos na rede de testes Fantom. Portanto, substitua-o pelo endereço do seu contrato inteligente se você o reimplantou.
Aqui você usará a biblioteca ethers.js para "conectar" o contrato inteligente à sua interface.
A primeira seção inicializa o endereço do contrato e a ABI. ABI significa Interface Binária de Aplicativo (Application Binary Interface) e você precisa dela para poder interagir com um contrato inteligente. A ABI descreve variáveis e funções no contrato, então a biblioteca ethers sabe o que fazer com suas instruções.
Você pode encontrar a ABI no Remix se o usou para compilar o contrato. Se você usou um framework como o Hardhat, ele gerou um arquivo ABI quando você compilou o contrato inteligente.
Fig. Localização da ABI no Remix IDE
A primeira função permite que a página se conecte à MetaMask e a use para interagir com o contrato inteligente. Nesse caso, ele injeta um provedor chamado 'window.ethereum' no navegador para que você possa usar a MetaMask.
Em seguida, você tem as duas funções para salvar a string na cadeia e recuperá-la. Novamente, o repositório tem uma explicação mais detalhada de como essas funções funcionam.
Este foi o último passo! Agora, a estrutura do seu projeto deve parecer algo assim:
Project’s directory
|
|_ index.html
|_ style.css
|_ script.js
|_ SaveString.sol
Note que o arquivo do contrato inteligente não precisa estar no diretório, mas todos os outros arquivos precisam.
Agora, sirva a página com lite-server e brinque com sua nova criação.
1.Clique em Connect Wallet e siga as instruções na MetaMask
2.Insira a informação que você quer salvar no contrato inteligente, que pode ser uma palavra, um número ou uma frase
3.Clique em Save Sentence
e complete a transação com a MetaMask
4.Clique em Retrieve Sentence
para mostrar um alerta na tela contendo a palavra que você salvou daquele endereço
Tente salvar várias palavras de diferentes endereços, para que você possa ver como cada informação salva é baseada no endereço!
Observe que, se você usar o contrato inteligente já implantado, precisará usar a rede de testes Fantom e garantir que sua carteira tenha a rede de testes Fantom selecionada.
Conclusão
Isso é tudo para este artigo. Espero que agora você tenha uma boa compreensão das aplicações Web3 e de como elas funcionam. Você também passou algum tempo construindo um DApp real usando uma estrutura básica.
O próximo passo seria aprender mais sobre a construção de DApps usando ferramentas como React e Next.js!
👋 Obrigado por ler; vejo você na próxima vez.
Esse artigo é uma tradução feita por @bananlabs. Você pode encontrar o artigo original aqui
Top comments (0)