Build and deploy your first dApp on Base in under 60 minutes

Share This Post

Building Your First Base dApp – Deploy, Verify, and Ship in 60 Minutes

What You’ll Achieve

By the end, you’ll bridge ETH to Base, deploy and verify a smart contract on Base mainnet, and ship a minimal web UI that reads and writes on-chain.

Why This Matters

Base is an Ethereum Layer 2 built for speed, scale, and low fees. In 2025, it grew to process over 53% of all L2 transactions while keeping median fees under $0.05. “Flashblocks reduced block confirmation times from 2 seconds to 200 milliseconds,” enabling near-instant UX. With TVL surging past $4B and 18.5M active addresses, deploying on Base puts your app where users already are-and where blockspace is expanding to 250 Mgas/s by year-end.

Prerequisites

  • Wallet: MetaMask (or Coinbase Wallet). You’ll add Base mainnet manually.
  • Gas: At least 0.01 ETH on Base for deployments and a few interactions.
  • Tools: Node.js 18+, Git, and either Foundry (recommended) or Hardhat.
  • Explorer/API: BaseScan account and API key for contract verification.
  • Concepts: Basic EVM familiarity (ABI, gas, nonces), and comfort with a terminal.

Base network details you’ll use:

Useful real contracts on Base (for reference/testing):

Step-by-Step Process

1) Add Base to your wallet and fund gas

  • MetaMask → Settings → Networks → Add network, then enter:
    • Network name: Base
    • RPC: https://mainnet.base.org
    • Chain ID: 8453
    • Currency symbol: ETH
    • Block explorer: https://basescan.org
  • Fund Base ETH:
    • Fastest: Use Base official bridge. Deposit ETH from Ethereum mainnet. Deposits confirm on Base in ~2-5 minutes; L1 fee applies once.
    • Alternate: Withdraw directly to Base from Coinbase or an exchange that supports Base network.
Screenshot: MetaMask Add Base network form
MetaMask network config for Base

Cost: Expect <$2 for the initial L1 bridge deposit (varies by Ethereum gas), then <$0.05 per transaction on Base.

2) Initialize a project with Foundry

  • Install Foundry: curl -L https://foundry.paradigm.xyz | bash && foundryup
  • Scaffold: forge init base-counter && cd base-counter
  • Create .env in project root with:
    • PRIVATE_KEY=0xYOUR_PRIVATE_KEY (use a dedicated deployer wallet)
    • BASE_RPC=https://mainnet.base.org
    • ETHERSCAN_API_KEY=YOUR_BASESCAN_API_KEY

Add a simple contract at src/Counter.sol:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;

contract Counter {
uint256 public count;

event Increment(address indexed caller, uint256 newCount);

function increment() external {
unchecked { count++; }
emit Increment(msg.sender, count);
}
}

Compile: forge build. If you use optimizer settings, add to foundry.toml: optimizer = true, optimizer_runs = 200.

3) Deploy to Base mainnet

  • Ensure your deployer wallet is selected in MetaMask and funded on Base.
  • Deploy with Foundry:
    • forge create src/Counter.sol:Counter --rpc-url $BASE_RPC --private-key $PRIVATE_KEY

Note the returned contract address and open it on BaseScan to confirm: https://basescan.org/address/0xYOUR_CONTRACT.

Gas and timing: Deployment should finalize on Base in under 1 second at the UX layer thanks to Flashblocks; BaseScan indexing may take ~10-60 seconds to display details. Expect ~$0.01-$0.03 in L2 gas for this contract (varies with congestion).

4) Verify your contract on BaseScan

  • Get an API key at: basescan.org/myapikey
  • Verify via Foundry:
    • forge verify-contract --chain 8453 --watch 0xYOUR_CONTRACT src/Counter.sol:Counter $ETHERSCAN_API_KEY
  • Alternatively, use BaseScan’s UI: Contract → Code → Verify & Publish. Match compiler version (e.g., 0.8.24) and optimizer runs.
