In this article we will provide a detailed guide on how to leverage Foundry for smart contract deployment and verification. Learn how to efficiently verify your contracts on Routescan using Foundry's command-line tools.
Initial Setup
Before creating the project, your environment must be set up correctly.
1. Install Foundry
Foundry is a command-line tool for EVM-compatible blockchain development, managed through foundryup
.
macOS/Linux. Open your terminal and run the following command.
curl -L https://foundry.paradigm.xyz
Then, follow the on-screen instructions, restart terminal or run
source ~/.zshenv
(Zsh shell) orsource ~/.profile
(Bash) and execute command foundryup.Windows. The installation process for Windows has specific requirements. Please follow the up-to-date instructions on the official Foundry website: Foundry Installation Guide
2. Prepare Your Crypto Wallet
You will need a browser extension wallet like MetaMask to hold your test funds and sign transactions. Deployment costs gas, even on a Testnet.
Creating the Foundry Project
1. Initialize the Project
To create and navigate to the new Foundry project, open your terminal and execute the following commands.
forge init my-foundry-project
cd my-foundry-project
2. Project Structure Overview
Foundry creates several folders. The most important are:
/src
: Where your Solidity contract (.sol
files) goes./script
: Where your deployment scripts (.s.sol
files) go./test
: Where your test files (.t.sol
files) go.foundry.toml
: The main configuration file for the project.
Configuring Your Project for Deployment
1. Lock the Compiler Version
To ensure your contracts are always compiled with the exact same compiler version, preventing verification mismatches, open your foundry.toml
file and add the solc
line with corresponding version number.
solc = "0.8.30"
2. Write Your Smart Contract
Go to the
/src
folder and modify the sampleCounter.sol
file or create a new.sol
file.Add the following example smart contract code to
Counter.sol
.// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.30;
contract Counter {
uint256 public number;
function setNumber(uint256 newNumber) public {
number = newNumber;
}
function increment() public {
number++;
}
}
3. Securely Store Your Private Key and RPC URL
You must provide your private key and a network RPC URL to deploy. The best way is using an .env
file.
⚠️ Important Note: Your private key gives total control over your wallet. Never share it.
Option A. Using a .env
File
This method securely stores your key in a file for the project, so you only have to set it up once.
Create the
.env
file in the root of your project folder (my-foundry-project
), named exactly.env
. Or use commandtouch .env
.
ℹ️ Files starting with a dot (`.
`) are hidden by default in macOS/Linux. In the file manager, you can press `Cmd + Shift + .
` to show/hide hidden files.
ℹ️ Windows sometimes hides file extensions. If your file is named `.env.txt
`, go to File Explorer > View tab > check the 'File name extensions' box. Then you can rename the file to remove the `.txt
` part.
Open the
.env
file and add the following, replacing the placeholders.PRIVATE_KEY="YOUR_WALLET_PRIVATE_KEY"
SEPOLIA_RPC_URL="YOUR_SEPOLIA_RPC_URL"
Visit Routescan RPCs page for detailed information about all supported Chain IDs and it’s RPC URLs.
Open the
.gitignore
file and make sure there is.env
line. If not, manually add the line.env
. This prevents your private key from being accidentally uploaded to version control systems like GitHub.
Option B. Using Temporary Terminal Variables
This method sets your secrets (e.g. private key) for your current terminal session only. If you close the terminal, you must run these commands again.
export PRIVATE_KEY="YOUR_WALLET_PRIVATE_KEY"
export SEPOLIA_RPC_URL="YOUR_SEPOLIA_RPC_URL"
Writing the Deployment Script
Navigate to the
/script
folder and modify the sampleCounter.s.sol
file to your needs or create a new.s.sol
file.As example, we will add the following Solidity script to handle the deployment logic.
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.30;
import {Script, console} from "forge-std/Script.sol";
import {Counter} from "../src/Counter.sol";
contract CounterScript is Script {
Counter public counter;
function setUp() public {}
function run() public {
vm.startBroadcast();
counter = new Counter();
vm.stopBroadcast();
}
}
Deploying and Verifying
This process involves three commands: loading your secrets, building the contract, and running the deployment script.
Load Environment Variables. Some terminals (like Git Bash) may not load the
.env
file automatically for shell commands. To be safe, always runsource .env
first.source .env
Build the Contract. Compile your project and create the necessary artifact files.
forge build
Deploy and Verify Automatically. Run the deployment script. The
--verify
flag will automatically send your code to Routescan for verification upon successful deployment.forge script script/Counter.s.sol:CounterScript \
--rpc-url $SEPOLIA_RPC_URL \
--private-key $PRIVATE_KEY \
--broadcast \
--verify \
--verifier-url 'https://api.routescan.io/v2/network/testnet/evm/11155111/etherscan' \
--etherscan-api-key "verifyContract"
Verifying a Pre-Deployed Contract
If auto-verification fails or you need to verify a contract later, use the forge verify-contract
command. First, load your environment file - source .env
or use command export
explained above. And then proceed to the example command below for contract verification.
forge verify-contract YOUR_DEPLOYED_ADDRESS src/Counter.sol:Counter \
--verifier-url 'https://api.routescan.io/v2/network/testnet/evm/11155111/etherscan' \
--etherscan-api-key "verifyContract" \
--compiler-version 0.8.30 \
Practical Tips
Error:
No matching artifact found for [ContractName]
. This means the verification command can't find the compiled file. Runforge clean
to clear the cache, thenforge build
to create fresh artifacts.Error:
Compiler run failed: Source "..." not found
during build. You deleted a source file (.sol
) but not its corresponding test file (.t.sol
). Delete the test file that is causing the error and rebuild.For detailed error logs, add the
vvvv
flag to the end of anyforge
command (e.g.,forge build -vvvv
).To run your project's tests, simply use the command
forge test
.To guarantee an "Exact Match" on verification, the compiler version must be identical everywhere. By setting
solc = "0.8.30"
infoundry.toml
, you force Foundry to use that specific version, preventing unexpected upgrades.To verify contracts that have already been verified (for example, if you wish to have “Exact Match” status instead of a “Partial Match”), use the
--skip-is-verified-check
flag.For rapid development, you can add the
--watch
flag to anyforge
command (likebuild
,test
, orscript
). This will automatically re-run the command whenever you save a change to a relevant file.If your contract requires constructor arguments, you must provide them during verification. For a contract with
constructor(string memory _greeting, uint256 _value)
, you would add the--constructor-args
flag.--constructor-args $(cast abi-encode "constructor(string,uint256)" "Hello" 123)