Skip to main content

Deploying and Verifying Contracts - Foundry

Updated over 3 weeks ago

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) or source ~/.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 sample Counter.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 command touch .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 sample Counter.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 run source .env first.

    source .env
  • Build the Contract. Compile your project and create the necessary artifact files.

    forge build
    Compiling contract via Foundry
  • 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 \
Successful contract verification via Foundry on Routescan

Practical Tips

  • Error: No matching artifact found for [ContractName]. This means the verification command can't find the compiled file. Run forge clean to clear the cache, then forge 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 any forge 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" in foundry.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 any forge command (like build, test, or script). 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)

To achieve even greater automation for your Hardhat and Foundry workflows at scale, explore the capabilities of Catapulta.

Did this answer your question?