Screenshot: BaseScan verify contract form
Verifying your contract on BaseScan

If verification fails, ensure your compiler version and optimizer settings match your build, and that evmVersion isn’t mismatched.

5) Build a minimal web UI (read/write)

  • Scaffold a Next.js app: npx create-next-app@latest base-ui
  • Install ethers: cd base-ui && npm i ethers
  • Create lib/abi.js with your ABI:
    • export const COUNTER_ABI = [
      { "inputs": [], "name": "count", "outputs": [{"internalType":"uint256","name":"","type":"uint256"}], "stateMutability":"view","type":"function" },
      { "inputs": [], "name": "increment", "outputs": [], "stateMutability":"nonpayable","type":"function" }
      ];
  • Edit pages/index.js to connect, read, and increment:

import { useEffect, useState } from "react";
import { ethers } from "ethers";
import { COUNTER_ABI } from "../lib/abi";

const CONTRACT = "0xYOUR_CONTRACT";
const BASE_ID = 8453;

export default function Home() {
const [account, setAccount] = useState("");
const [count, setCount] = useState(0);
const [provider, setProvider] = useState();
const [contract, setContract] = useState();

async function connect() {
if (!window.ethereum) return alert("Install MetaMask");
const p = new ethers.BrowserProvider(window.ethereum);
const net = await p.getNetwork();
if (Number(net.chainId) !== BASE_ID) {
await window.ethereum.request({
method: "wallet_switchEthereumChain",
params: [{ chainId: "0x2105" }], // 8453 in hex
});
}
const s = await p.getSigner();
setAccount(await s.getAddress());
const c = new ethers.Contract(CONTRACT, COUNTER_ABI, s);
setProvider(p);
setContract(c);
}

async function refresh() {
if (!contract) return;
setCount(Number(await contract.count()));
}

async function increment() {
const tx = await contract.increment();
await tx.wait(); // near-instant on Base; UX updates ~<1s
refresh();
}

useEffect(() => {
if (contract) refresh();
}, [contract]);

return (
<main style={{ padding: 24 }}>
<h1>Base Counter</h1>
<button onClick={connect}>{account ? "Connected" : "Connect"}</button>
<p>Count: {count}</p>
<button onClick={increment}>Increment</button>
</main>
);
}

Screenshot: Minimal Base dApp UI with connect and increment buttons
Minimal UI: connect, read, write

Run locally: npm run dev. Open http://localhost:3000 and connect. Each increment() costs a few cents or less and confirms in ~200 ms from a UX standpoint.

6) Measure and confirm

  • Open your transaction on BaseScan from MetaMask’s activity feed to see exact gas used and USD cost.
  • Expect L2 gas for increment() around 21k–45k units. With typical L2 gas prices, fees are often $0.005–$0.03.
  • Batch throughput: Base regularly sustains high TPS and can exceed 1,500+ TPS during peaks, thanks to 50 Mgas/s capacity and Flashblocks. Plan your UX for rapid confirmations and low polling intervals.

Common Issues

  • Transaction stuck pending?
    • In MetaMask, use Speed up to resubmit with a higher fee. Ensure you’re on chain ID 8453.
    • If pending for >2 minutes, check status.base.org and that your RPC is https://mainnet.base.org. Consider switching to a hosted RPC (Alchemy, Infura) for WebSocket updates.
  • Bridge deposit taking long?
    • Deposits usually arrive on Base within ~2–5 minutes. If Ethereum is congested, it may take longer. Track your deposit tx on Etherscan and the corresponding L2 message on BaseScan.
    • Withdrawals via the official bridge take ~7 days (Optimistic challenge period). For faster exits, use a reputable third-party bridge/liquidity network, weighing trust and slippage.
  • Verification failed on BaseScan?
    • Use the exact compiler version (e.g., 0.8.24) and optimizer runs from your build. Mismatches cause failure.
    • If using libraries or proxies, supply constructor args and linked libraries. Foundry’s --watch helps.
  • “Insufficient liquidity” on DEX or swaps?
    • For tokens like USDC on Base, confirm the real address: USDC 0x8335…2913. If a token isn’t liquid, use ETH or USDC as routing assets.
  • Wrong network or chain ID?
    • Base mainnet is 8453. In code, ensure wallet_switchEthereumChain targets 0x2105.

