← All guides
beginner May 16, 2026

Deploy a smart contract on Base Sepolia

Deploy and verify a Solidity contract on Base Sepolia using Foundry. Base is an Ethereum L2 by Coinbase — fast, cheap and EVM-compatible.


Base is an Ethereum L2 built on the OP Stack by Coinbase. It is fully EVM-compatible, which means any contract that works on Ethereum Sepolia will work on Base Sepolia with only a network change.

Why Base Sepolia

  • Low fees — gas costs are a fraction of Ethereum mainnet
  • Fast finality — 2-second block times
  • Builder ecosystem — one of the most active L2 communities in 2026
  • Same tooling — Foundry, Hardhat, ethers.js, viem all work without changes

Prerequisites

  • Foundry installed (curl -L https://foundry.paradigm.xyz | bash && foundryup)
  • Base Sepolia ETH — request from the Base Sepolia faucet or bridge from Sepolia
  • A Basescan API key — free at basescan.org

Network details

Parameter Value
Network name Base Sepolia
Chain ID 84532
RPC URL https://sepolia.base.org
Explorer sepolia.basescan.org
Currency ETH

1. Project setup

If you already have a Foundry project, you only need to update foundry.toml. Otherwise:

forge init my-base-contract
cd my-base-contract

2. Configure foundry.toml

[profile.default]
src = "src"
out = "out"
libs = ["lib"]

[rpc_endpoints]
base_sepolia = "${BASE_SEPOLIA_RPC_URL}"

[etherscan]
base_sepolia = { key = "${BASESCAN_API_KEY}", url = "https://api-sepolia.basescan.org/api" }

3. Environment variables

BASE_SEPOLIA_RPC_URL=https://sepolia.base.org
PRIVATE_KEY=0xYOUR_DEV_WALLET_PRIVATE_KEY
BASESCAN_API_KEY=YOUR_BASESCAN_API_KEY

4. Sample contract

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

contract SimpleStore {
    mapping(address => uint256) public balances;

    event Deposited(address indexed user, uint256 amount);
    event Withdrawn(address indexed user, uint256 amount);

    function deposit() external payable {
        balances[msg.sender] += msg.value;
        emit Deposited(msg.sender, msg.value);
    }

    function withdraw(uint256 amount) external {
        require(balances[msg.sender] >= amount, "Insufficient balance");
        balances[msg.sender] -= amount;
        (bool ok,) = msg.sender.call{value: amount}("");
        require(ok, "Transfer failed");
        emit Withdrawn(msg.sender, amount);
    }
}

5. Deployment script

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

import {Script} from "forge-std/Script.sol";
import {SimpleStore} from "../src/SimpleStore.sol";

contract Deploy is Script {
    function run() external returns (SimpleStore) {
        vm.startBroadcast();
        SimpleStore store = new SimpleStore();
        vm.stopBroadcast();
        return store;
    }
}

6. Deploy and verify

source .env

forge script script/Deploy.s.sol \
  --rpc-url base_sepolia \
  --private-key $PRIVATE_KEY \
  --broadcast \
  --verify

7. Interact with the contract

Deposit ETH:

cast send <CONTRACT_ADDRESS> "deposit()" \
  --value 0.01ether \
  --private-key $PRIVATE_KEY \
  --rpc-url $BASE_SEPOLIA_RPC_URL

Check balance:

cast call <CONTRACT_ADDRESS> \
  "balances(address)(uint256)" \
  <YOUR_ADDRESS> \
  --rpc-url $BASE_SEPOLIA_RPC_URL

Bridging from Sepolia to Base Sepolia

If you already have Sepolia ETH, you can bridge it:

  1. Go to bridge.base.org
  2. Connect your wallet
  3. Select Sepolia → Base Sepolia
  4. Bridge takes ~1 minute on testnet

Differences from Ethereum mainnet

Ethereum Base
Block time ~12s ~2s
Gas price Variable Very low
Finality ~15min (safe) Inherits from L1
block.chainid 1 8453 (mainnet) / 84532 (testnet)

If your contract uses block.chainid for logic, make sure to account for Base’s chain ID.