Sobre nós Guias Projetos Contactos
Админка
please wait

O Ethereum permite aplicações descentralizadas (dApps) através de smart contracts e de uma blockchain programável. O Web3.js disponibiliza a interface JavaScript para interagir com nós Ethereum. Este guia aborda a criação de aplicações blockchain na perspetiva de um developer sénior.

Porquê Desenvolvimento em Ethereum

O Ethereum oferece capacidades únicas:

  1. Smart Contracts: Código autoexecutável na blockchain
  2. Descentralização: Sem um único ponto de falha ou de controlo
  3. Transparência: Todas as transações verificáveis publicamente
  4. Dinheiro Programável: Criar aplicações financeiras sem intermediários
  5. NFTs e Tokens: Criar ativos digitais

Configuração do Ambiente de Desenvolvimento

Instalar Dependências

# Ambiente Node.js
npm init -y
npm install web3 ethers dotenv

Fornecedores de Infraestrutura

Utilize fornecedores como a Infura ou a Alchemy em vez de executar o seu próprio nó:

// .env
INFURA_API_KEY=your_api_key_here
PRIVATE_KEY_1=your_private_key_here
PRIVATE_KEY_2=second_private_key_here

Desenvolvimento Local com Ganache

O Ganache disponibiliza uma blockchain Ethereum local para testes:

# Instalar a CLI do Ganache
npm install -g ganache
# Iniciar blockchain local
ganache --port 8545

Noções Básicas de Web3.js

Ligar à Rede

import { Web3 } from 'web3';
import 'dotenv/config';
// Desenvolvimento vs. Produção
const isProduction = false;
const web3 = new Web3({
provider: `https://${!isProduction ? 'sepolia' : 'mainnet'}.infura.io/v3/${process.env.INFURA_API_KEY}`,
config: {
defaultTransactionType: "0x2", // Transações EIP-1559
},
});
// Verificar ligação
const blockNumber = await web3.eth.getBlockNumber();
console.log('Current block:', blockNumber);

Gestão de Contas

// Criar nova conta
const newAccount = web3.eth.accounts.create();
console.log('Address:', newAccount.address);
console.log('Private Key:', newAccount.privateKey);
// Carregar conta existente a partir de chave privada
const account = web3.eth.accounts.privateKeyToAccount(process.env.PRIVATE_KEY_1);
console.log('Loaded address:', account.address);
// Obter saldo
const balance = await web3.eth.getBalance(account.address);
console.log('Balance:', web3.utils.fromWei(balance, 'ether'), 'ETH');

Efetuar Transações

Enviar ETH

import { Web3 } from 'web3';
const isProduction = false;
const web3 = new Web3({
provider: `https://${!isProduction ? 'sepolia' : 'mainnet'}.infura.io/v3/${process.env.INFURA_API_KEY}`,
config: {
defaultTransactionType: "0x2",
},
});
// Inicializar contas
const sender = web3.eth.accounts.privateKeyToAccount(process.env.PRIVATE_KEY_1);
const receiver = web3.eth.accounts.privateKeyToAccount(process.env.PRIVATE_KEY_2);
async function sendTransaction() {
// Registar links das contas para verificação
console.log(`Sender: https://${isProduction ? '' : 'sepolia.'}etherscan.io/address/${sender.address}`);
console.log(`Receiver: https://${isProduction ? '' : 'sepolia.'}etherscan.io/address/${receiver.address}`);
// Verificar saldo
const balance = await web3.eth.getBalance(sender.address);
console.log(`Sender balance: ${web3.utils.fromWei(balance, 'ether')} ETH`);
// Obter contagem de transações (nonce)
const txCount = await web3.eth.getTransactionCount(sender.address);
// Construir transação
const txObject = {
nonce: web3.utils.toHex(txCount),
to: receiver.address,
value: web3.utils.toWei('0.001', 'ether'),
maxPriorityFeePerGas: 10_000,
maxFeePerGas: 10_000_000_000, // Custo máximo de transação permitido
};
// Assinar transação
const signedTx = await sender.signTransaction(txObject);
// Enviar transação
console.log(`TX: https://${isProduction ? '' : 'sepolia.'}etherscan.io/tx/${signedTx.transactionHash}`);
const receipt = await web3.eth.sendSignedTransaction(signedTx.rawTransaction);
console.log('Transaction confirmed in block:', receipt.blockNumber);
// Verificar novo saldo
const newBalance = await web3.eth.getBalance(receiver.address);
console.log(`Receiver balance: ${web3.utils.fromWei(newBalance, 'ether')} ETH`);
}
sendTransaction();

Interação com Smart Contracts

Compilar Smart Contract

Utilizando o compilador Solidity:

npm install solc

Contrato simples SimpleStorage.sol:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract SimpleStorage {
uint256 private storedValue;
event ValueChanged(uint256 newValue);
function set(uint256 value) public {
storedValue = value;
emit ValueChanged(value);
}
function get() public view returns (uint256) {
return storedValue;
}
}

Fazer Deploy do Contrato

import { Web3 } from 'web3';
import fs from 'fs';
import solc from 'solc';
const web3 = new Web3('http://localhost:8545'); // Ganache
// Compilar contrato
const source = fs.readFileSync('SimpleStorage.sol', 'utf8');
const input = {
language: 'Solidity',
sources: {
'SimpleStorage.sol': { content: source },
},
settings: {
outputSelection: {
'*': { '*': ['abi', 'evm.bytecode'] },
},
},
};
const compiled = JSON.parse(solc.compile(JSON.stringify(input)));
const contract = compiled.contracts['SimpleStorage.sol']['SimpleStorage'];
const abi = contract.abi;
const bytecode = contract.evm.bytecode.object;
async function deploy() {
const accounts = await web3.eth.getAccounts();
const SimpleStorage = new web3.eth.Contract(abi);
const deployed = await SimpleStorage
.deploy({ data: bytecode })
.send({
from: accounts[0],
gas: 1500000,
});
console.log('Contract deployed at:', deployed.options.address);
return deployed.options.address;
}
deploy();

