standards/dev-onboarding-web3
Web2 to Web3 Developer Onboarding Guide
ethereumguide🤖 Auto-generatedconfidence highhealth 100%
v1.0.0·Updated 3/26/2026
Overview
This guide translates Web2 concepts to Web3 equivalents and provides role-specific onboarding paths. Whether you're a frontend developer, backend engineer, or moving into smart contract development, this guide gives you the fastest path to productivity.
Web2 → Web3 Concept Translation
| Web2 Concept | Web3 Equivalent | Key Difference |
|---|---|---|
| Database (SQL/NoSQL) | Blockchain state / Events | Immutable, public, expensive to write |
| REST API | Smart contract ABI | Callable on-chain, costs gas |
| Authentication (JWT) | Wallet signature (EIP-712) | Cryptographic, no server required |
| User account | Wallet address (EOA) | User controls private key |
| Server session | No equivalent | Web3 is stateless at protocol level |
| Database migration | Contract upgrade / migration | Much harder — requires proxy or new deployment |
| Write to DB | Send transaction | Costs gas, takes seconds, irreversible |
| Read from DB | Call contract view function | Free, instant, no signature needed |
| Cron jobs | Chainlink Automation / Gelato | On-chain keepers, cost ETH |
| File storage | IPFS / Arweave | Content-addressed, decentralized |
| Environment variables | Hardcoded in contract | Secrets cannot be kept on-chain |
| Admin panel | Multisig (Safe) | Multi-party approval required |
| Feature flags | Contract upgrades | Expensive and trust-requiring |
| Log analytics | Event indexing (The Graph) | Requires subgraph or indexer setup |
Common Misconceptions
"Smart contracts are like APIs"
- ❌ Wrong: APIs can be updated, have server costs, can store any data cheaply
- ✅ Reality: Contracts are immutable by default, writing data costs gas, computation is expensive
"Web3 apps don't need a backend"
- ❌ Wrong: Most dApps need off-chain indexing, APIs, and infrastructure
- ✅ Reality: The blockchain is just one component — you still need Next.js, databases for off-chain data, APIs for metadata, indexers for event data
"Private keys are like passwords"
- ❌ Wrong: Passwords can be reset; private key loss = permanent loss of funds
- ✅ Reality: Private keys derive the wallet address mathematically. There is no recovery mechanism.
"Transactions are instant"
- ❌ Wrong: Ethereum L1 has 12-second block times; finality takes minutes
- ✅ Reality: L2s have near-instant soft finality (1-2s), but hard finality (on L1) can take minutes to hours
Frontend Developer Path
Your Advantage
You already know React, TypeScript, state management, and UX. Web3 frontend is 80% regular web development.
New Concepts to Learn (in order)
- Wallet connection — MetaMask, WalletConnect, Coinbase Wallet
- Reading blockchain state — calling view functions
- Sending transactions — write functions, gas, tx lifecycle
- Event handling — listening for on-chain events
- Signature flows — EIP-712, permit, EIP-1271
Essential Toolchain
# Install core dependencies for a modern Web3 frontend
npm install wagmi viem @tanstack/react-query
npm install @rainbow-me/rainbowkit # Wallet connection UI
# OR
npm install @coinbase/onchainkit # Base-focused wallet kit
# For Solana
npm install @solana/web3.js @solana/wallet-adapter-react
Starter Code Pattern (Next.js + wagmi v2)
// app/providers.tsx
"use client";
import { WagmiProvider, createConfig, http } from "wagmi";
import { base, mainnet } from "wagmi/chains";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { RainbowKitProvider, getDefaultConfig } from "@rainbow-me/rainbowkit";
import "@rainbow-me/rainbowkit/styles.css";
const config = getDefaultConfig({
appName: "My App",
projectId: "YOUR_WALLETCONNECT_PROJECT_ID",
chains: [base, mainnet],
});
const queryClient = new QueryClient();
export function Providers({ children }: { children: React.ReactNode }) {
return (
<WagmiProvider config={config}>
<QueryClientProvider client={queryClient}>
<RainbowKitProvider>{children}</RainbowKitProvider>
</QueryClientProvider>
</WagmiProvider>
);
}
// components/TokenBalance.tsx
"use client";
import { useReadContract, useAccount } from "wagmi";
import { formatUnits } from "viem";
const ERC20_ABI = [
{ name: "balanceOf", type: "function", inputs: [{ name: "account", type: "address" }], outputs: [{ name: "", type: "uint256" }], stateMutability: "view" },
{ name: "decimals", type: "function", inputs: [], outputs: [{ name: "", type: "uint8" }], stateMutability: "view" },
] as const;
export function TokenBalance({ tokenAddress }: { tokenAddress: `0x${string}` }) {
const { address } = useAccount();
const { data: balance } = useReadContract({
address: tokenAddress,
abi: ERC20_ABI,
functionName: "balanceOf",
args: [address!],
query: { enabled: !!address },
});
const { data: decimals } = useReadContract({
address: tokenAddress,
abi: ERC20_ABI,
functionName: "decimals",
});
if (!balance || !decimals) return <span>Loading...</span>;
return <span>{formatUnits(balance, decimals)} tokens</span>;
}
Transaction UX Pattern
"use client";
import { useWriteContract, useWaitForTransactionReceipt } from "wagmi";
export function TransferButton() {
const { writeContract, data: hash, isPending } = useWriteContract();
const { isLoading: isConfirming, isSuccess } = useWaitForTransactionReceipt({ hash });
return (
<button
onClick={() => writeContract({
address: "0x...",
abi: ERC20_ABI,
functionName: "transfer",
args: ["0x...", 1000000n],
})}
disabled={isPending || isConfirming}
>
{isPending ? "Confirming in wallet..." :
isConfirming ? "Waiting for blockchain..." :
isSuccess ? "Done!" : "Transfer"}
</button>
);
}
Backend Developer Path
Your Advantage
You understand APIs, data models, async operations, and infrastructure. Web3 backend adds blockchain data as a new data source.
Key Shift in Thinking
- Blockchain = append-only log + global state machine
- Your backend often indexes/caches chain data into a real database
- Webhooks → Event listeners
- Database writes → Transactions (with gas costs + confirmation delays)
Essential Backend Stack
Chain interaction: ethers.js v6 or viem
Indexing: The Graph (decentralized) or Ponder (local-first)
Node access: Alchemy, Infura, or QuickNode (not public RPCs in prod)
Event streaming: WebSocket subscriptions or polling
Database: PostgreSQL for indexed data + chain as source of truth
Reading Blockchain Data
import { createPublicClient, http, parseAbi } from "viem";
import { mainnet } from "viem/chains";
const client = createPublicClient({
chain: mainnet,
transport: http(process.env.ALCHEMY_URL),
});
// Read contract state
const balance = await client.readContract({
address: "0x...",
abi: parseAbi(["function balanceOf(address) view returns (uint256)"]),
functionName: "balanceOf",
args: ["0x..."],
});
// Get past events (crucial for indexing)
const logs = await client.getLogs({
address: "0x...",
event: parseAbiItem("event Transfer(address indexed from, address indexed to, uint256 value)"),
fromBlock: 19000000n,
toBlock: "latest",
});
// Watch for new events
client.watchContractEvent({
address: "0x...",
abi: erc20Abi,
eventName: "Transfer",
onLogs: (logs) => {
console.log("New transfers:", logs);
// Save to your database
},
});
Signing Transactions Server-Side
import { createWalletClient, http } from "viem";
import { privateKeyToAccount } from "viem/accounts";
// ⚠️ NEVER expose private keys — use AWS KMS, HashiCorp Vault, or similar in production
const account = privateKeyToAccount(process.env.PRIVATE_KEY as `0x${string}`);
const walletClient = createWalletClient({
account,
chain: mainnet,
transport: http(process.env.RPC_URL),
});
const hash = await walletClient.writeContract({
address: "0x...",
abi: contractAbi,
functionName: "distribute",
args: [recipients, amounts],
});
Solidity Developer Path
Your Advantage (Web2 background)
Strong programming fundamentals help, but Solidity requires a completely different mental model around security, gas, and state.
Core Concepts to Master First
- EVM storage model — everything is in 32-byte slots
- msg.sender vs tx.origin — never use tx.origin for auth
- reentrancy — check-effects-interactions pattern
- gas optimization — storage reads/writes are expensive
- event logging — how off-chain indexing works
Essential Toolchain
# Install Foundry (recommended for smart contract dev)
curl -L https://foundry.paradigm.xyz | bash
foundryup
# Or Hardhat (Node.js based)
npm install --save-dev hardhat
# OpenZeppelin contracts (security-audited building blocks)
forge install OpenZeppelin/openzeppelin-contracts
# or
npm install @openzeppelin/contracts
Basic Solidity Patterns
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
contract MyToken is ERC20, Ownable, ReentrancyGuard {
uint256 public constant MAX_SUPPLY = 1_000_000 * 10**18;
constructor() ERC20("MyToken", "MTK") Ownable(msg.sender) {}
// Checks-Effects-Interactions pattern
function mint(address to, uint256 amount) external onlyOwner nonReentrant {
// CHECK
require(totalSupply() + amount <= MAX_SUPPLY, "Exceeds max supply");
// EFFECT
_mint(to, amount);
// INTERACT (if needed — external calls last)
}
}
Security Checklist for New Solidity Devs
- Use
nonReentrantmodifier for any function with external calls - Validate inputs at function entry (require statements)
- Use OpenZeppelin contracts instead of reimplementing standards
- Emit events for all state changes
- Test with fuzzing (Foundry's
forge test --fuzz-runs 10000) - Run Slither static analysis:
slither . - Never store secrets on-chain (all state is public)
- Set explicit compiler version in pragma
Universal Learning Roadmap
Week 1-2: Foundations
- Understand Ethereum accounts, transactions, and blocks
- Set up MetaMask, get testnet ETH (Sepolia faucet)
- Read a block explorer (Etherscan) — understand tx data
Week 3-4: Your Role's Stack
- Frontend: Build a dApp that reads ENS names and displays token balances
- Backend: Build an indexer that tracks ERC-20 Transfer events
- Solidity: Deploy ERC-20 and ERC-721 contracts to Sepolia
Month 2: DeFi Primitives
- Understand Uniswap v2/v3 AMM mechanics
- Build something using an existing protocol (Aave, Uniswap)
- Learn about price oracles (Chainlink, Uniswap TWAP)
Month 3: Production Skills
- Security audit basics (OpenZeppelin Defender, Slither)
- Gas optimization techniques
- Deployment with upgradeable contracts (if needed)
- The Graph subgraph for event indexing
Recommended Resources
| Resource | For | Type |
|---|---|---|
| docs.soliditylang.org | Solidity | Official docs |
| book.getfoundry.sh | Foundry | Official docs |
| docs.openzeppelin.com | Contracts | Official docs |
| wagmi.sh | wagmi v2 | Official docs |
| viem.sh | viem | Official docs |
| cryptozombies.io | Solidity basics | Interactive tutorial |
| speedrunethereum.com | Full-stack Web3 | Project-based |
| Secureum bootcamp | Security | Security focus |