Web3 e Blockchain: conceitos básicos para desenvolvedores web
1. Do Web2 ao Web3: Mudança de Paradigma
1.1. O que é Web3: descentralização, propriedade de dados e ausência de intermediários
Web3 representa a terceira geração da internet, onde o controle dos dados e a propriedade digital retornam aos usuários. Diferente do Web2, onde gigantes como Google e Facebook centralizam dados e lucram com eles, o Web3 utiliza blockchain para eliminar intermediários. Desenvolvedores web agora criam aplicações onde o usuário realmente possui seus ativos digitais, sejam tokens, NFTs ou identidades.
1.2. Diferenças fundamentais entre arquitetura cliente-servidor (Web2) e rede peer-to-peer (Web3)
No Web2, um servidor central armazena dados e processa requisições. Exemplo clássico:
// Web2: Requisição a uma API REST
fetch('https://api.exemplo.com/usuarios/123')
.then(res => res.json())
.then(console.log)
No Web3, não há servidor central. Os dados residem em milhares de nós distribuídos. A comunicação ocorre diretamente com a blockchain:
// Web3: Chamada a um contrato inteligente
const provider = new ethers.providers.Web3Provider(window.ethereum)
const contract = new ethers.Contract(enderecoContrato, abi, provider)
const dados = await contract.obterDados(123)
1.3. Papel do desenvolvedor web: de consumidor de APIs REST para interação com contratos inteligentes
O desenvolvedor web tradicional consome APIs REST ou GraphQL. No Web3, ele interage com contratos inteligentes — programas imutáveis na blockchain. A lógica de negócio migra do backend para o contrato, e o frontend se torna a interface para essa lógica descentralizada.
2. Fundamentos de Blockchain para Desenvolvedores
2.1. O que é um blockchain: blocos, hashes, cadeia imutável e consenso
Um blockchain é um livro-razão digital onde cada bloco contém transações e um hash do bloco anterior, formando uma cadeia imutável. O consenso (Proof of Work ou Proof of Stake) valida novos blocos sem necessidade de autoridade central.
Bloco 1:
Hash: 0x4f3a...
Hash anterior: 0x0000...
Transações: [tx1, tx2]
Bloco 2:
Hash: 0x9b2c...
Hash anterior: 0x4f3a...
Transações: [tx3, tx4]
2.2. Contratos inteligentes: código autoexecutável na blockchain
Contratos inteligentes são programas que rodam na blockchain. Exemplo em Solidity:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract Contador {
uint256 public valor;
function incrementar() public {
valor += 1;
}
}
2.3. Endereços, chaves públicas/privadas e carteiras
Assim como sessões e tokens JWT autenticam usuários no Web2, no Web3 a autenticação ocorre via criptografia de chave pública/privada. O endereço Ethereum (ex: 0x123...) é derivado da chave pública. A carteira (MetaMask, WalletConnect) gerencia essas chaves e assina transações.
3. Ferramentas e Ambiente de Desenvolvimento Web3
3.1. Provedores de nó: Infura, Alchemy e conexão com redes
Provedores como Infura e Alchemy oferecem acesso a nós Ethereum sem necessidade de rodar um nó próprio:
const provider = new ethers.providers.InfuraProvider('sepolia', 'SUA_API_KEY')
3.2. Bibliotecas essenciais: Ethers.js e Web3.js
Ethers.js é a biblioteca mais moderna para interagir com Ethereum:
// Provider: conexão com a blockchain
// Signer: quem assina transações (carteira)
// Contract: interface para contratos inteligentes
const provider = new ethers.providers.Web3Provider(window.ethereum)
const signer = provider.getSigner()
const contract = new ethers.Contract(endereco, abi, signer)
3.3. Wallets para navegador: MetaMask
MetaMask injeta window.ethereum no navegador. Para conectar:
async function conectarCarteira() {
if (window.ethereum) {
const contas = await window.ethereum.request({
method: 'eth_requestAccounts'
})
return contas[0]
}
}
4. Interagindo com Contratos Inteligentes a partir do Frontend
4.1. Lendo dados da blockchain: chamadas call
Chamadas call são gratuitas e apenas leem dados:
const saldo = await contract.balanceOf(enderecoUsuario)
console.log(`Saldo: ${ethers.utils.formatEther(saldo)} ETH`)
4.2. Escrevendo dados: transações send
Transações send modificam o estado e custam gas:
const tx = await contract.transfer(enderecoDestino, ethers.utils.parseEther("0.1"))
await tx.wait() // Aguarda confirmação
console.log(`Transação confirmada: ${tx.hash}`)
4.3. Eventos e logs: escutando mudanças em tempo real
Contratos emitem eventos que o frontend pode escutar:
contract.on("Transfer", (from, to, value) => {
console.log(`Transferência: ${from} -> ${to}: ${value}`)
})
5. Autenticação Descentralizada e Identidade Digital
5.1. Login com carteira (Sign-in with Ethereum — EIP-4361)
Em vez de senha, o usuário assina uma mensagem:
const mensagem = `Bem-vindo ao DApp!
Nonce: ${nonce}
Endereço: ${endereco}`
const assinatura = await signer.signMessage(mensagem)
// Enviar mensagem + assinatura para backend verificar
5.2. Recuperação de endereço e nonce para evitar replay attacks
O backend verifica a assinatura e recupera o endereço:
const enderecoRecuperado = ethers.utils.verifyMessage(mensagem, assinatura)
if (enderecoRecuperado === endereco) {
// Autenticado!
}
5.3. Diferenças práticas: session storage vs. chave pública como identificador
No Web2, usamos session storage para tokens JWT. No Web3, o identificador é o endereço público da carteira. Não há logout tradicional — a sessão dura enquanto o usuário mantiver a assinatura válida.
6. Armazenamento Descentralizado e Oráculos
6.1. IPFS e Filecoin: armazenamento de metadados e arquivos grandes
IPFS armazena arquivos de forma distribuída. Combinado com contratos:
// Upload para IPFS via Pinata ou Infura
const resultado = await ipfs.add(arquivo)
const hashIPFS = resultado.path // Ex: QmX...
// Armazenar hash no contrato
await contract.definirImagemPerfil(hashIPFS)
6.2. Oráculos (Chainlink): como trazer dados do mundo real
Oráculos conectam blockchain a dados externos:
// Contrato solicita preço ETH/USD via Chainlink
uint256 preco = await priceFeed.latestRoundData()
6.3. Combinação prática: frontend web + IPFS para imagens + contrato para ownership
// Frontend: exibe NFT armazenado no IPFS
const hash = await contract.obterTokenURI(tokenId)
const metadata = await fetch(`https://ipfs.io/ipfs/${hash}`)
const imagem = metadata.image // URL IPFS da imagem
7. Segurança, Custos e Boas Práticas para Devs Web
7.1. Gas e estimativas de custo
Cada transação custa gas, pago em ETH. Estimar custo:
const estimativa = await contract.estimateGas.transfer(endereco, valor)
console.log(`Gas estimado: ${estimativa.toString()}`)
7.2. Riscos comuns
- Reentrância: ataques que chamam o contrato repetidamente
- Front-running: bots que veem transações pendentes e as antecipam
- Validação: sempre validar no contrato, nunca apenas no frontend
7.3. Debugging e testes: Hardhat, Ganache
Hardhat permite simular blockchain local:
// hardhat.config.js
module.exports = {
networks: {
hardhat: {
chainId: 31337
}
}
}
// Teste local: npx hardhat node
Referências
- Documentação oficial Ethers.js — Biblioteca completa para interação com Ethereum no frontend e backend
- Solidity Documentation — Linguagem oficial para contratos inteligentes na Ethereum
- MetaMask Developer Docs — Guia de integração da carteira mais popular para navegadores
- Infura Documentation — Provedor de nós Ethereum com planos gratuitos para desenvolvimento
- IPFS Documentation — Sistema de arquivos distribuído para armazenamento descentralizado
- Chainlink Documentation — Rede de oráculos descentralizados para dados externos
- EIP-4361: Sign-in with Ethereum — Padrão para autenticação descentralizada via carteira
- Hardhat Documentation — Ambiente de desenvolvimento e testes para contratos inteligentes