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:
- Go to bridge.base.org
- Connect your wallet
- Select Sepolia → Base Sepolia
- 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.