Os aplicativos descentralizados (dApps) revolucionaram a forma como interagimos com redes blockchain e contratos inteligentes. Para permitir uma comunicação perfeita com a blockchain Ethereum, os desenvolvedores contam com bibliotecas especializadas como ethers.js e web3.js. Neste artigo, explorarei as funcionalidades, as diferenças e o uso prático dessas duas bibliotecas JavaScript populares para o desenvolvimento de dApps. Seja você um desenvolvedor experiente ou um novato no espaço blockchain, este guia tem como objetivo fornecer a você uma compreensão abrangente do ethers.js e do web3.js e como aproveitar o poder deles para seu próximo projeto de dApp.
Compreendendo o ethers.js
O Ethers.js surgiu como uma biblioteca avançada projetada para interagir com a blockchain Ethereum. Seus principais recursos incluem simplicidade, velocidade e _type safety _(nunca converte valores explicitamente ou implicitamente de um tipo para outro). Criado com TypeScript, o ethers.js oferece uma API intuitiva para gerenciar contas, lidar com transações e interagir com contratos inteligentes. Vamos nos aprofundar em algumas das principais funcionalidades:
Como Ethers.js vai ser usado
Gerenciamento da Conta
O Ethers.js facilita a geração de carteiras Ethereum, o acesso aos detalhes da conta e a assinatura de transações com segurança. Veja abaixo um exemplo de como criar uma carteira Ethereum usando o ethers.js:
const { ethers } = require("ethers");
const wallet = ethers.Wallet.createRandom();
console.log("Address:", wallet.address);
console.log("Private Key:", wallet.privateKey);
Processamento de Transações
O envio e o recebimento de transações é um aspecto fundamental do desenvolvimento de dApps. O Ethers.js simplifica esse processo, fornecendo aos desenvolvedores as ferramentas para criar e transmitir transações sem problemas. Veja a seguir como enviar ether de uma conta para outra:
const { ethers } = require("ethers");
const privateKey = "YOUR_PRIVATE_KEY";
const provider = ethers.getDefaultProvider("rinkeby");
const wallet = new ethers.Wallet(privateKey, provider);
const recipientAddress = "RECIPIENT_ADDRESS";
const transaction = {
to: recipientAddress,
value: ethers.utils.parseEther("1.0"), // Sending 1 ether
};
(async () => {
const tx = await wallet.sendTransaction(transaction);
console.log("Transaction hash:", tx.hash);
})();
Interação de Contratos Inteligentes
O Ethers.js aproveita as interfaces binárias de aplicativos (ABIs) de contratos inteligentes para interagir com os contratos inteligentes Ethereum. Abaixo está um exemplo de implantação de um contrato de token ERC20 simples e de interação com ele usando o ethers.js:
const { ethers } = require("ethers");
const erc20ABI = require("./path/to/erc20ABI.json");
const privateKey = "YOUR_PRIVATE_KEY";
const provider = ethers.getDefaultProvider("rinkeby");
const wallet = new ethers.Wallet(privateKey, provider);
const contractAddress = "CONTRACT_ADDRESS";
const erc20Contract = new ethers.Contract(contractAddress, erc20ABI, wallet);
// Obtém o saldo de uma conta
(async () => {
const accountAddress = "ACCOUNT_ADDRESS";
const balance = await erc20Contract.balanceOf(accountAddress);
console.log("Balance:", balance.toString());
})();
Compreendendo o web3.js
A Web3.js é outra biblioteca amplamente usada para o desenvolvimento de dApp Ethereum, endossada pela própria Fundação Ethereum. Sua versatilidade e o amplo suporte da comunidade fazem dela uma escolha popular entre os desenvolvedores. Vamos nos aprofundar em suas principais funcionalidades:
Como o web3.js vai usar<>/center
Gerenciamento da Conta
Semelhante ao ethers.js, o web3.js facilita a criação de contas, o acesso e a assinatura de transações. Veja abaixo um exemplo de como criar uma conta Ethereum usando o web3.js:
const Web3 = require("web3");
const providerUrl = "https://rinkeby.infura.io/v3/YOUR_INFURA_API_KEY";
const web3 = new Web3(providerUrl);
const account = web3.eth.accounts.create();
console.log("Address:", account.address);
console.log("Private Key:", account.privateKey);
Processamento de Transações
O Web3.js fornece uma interface JSON-RPC para o processamento de transações, permitindo que os desenvolvedores criem e executem transações com facilidade. Veja abaixo um exemplo de envio de ether de uma conta para outra usando o web3.js:
const Web3 = require("web3");
const providerUrl = "https://rinkeby.infura.io/v3/YOUR_INFURA_API_KEY";
const web3 = new Web3(providerUrl);
const privateKey = "YOUR_PRIVATE_KEY";
const senderAddress = "SENDER_ADDRESS";
const recipientAddress = "RECIPIENT_ADDRESS";
web3.eth.accounts.wallet.add(privateKey);
const tx = {
from: senderAddress,
to: recipientAddress,
value: web3.utils.toWei("1", "ether"),
};
web3.eth.sendTransaction(tx)
.on("transactionHash", (hash) => {
console.log("Transaction hash:", hash);
})
.on("receipt", (receipt) => {
console.log("Transaction receipt:", receipt);
});
Interação de Contratos Inteligentes
A interação com os contratos inteligentes da Ethereum é muito fácil com o web3.js. Abaixo está um exemplo de configuração de um objeto de contrato, chamando métodos de contrato e recebendo eventos emitidos pelo contrato:
const Web3 = require("web3");
const contractABI = require("./path/to/contractABI.json");
const providerUrl = "https://rinkeby.infura.io/v3/YOUR_INFURA_API_KEY";
const web3 = new Web3(providerUrl);
const contractAddress = "CONTRACT_ADDRESS";
const contractInstance = new web3.eth.Contract(contractABI, contractAddress);
// Chama um método de contrato
(async () => {
const result = await contractInstance.methods.someMethod().call();
console.log("Result:", result);
})();
// Ouve os eventos do contrato
contractInstance.events.SomeEvent()
.on("data", (event) => {
console.log("Event data:", event.returnValues);
})
.on("error", (error) => {
console.error("Error:", error);
});
Comparando o ethers.js e o web3.js
Tanto o ethers.js quanto o web3.js têm seus pontos fortes e casos de uso, o que os torna ferramentas valiosas para o desenvolvimento de dApps. Vamos explorar os principais fatores a serem considerados ao comparar as duas bibliotecas.
Type Safety e Projeto API:
O Ethers.js se destaca com seu suporte ao TypeScript, oferecendo type safety aprimorado e integridade de código melhorada. Para os desenvolvedores familiarizados com o TypeScript, o ethers.js oferece uma experiência de desenvolvimento mais estruturada e robusta. Por outro lado, o web3.js não oferece suporte ao TypeScript, mas sua API baseada em JavaScript permanece mais familiar para os desenvolvedores sem experiência prévia com o TypeScript.
Suporte da Comunidade e Documentação:
O web3.js conta com amplo apoio da comunidade devido ao seu endosso pela Fundação Ethereum e à sua ampla adoção. Como resultado, o web3.js tem uma abundância de recursos, tutoriais e projetos orientados pela comunidade. No entanto, o ethers.js está ganhando popularidade e tem uma comunidade ativa, com uma documentação oficial bem mantida e um crescente conteúdo contribuído pela comunidade.
Tamanho e Performance:
O Ethers.js é conhecido por seu tamanho pequeno e performance eficiente, o que o torna uma excelente opção para aplicativos em que o mínimo de espaço ocupado e o desempenho otimizado são cruciais. Em contrapartida, o web3.js é uma biblioteca mais substancial com funcionalidades adicionais, o que pode afetar a performance em determinados cenários. Os desenvolvedores precisam pesar as compensações entre os recursos e o desempenho ao fazer sua escolha.
Escolhendo a Biblioteca Certa para o dApp
A escolha da biblioteca certa para seu dApp depende de vários fatores. Considere os seguintes aspectos para tomar uma decisão fundamentada:
Complexidade do Projeto:
Para dApps relativamente simples, o ethers.js ou o web3.js podem ser adequados. No entanto, para projetos mais complexos que exigem verificação robusta de tipos e uma abordagem de desenvolvimento estruturada, o ethers.js pode ser a escolha mais adequada. Por outro lado, a vasta comunidade e os diversos casos de uso do web3.js podem ser benéficos para dApps ambiciosos e voltados para a comunidade.
Familiaridade do Desenvolvedor:
Considere o conjunto de habilidades e a familiaridade do seu time de desenvolvimento. Se a sua equipe já for proficiente em TypeScript e valorizar a type safety, o ethers.js poderá se alinhar bem à sua experiência. Por outro lado, o web3.js pode ser preferido se o seu time estiver mais confortável com o JavaScript tradicional e tiver experiência anterior com a biblioteca.
Requisitos de Desempenho:
Para aplicativos em que o desempenho é uma prioridade máxima, o tamanho pequeno e o desempenho otimizado do ethers.js podem ser a melhor opção. Por outro lado, os recursos adicionais e o ecossistema maior do web3.js podem ser vantajosos para projetos em que a performance não é a principal preocupação.
Exemplo Prático: Construindo um dApp Simples
Vamos criar um dApp de votação simplificado usando ethers.js ou web3.js. O dApp permitirá que os usuários votem em sua opção favorita e os votos serão registrados na blockchain Ethereum usando um contrato inteligente.
Pilha (stack) de Código Front-end:
▪️ HTML: O arquivo HTML para criar a estrutura básica da interface de votação.
▪️ CSS: O arquivo CSS para estilizar a interface de votação.
▪️ JavaScript: O arquivo JavaScript para interagir com o contrato inteligente Ethereum usando ou o either ethers.js ou o web3.js.
HTML (index.html):
<!DOCTYPE html>
<html>
<head>
<title>Simple Voting dApp</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<div class="container">
<h1>Vote for Your Favorite Option</h1>
<div class="options">
<button id="option1">Option 1</button>
<button id="option2">Option 2</button>
</div>
<div class="result">
<p>Option 1 Votes: <span id="votesOption1">0</span></p>
<p>Option 2 Votes: <span id="votesOption2">0</span></p>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/web3.min.js"></script>
<script src="app.js"></script>
</body>
</html>
CSS (styles.css):
body {
font-family: Arial, sans-serif;
background-color: #f7f7f7;
margin: 0;
padding: 0;
}
.container {
max-width: 600px;
margin: 0 auto;
padding: 20px;
background-color: #ffffff;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}
h1 {
text-align: center;
}
.options {
display: flex;
justify-content: center;
gap: 20px;
}
button {
padding: 10px 20px;
font-size: 16px;
cursor: pointer;
}
.result {
margin-top: 20px;
}
.result p {
margin: 0;
}
span {
font-weight: bold;
}
JavaScript (app.js):
const providerUrl = "https://rinkeby.infura.io/v3/YOUR_INFURA_API_KEY";
const web3 = new Web3(providerUrl);
const contractABI = [...]; // Substituir pela ABI de seu contrato inteligente implantado
const contractAddress = "CONTRACT_ADDRESS"; // Substitui pelo endereço de seu contrato inteligente
const votingContract = new web3.eth.Contract(contractABI, contractAddress);
const option1Button = document.getElementById("option1");
const option2Button = document.getElementById("option2");
const votesOption1Element = document.getElementById("votesOption1");
const votesOption2Element = document.getElementById("votesOption2");
option1Button.addEventListener("click", async () => {
await vote(1);
});
option2Button.addEventListener("click", async () => {
await vote(2);
});
async function vote(option) {
const accounts = await web3.eth.getAccounts();
const sender = accounts[0];
try {
const result = await votingContract.methods.vote(option).send({ from: sender });
console.log("Transaction hash:", result.transactionHash);
updateVoteCounts();
} catch (error) {
console.error("Vote error:", error);
}
}
async function updateVoteCounts() {
const option1Votes = await votingContract.methods.getVoteCount(1).call();
const option2Votes = await votingContract.methods.getVoteCount(2).call();
votesOption1Element.textContent = option1Votes;
votesOption2Element.textContent = option2Votes;
}
Pilha de Código Backend:
▪️ Solidity: O código do contrato inteligente Solidity para o mecanismo de votação.
Solidity (Voting.sol):
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract Voting {
mapping(uint256 => uint256) public voteCounts;
function vote(uint256 option) public {
require(option == 1 || option == 2, "Invalid option");
voteCounts[option]++;
}
function getVoteCount(uint256 option) public view returns (uint256) {
require(option == 1 || option == 2, "Invalid option");
return voteCounts[option];
}
}
Implantar o Contrato Inteligente:
👣 Compile o contrato inteligente do Solidity (Voting.sol) usando o compilador Solidity.
👣 Implante o contrato inteligente compilado na rede de teste Rinkeby usando Remix, Truffle ou Hardhat.
👣 Obtenha o endereço do contrato e a ABI após a implantação.
Substitua "YOUR_INFURA_API_KEY" por sua chave de API Infura real e "[...]" no código JavaScript pela ABI real de seu contrato inteligente implantado.
Ethers.js e web3.js são ferramentas valiosas para o desenvolvimento de dApps Ethereum, cada uma com seus pontos fortes e vantagens. Ao compreender suas funcionalidades e comparar seus recursos, você pode tomar uma decisão fundamentada ao selecionar a biblioteca que melhor atende às necessidades específicas do seu dApp. Quer você priorize a type safety, o suporte da comunidade ou o desempenho, ambas as bibliotecas oferecem soluções poderosas para a criação de aplicativos descentralizados interessantes e inovadores.
Esse artigo foi escrito por Harith D. Jayawardhane e traduzido por Fátima Lima. O original pode ser lido aqui.
Latest comments (0)