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 ConceptWeb3 EquivalentKey Difference
Database (SQL/NoSQL)Blockchain state / EventsImmutable, public, expensive to write
REST APISmart contract ABICallable on-chain, costs gas
Authentication (JWT)Wallet signature (EIP-712)Cryptographic, no server required
User accountWallet address (EOA)User controls private key
Server sessionNo equivalentWeb3 is stateless at protocol level
Database migrationContract upgrade / migrationMuch harder — requires proxy or new deployment
Write to DBSend transactionCosts gas, takes seconds, irreversible
Read from DBCall contract view functionFree, instant, no signature needed
Cron jobsChainlink Automation / GelatoOn-chain keepers, cost ETH
File storageIPFS / ArweaveContent-addressed, decentralized
Environment variablesHardcoded in contractSecrets cannot be kept on-chain
Admin panelMultisig (Safe)Multi-party approval required
Feature flagsContract upgradesExpensive and trust-requiring
Log analyticsEvent 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)

  1. Wallet connection — MetaMask, WalletConnect, Coinbase Wallet
  2. Reading blockchain state — calling view functions
  3. Sending transactions — write functions, gas, tx lifecycle
  4. Event handling — listening for on-chain events
  5. 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

  1. EVM storage model — everything is in 32-byte slots
  2. msg.sender vs tx.origin — never use tx.origin for auth
  3. reentrancy — check-effects-interactions pattern
  4. gas optimization — storage reads/writes are expensive
  5. 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 nonReentrant modifier 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
ResourceForType
docs.soliditylang.orgSolidityOfficial docs
book.getfoundry.shFoundryOfficial docs
docs.openzeppelin.comContractsOfficial docs
wagmi.shwagmi v2Official docs
viem.shviemOfficial docs
cryptozombies.ioSolidity basicsInteractive tutorial
speedrunethereum.comFull-stack Web3Project-based
Secureum bootcampSecuritySecurity focus