Learn Web3 Development
Interactive tutorials to help you build decentralized applications
1. Connect a Wallet
BeginnerLearn how to detect and connect to MetaMask or other Web3 wallets using ethers.js. This is the foundation of any dApp.
JavaScript
// Check if MetaMask is installed
if (typeof window.ethereum !== 'undefined') {
console.log('MetaMask is installed!');
}
// Request account access
async function connectWallet() {
try {
// Request accounts from MetaMask
const accounts = await window.ethereum.request({
method: 'eth_requestAccounts'
});
// Create ethers provider
const provider = new ethers.providers.Web3Provider(window.ethereum);
const signer = provider.getSigner();
console.log('Connected:', accounts[0]);
return { provider, signer, address: accounts[0] };
} catch (error) {
console.error('Connection failed:', error);
}
}
🔴 Live Demo
Click the button to connect your wallet
2. Read Blockchain Data
BeginnerQuery balances, block numbers, and other on-chain data without requiring a wallet connection.
JavaScript
// You can use a public RPC to read data
const provider = new ethers.providers.JsonRpcProvider(
'https://eth.llamarpc.com'
);
// Get ETH balance of any address
async function getBalance(address) {
const balance = await provider.getBalance(address);
return ethers.utils.formatEther(balance);
}
// Get current block number
async function getBlockNumber() {
return await provider.getBlockNumber();
}
// Get gas price
async function getGasPrice() {
const gasPrice = await provider.getGasPrice();
return ethers.utils.formatUnits(gasPrice, 'gwei');
}
// Example usage
const vitalikAddress = '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045';
const balance = await getBalance(vitalikAddress);
console.log(`Balance: ${balance} ETH`);
🔴 Live Demo
Enter an address to check its ETH balance
3. Interact with Smart Contracts
IntermediateCall functions on deployed smart contracts. Read data and execute transactions.
JavaScript
// ERC-20 Token ABI (simplified)
const ERC20_ABI = [
'function name() view returns (string)',
'function symbol() view returns (string)',
'function decimals() view returns (uint8)',
'function balanceOf(address) view returns (uint256)',
'function transfer(address to, uint256 amount) returns (bool)'
];
// Create contract instance
const tokenAddress = '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48'; // USDC
const contract = new ethers.Contract(tokenAddress, ERC20_ABI, provider);
// Read contract data
async function getTokenInfo() {
const name = await contract.name();
const symbol = await contract.symbol();
const decimals = await contract.decimals();
console.log(`Token: ${name} (${symbol})`);
console.log(`Decimals: ${decimals}`);
}
// Get token balance
async function getTokenBalance(walletAddress) {
const balance = await contract.balanceOf(walletAddress);
const decimals = await contract.decimals();
return ethers.utils.formatUnits(balance, decimals);
}
🔴 Live Demo
Click to read USDC contract data
4. Sign Messages
IntermediateCryptographically sign messages to prove ownership of an address. Used for authentication and off-chain actions.
JavaScript
// Sign a message with the connected wallet
async function signMessage(message) {
const provider = new ethers.providers.Web3Provider(window.ethereum);
const signer = provider.getSigner();
// This will prompt the user to sign
const signature = await signer.signMessage(message);
console.log('Signature:', signature);
return signature;
}
// Verify a signature
function verifySignature(message, signature, expectedAddress) {
const recoveredAddress = ethers.utils.verifyMessage(
message,
signature
);
return recoveredAddress.toLowerCase() === expectedAddress.toLowerCase();
}
// Example: Sign-in with Ethereum
const message = `Sign in to Web3Hub\nNonce: ${Date.now()}`;
const signature = await signMessage(message);
🔴 Live Demo
Connect wallet and sign a message
5. Send Transactions
AdvancedSend ETH or interact with contracts by submitting transactions to the blockchain.
JavaScript
// Send ETH to another address
async function sendETH(toAddress, amountInEth) {
const provider = new ethers.providers.Web3Provider(window.ethereum);
const signer = provider.getSigner();
// Create transaction object
const tx = {
to: toAddress,
value: ethers.utils.parseEther(amountInEth)
};
// Send transaction (will prompt user)
const transaction = await signer.sendTransaction(tx);
console.log('TX Hash:', transaction.hash);
// Wait for confirmation
const receipt = await transaction.wait();
console.log('Confirmed in block:', receipt.blockNumber);
return receipt;
}
// Call a contract function that modifies state
async function approveToken(tokenAddress, spenderAddress, amount) {
const abi = ['function approve(address, uint256) returns (bool)'];
const signer = provider.getSigner();
const contract = new ethers.Contract(tokenAddress, abi, signer);
const tx = await contract.approve(spenderAddress, amount);
return await tx.wait();
}
🔴 Live Demo
⚠️ This would send real ETH - demo disabled for safety
Transaction demos are disabled to prevent accidental fund transfers