---
title: "Deploy on Base"
description: "Set up Foundry, configure RPC and key management, and deploy a smart contract to Base Sepolia in a single workflow."
source: https://basehub.org/introduction/deploy-on-base/
---
import { Aside } from '@astrojs/starlight/components';

Set up a Foundry project, point it at Base, and deploy a contract to Base Sepolia in a single end-to-end workflow.

## What you build

By the end of this guide you will have:

- A Foundry-based development environment configured for Base
- A smart contract deployed to Base Sepolia
- A connection pattern your frontend can reuse against your contracts

<Aside type="tip">
Base is a fast, low-cost, builder-friendly Ethereum L2 designed to bring the next billion users onchain. Following this guide plugs you into a wide ecosystem of developers, creators, and operators building the global onchain economy.
</Aside>

## Set up your development environment

1. Create a project directory.

```bash
mkdir my-base-project && cd my-base-project
```

2. Install Foundry, the framework used throughout this guide.

```bash
curl -L https://foundry.paradigm.xyz | bash
foundryup
```

The installer pulls Foundry and updates it to the latest release.

3. Initialize a Solidity project.

```bash
forge init
```

The Foundry project is ready. The starter contract sits at `src/Counter.sol` — this guide uses that contract as the deployment target.

<Aside type="tip">
Foundry packages tools for Ethereum development including Forge (testing), Cast (chain interactions), and Anvil (local node). The full reference is in [the Foundry Book](https://book.getfoundry.sh/).
</Aside>

## Configure Foundry for Base

Deploying to Base requires two pieces:

1. An RPC connection to the network
2. A funded private key for signing the deployment transaction

### 1. Set up your RPC connection

1. Create a `.env` file at the project root.
2. Add the Base RPC URLs.

```bash
BASE_RPC_URL="https://mainnet.base.org"
BASE_SEPOLIA_RPC_URL="https://sepolia.base.org"
```

3. Load the variables into your shell.

```bash
source .env
```

<Aside type="tip">
Base Sepolia is the test network for Base and is used for the rest of this guide. Free Base Sepolia ETH is available from the [faucets list](/network/network-faucets/).
</Aside>

### 2. Secure your private key

1. Import your private key into Foundry's encrypted keystore.

```bash
cast wallet import deployer --interactive
```

2. Paste the key when prompted and set a password.

The encrypted key is stored at `~/.foundry/keystores`, which is excluded from git.

<Aside type="caution">
Never share or commit a private key. Treat it as a credential and store it accordingly.
</Aside>

## Deploy your contract

With the environment configured, deploy to Base Sepolia.

1. (Optional) Run a dry run first to confirm the deployment is well-formed.

```bash
forge create ./src/Counter.sol:Counter --rpc-url $BASE_SEPOLIA_RPC_URL --account deployer
```

This simulates the deploy without broadcasting. You will see the transaction details and ABI; nothing is written onchain.

2. Add `--broadcast` to actually deploy.

```bash
forge create ./src/Counter.sol:Counter --rpc-url $BASE_SEPOLIA_RPC_URL --account deployer --broadcast
```

<Aside type="tip">
The `--broadcast` flag is required to send the transaction. Without it, Foundry only simulates.
</Aside>

The contract argument follows the format `<contract-path>:<contract-name>`.

3. A successful deploy prints output similar to:

```
Deployer: 0x...
Deployed to: 0x...  <-- YOUR CONTRACT ADDRESS
Transaction hash: 0x...
```

4. Save the deployed address into `.env`.

```bash
COUNTER_CONTRACT_ADDRESS="0x..."
```

Replace `0x...` with the address from the output.

5. Reload the variables.

```bash
source .env
```

<Aside type="tip">
Re-run `source .env` after every change to load new variables into the current shell.
</Aside>

### Verify your deployment

To confirm the contract is live:

1. Look up the transaction hash on [Sepolia Basescan](https://sepolia.basescan.org/).
2. Read the contract directly with `cast`:

```bash
cast call $COUNTER_CONTRACT_ADDRESS "number()(uint256)" --rpc-url $BASE_SEPOLIA_RPC_URL
```

<Aside type="tip">
The command requires `COUNTER_CONTRACT_ADDRESS` in `.env` and a fresh `source .env`. Otherwise the variable expands to nothing and the call fails.
</Aside>

The call returns the initial value of the Counter's `number` storage slot, which is `0`.

The contract is now live on Base Sepolia.

## Next steps

- Wire a frontend to your contracts using [wagmi](https://wagmi.sh) or [viem](https://viem.sh).
- Dive deeper into Foundry workflows in the [Foundry deployment tutorial](https://docs.base.org/learn/foundry/deploy-with-foundry).