Pro Tips

  • Gas optimization
    • Enable Solidity optimizer (200–400 runs) and pack storage to reduce L2 gas usage.
    • Batch calls via multicall where possible to amortize overhead.
  • UX for Flashblocks
    • Use WebSocket providers to react to ~200 ms block confirmations. Optimistically update UI after tx.hash, then reconcile on tx.wait().
  • Best time to transact
    • Off-peak UTC hours (03:00–07:00) often show the lowest fees. Base’s fee market stays stable even during spikes but timing still helps.
  • Funding paths
    • For teams, consider direct Base withdrawals from Coinbase for operational accounts to avoid L1 bridging costs.
  • Security workflow
    • Simulate transactions with Tenderly or Foundry’s forge script --dry-run. Use OpenZeppelin implementations where possible and run unit/invariant tests before mainnet.
  • Observability
    • Emit events (like Increment) and index them in a subgraph (The Graph supports Base) for fast UI state.

What’s Next

  • Productionize: Add role-based access, pause guards, and upgrade patterns (if truly needed) with transparent proxies.
  • Indexing: Create a subgraph for your events and denormalized views.
  • Frontend polish: Migrate to wagmi/viem and RainbowKit for robust wallet UX on Base.
  • CI/CD: Add automated tests, static analysis (Slither), gas snapshots, and deploy scripts with environment gates.
  • Integrations: Connect to Base-native DeFi (e.g., swap via a DEX) using real tokens like USDC 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913 and WETH 0x4200...0006.
  • Scale strategy: As Base scales from 50 to 250 Mgas/s, design for higher throughput-shard state by account, minimize hot storage slots, and prefer pull-based payout patterns.

You’ve deployed, verified, and shipped a working Base dApp. From here, focus on product-market fit, robust testing, and composability with the growing Base ecosystem—where fees are low, confirmation is near-instant, and users are already active.

Reference Links

Note: Base is currently evolving its decentralization stage and fee market. Always review current docs and status pages before deploying critical systems.

Related Posts

How to Run a Weekly Base Deep‑Dive: TVL, Token News, Solana Bridge & On‑Chain Activity

Learn a repeatable weekly workflow to analyze Base: TVL, users, fees, token and Solana bridge developments, plus live on-chain checks using Base tools.

Stablecoins on Base: Institutional-Grade Ecosystem Analysis

Base’s stablecoin ecosystem reached $2.8B TVL in Nov 2025, with USDC dominating 78–87% and new yield tokens like USDe adding efficiency—and concentration...

AI and Blockchain Converge: Base Sees Institutional Growth

Base's AI-focused ecosystem saw AI TVL hit $1.82 billion in Nov 2025, unique addresses rose 50% and transaction volume topped $4 billion, signaling...

Base Chain’s RWA Tokenization Soars to $1.82B, Institutional Grade

Base Chain’s real-world asset tokenization reached $1.82B TVL in Nov 2025, with sub-second settlement, 42 new contracts and growing institutional interest.

Securely store and manage your crypto on Base: custody, bridging, and multisig in 30 minutes

What You’ll Achieve Set up a secure, operationally sound workflow to store and manage your cryptocurrency on Base: add the Base network to your...

Secure Your First Transactions on Base: A Beginner’s Blockchain Security Playbook

Secure Your First Transactions on Base: A Beginner’s Blockchain Security Playbook What You’ll Achieve In 30 minutes, you’ll securely set up Base,...