This guide walks you through deploying your Bun-Eth contracts to various networks, including testnets and mainnet.
- Prerequisites
- Local Deployment (Anvil)
- Testnet Deployment (Sepolia)
- Multi-Chain Deployment
- Verification
- Troubleshooting
Before deploying, ensure you have:
-
Bun-Eth project set up
task install task contracts:compile
-
Foundry installed
curl -L https://foundry.paradigm.xyz | bash foundryup -
Environment variables configured (copy
.env.exampleto.env)
Anvil is a local Ethereum node that comes with Foundry, perfect for development and testing.
task dev:upThis starts:
- Anvil local node on port
3002(configurable viaANVIL_PORT) - API server on port
3001 - Web UI on port
3000(if full-stack)
task contracts:deployThis will:
- Deploy your contracts to the local Anvil network
- Generate TypeScript types for your contracts
- Enable contract hot reload in the frontend
Check the API health endpoint:
task check:healthOr visit:
- Web UI: http://localhost:3000
- API: http://localhost:3001
- Anvil RPC: http://localhost:3002
Sepolia is an Ethereum testnet recommended for testing your dApp before mainnet deployment.
You'll need Sepolia ETH to pay for gas. Get it from:
Sign up for a free account on one of these providers:
Alchemy (Recommended)
- Go to alchemy.com
- Create a free account
- Create a new app for Sepolia
- Copy the HTTPS RPC URL
Infura
- Go to infura.io
- Create a free account
- Create a new project
- Select Sepolia network
- Copy the HTTPS endpoint
- Go to Etherscan
- Sign up or log in
- Create a new API key
- Copy the API key
# Copy the example if you haven't already
cp .env.example .envEdit .env and add:
# Your wallet private key (⚠️ NEVER commit this!)
# Create a new wallet for testnet deployments
PRIVATE_KEY=0xyour_private_key_here
# Sepolia RPC URL from Alchemy or Infura
SEPOLIA_RPC_URL=https://eth-sepolia.g.alchemy.com/v2/your_api_key
# Etherscan API key for contract verification
ETHERSCAN_API_KEY=your_etherscan_api_key.env file or share your private key!
Send Sepolia ETH to the address associated with your PRIVATE_KEY:
# Get your address from private key using cast
cast wallet address --private-key $PRIVATE_KEYtask contracts:deploy:sepoliaThis will:
- Validate your environment variables
- Deploy contracts to Sepolia
- Automatically verify contracts on Etherscan
Check your contracts on Sepolia Etherscan:
- Search for your contract address
- Verify the contract is deployed
- Check that source code is verified
To deploy to multiple chains (Base, Arbitrum, etc.), add the respective configurations.
Add to your .env:
# Base Sepolia (testnet)
BASE_SEPOLIA_RPC_URL=https://sepolia.base.org
BASESCAN_API_KEY=your_basescan_api_key
# Arbitrum Sepolia (testnet)
ARBITRUM_SEPOLIA_RPC_URL=https://sepolia-rollup.arbitrum.io/rpc
ARBISCAN_API_KEY=your_arbiscan_api_keyAdd to tooling/task/Taskfile.yml:
contracts:deploy:base-sepolia:
desc: Deploy contracts to Base Sepolia testnet
dir: packages/contracts
cmds:
- |
if [ -z "$BASE_SEPOLIA_RPC_URL" ]; then
echo "❌ Error: BASE_SEPOLIA_RPC_URL not set"
exit 1
fi
- FOUNDRY_DISABLE_NIGHTLY_WARNING=true forge script script/Deploy.s.sol:DeployScript --rpc-url $BASE_SEPOLIA_RPC_URL --private-key $PRIVATE_KEY --broadcast --verify --etherscan-api-key ${BASESCAN_API_KEY:-}
contracts:deploy:arbitrum-sepolia:
desc: Deploy contracts to Arbitrum Sepolia testnet
dir: packages/contracts
cmds:
- |
if [ -z "$ARBITRUM_SEPOLIA_RPC_URL" ]; then
echo "❌ Error: ARBITRUM_SEPOLIA_RPC_URL not set"
exit 1
fi
- FOUNDRY_DISABLE_NIGHTLY_WARNING=true forge script script/Deploy.s.sol:DeployScript --rpc-url $ARBITRUM_SEPOLIA_RPC_URL --private-key $PRIVATE_KEY --broadcast --verify --etherscan-api-key ${ARBISCAN_API_KEY:-}task contracts:deploy:base-sepolia
task contracts:deploy:arbitrum-sepoliaIf automatic verification fails, verify manually:
cd packages/contracts
forge verify-contract \
--chain sepolia \
--compiler-version v0.8.20 \
--etherscan-api-key $ETHERSCAN_API_KEY \
CONTRACT_ADDRESS \
src/YourContract.sol:YourContractforge verify-check --chain sepolia CHECK_GUID --etherscan-api-key $ETHERSCAN_API_KEYSolution: Make sure you've:
- Created a
.envfile from.env.example - Added your
SEPOLIA_RPC_URLto the.envfile - Run
task contracts:deploy:sepoliafrom the project root (not frompackages/contracts)
Solution: Add your private key to .env:
PRIVATE_KEY=0xyour_private_key_hereSolution:
- Get testnet ETH from a faucet (see links above)
- Send it to your deployer address:
cast wallet address --private-key $PRIVATE_KEY
Possible causes:
- Etherscan API key not set: Add
ETHERSCAN_API_KEYto.env - Rate limiting: Wait a few minutes and try manual verification
- Wrong compiler version: Check your
foundry.tomlmatches the deployed contract
Manual verification:
forge verify-contract \
--chain sepolia \
--etherscan-api-key $ETHERSCAN_API_KEY \
CONTRACT_ADDRESS \
src/YourContract.sol:YourContractSolution: Check your RPC URL format:
- Should start with
https:// - Should not have trailing spaces
- Should include your API key
Example:
SEPOLIA_RPC_URL=https://eth-sepolia.g.alchemy.com/v2/YOUR_KEY_HERESolution: This happens when transactions get out of sync. Reset your account nonce:
cast send --private-key $PRIVATE_KEY --nonce $(cast nonce $YOUR_ADDRESS) --value 0 $YOUR_ADDRESS- All contracts thoroughly tested on testnets
- Security audit completed (for production apps)
- All environment variables verified
- Sufficient ETH for deployment (check gas prices)
- Deploy script tested multiple times on testnet
- Backup of all deployment keys and addresses
- Add mainnet configuration to
.env:
MAINNET_RPC_URL=https://eth-mainnet.g.alchemy.com/v2/YOUR_KEY
PRIVATE_KEY=0xyour_mainnet_deployer_key- Create mainnet deployment task in
Taskfile.yml - Deploy with extreme caution:
task contracts:deploy:mainnet- Use separate wallets: Never use the same wallet for development, testnet, and mainnet
- Environment variables: Keep sensitive data in
.env, never commit - Test thoroughly: Deploy to testnet multiple times before mainnet
- Gas estimation: Check gas prices before deploying on mainnet
- Verification: Always verify contracts after deployment
- Documentation: Document all deployed contract addresses
- Backups: Keep backups of deployment artifacts and addresses
- Foundry Book - Deploying
- Ethereum Gas Tracker
- Chainlist - RPC URLs
- Alchemy Documentation
- Infura Documentation
Need help? Check the Bun-Eth GitHub Discussions or open an issue.