Interagir com o Contrato

const contractAddress = '0x...'; // Endereço após deploy
const contract = new web3.eth.Contract(abi, contractAddress);
// Ler valor (gratuito, sem gas)
async function getValue() {
const value = await contract.methods.get().call();
console.log('Stored value:', value);
}
// Escrever valor (custa gas)
async function setValue(newValue) {
const accounts = await web3.eth.getAccounts();
const receipt = await contract.methods
.set(newValue)
.send({
from: accounts[0],
gas: 100000,
});
console.log('Transaction hash:', receipt.transactionHash);
}
// Escutar eventos
contract.events.ValueChanged({
fromBlock: 'latest',
})
.on('data', (event) => {
console.log('Value changed to:', event.returnValues.newValue);
})
.on('error', console.error);

Utilizar a Alternativa Ethers.js

O Ethers.js é outra biblioteca popular com uma API mais limpa:

import { ethers } from 'ethers';
// Ligar ao provider
const provider = new ethers.JsonRpcProvider(
`https://sepolia.infura.io/v3/${process.env.INFURA_API_KEY}`
);
// Criar wallet
const wallet = new ethers.Wallet(process.env.PRIVATE_KEY, provider);
// Enviar transação
async function sendEther() {
const tx = await wallet.sendTransaction({
to: '0xRecipientAddress',
value: ethers.parseEther('0.01'),
});
console.log('TX Hash:', tx.hash);
const receipt = await tx.wait();
console.log('Confirmed in block:', receipt.blockNumber);
}
// Interação com contrato
const contract = new ethers.Contract(contractAddress, abi, wallet);
await contract.set(42);
const value = await contract.get();

Interação com Tokens ERC-20

const tokenABI = [
'function balanceOf(address owner) view returns (uint256)',
'function transfer(address to, uint256 amount) returns (bool)',
'function decimals() view returns (uint8)',
'function symbol() view returns (string)',
];
const tokenContract = new web3.eth.Contract(tokenABI, tokenAddress);
// Obter informação do token
const symbol = await tokenContract.methods.symbol().call();
const decimals = await tokenContract.methods.decimals().call();
const balance = await tokenContract.methods.balanceOf(walletAddress).call();
console.log(`Balance: ${balance / 10 ** decimals} ${symbol}`);
// Transferir tokens
const amount = BigInt(100) * BigInt(10 ** decimals); // 100 tokens
await tokenContract.methods
.transfer(recipientAddress, amount.toString())
.send({ from: senderAddress, gas: 100000 });

Ambiente de Testes

Utilizar a Testnet Sepolia

  1. Obter ETH de teste a partir do faucet: https://www.alchemy.com/faucets/ethereum-sepolia
  2. Mudar para a testnet no seu código:
const isProduction = process.env.NODE_ENV === 'production';
const network = isProduction ? 'mainnet' : 'sepolia';
const provider = `https://${network}.infura.io/v3/${process.env.INFURA_API_KEY}`;

Hardhat para Desenvolvimento

npm install --save-dev hardhat @nomicfoundation/hardhat-toolbox
npx hardhat init

Configurar hardhat.config.js:

require("@nomicfoundation/hardhat-toolbox");
module.exports = {
solidity: "0.8.19",
networks: {
sepolia: {
url: `https://sepolia.infura.io/v3/${process.env.INFURA_API_KEY}`,
accounts: [process.env.PRIVATE_KEY],
},
},
};

Executar testes:

npx hardhat test
npx hardhat run scripts/deploy.js --network sepolia

Ferramentas Úteis de Desenvolvimento

  • Remix IDE: Editor Solidity baseado no browser - https://remix.ethereum.org
  • Etherscan: Explorador de blocos - https://etherscan.io
  • Ganache: Blockchain local - https://github.com/trufflesuite/ganache-ui
  • Infura: Infraestrutura de nós - https://www.infura.io
  • Alchemy: API melhorada - https://www.alchemy.com

Considerações de Segurança

  1. Nunca expor chaves privadas: Utilize variáveis de ambiente
  2. Validar todas as entradas: Os smart contracts não podem ser alterados após o deploy
  3. Testar exaustivamente: Bugs custam dinheiro real
  4. Utilizar contratos auditados: Não reinvente a roda para tokens
  5. Compreender gas: Otimize para poupar dinheiro aos utilizadores
  6. Lidar com falhas: As transações podem falhar por muitas razões

Principais Conclusões

  1. Use primeiro as testnets: Teste sempre na Sepolia antes da mainnet
  2. Compreender gas: Cada operação custa dinheiro
  3. Eventos para atualizações de UI: Escute eventos do contrato para atualizações em tempo real
  4. BigInt para montantes: O Ethereum usa 18 casas decimais; use BigInt
  5. Gestão segura de chaves: Utilize hardware wallets em produção
  6. Verificar no Etherscan: Publique o código-fonte para transparência

O desenvolvimento blockchain exige atenção cuidadosa à segurança e aos testes — os erros são permanentes e potencialmente dispendiosos. Comece com testnets e montantes pequenos até ter confiança.

 
 
 
Языки
Темы
Copyright © 1999 — 2026
ZK Interactive