Skip to main content

Foundry

Overview​

Foundry is a blazing-fast, portable, and modular toolkit for Ethereum application development, written in Rust. This tutorial demonstrates how to deploy a smart contract to the Soneium Minato testnet with Foundry, using an ERC-20 token contract as an example.

Foundry consists of four primary tools:

  • Forge: An Ethereum testing framework, similar to Truffle, Hardhat, and DappTools.
  • Cast: Swiss army knife for interacting with EVM smart contracts, sending transactions and getting chain data.
  • Anvil: Local Ethereum node, akin to Ganache, Hardhat Network.
  • Chisel: Fast, utilitarian, and verbose solidity REPL.

For more in-depth information please refer to the official Foundry documentation.

info

In this tutorial, you will deploy a contract to the Soneium Minato testnet. Ensure your wallet contains Sepolia ETH. You can fund your wallet using one of the faucets listed here.

Installing Foundry​

Foundryup is the official installer for the Foundry toolchain. To install it, run the following command in your terminal:

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

After installation, run foundryup to fetch the latest Foundry builds. For detailed instructions, refer to the installation guide.

Creating a Foundry Project​

In this section, you will initialize a new Foundry project and use the OpenZeppelin contracts library to create a basic ERC-20 token.


  1. Initializing a new project:

    Run the following command to create a new project called gm_soneium:

    forge init gm_soneium

    This creates a folder structure as shown below:

    πŸ“gm_soneium
    β”œβ”€β”€ README.md
    β”œβ”€β”€ foundry.toml
    β”œβ”€β”€ πŸ“lib
    β”‚ └── πŸ“forge-std
    β”œβ”€β”€ πŸ“script
    β”‚ └── Counter.s.sol
    β”œβ”€β”€ πŸ“src
    β”‚ └── Counter.sol
    └── πŸ“test
    └── Counter.t.sol

    Explanation:

    • foundry.toml: Configuration file for Foundry projects, allowing you to define compiler settings, dependencies, and more.
    • Source folder: Contains your Solidity contracts. By default, it includes the example Counter.sol.
    • Test folder: Stores test files written in Solidity with a .t.sol extension. Run tests using forge test.
    • Script folder: Used for deployment and interaction scripts written in Solidity with a .s.sol extension, which can be executed with forge script.

  1. Setting up an ERC-20 contract:

    Navigate to the gm_soneium directory and add the OpenZeppelin Contracts v5 library to your Foundry project:

    cd gm_soneium
    forge install OpenZeppelin/openzeppelin-contracts

    Create a file called GMToken.sol in the src folder and add the following code:

    src/GMToken.sol
    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.20;

    import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";

    contract GMToken is ERC20 {
    constructor(uint256 initialSupply) ERC20("GoMainstream", "GM") {
    _mint(msg.sender, initialSupply);
    }
    }

    This contract implements a basic ERC-20 token named GoMainstream with the symbol GM. The initialSupply of tokens is minted to the deployer's address upon deployment.

    Remove the default example files to clean up your project:

    rm src/Counter.sol test/Counter.t.sol script/Counter.s.sol

Setting Up the Deployment Configuration​

Next, you will configure your Foundry project to deploy smart contracts to the Soneium Minato testnet.


  1. Adding the Soneium Minato network:

    Create a .env file in your project directory and add the RPC endpoint and Blockscout API URL:

    .env
    MINATO_RPC_URL="https://rpc.minato.soneium.org"
    MINATO_BLOCKSCOUT_URL="https://soneium-minato.blockscout.com/api/"
    info

    Providing a Blockscout API key is optional for contract verification.


  1. Importing your deployment wallet:

    Use the following command to securely import your private key into Foundry's keystore. You will be prompted for your private key and a password:

    cast wallet import deployer --interactive

    Verify that the wallet is properly set up:

    cast wallet list
    warning

    Never share your private key. It grants full access to your wallet.

    tip

    Refer to the MetaMask documentation for instructions on exporting your account's private key.

    tip

    To use a Ledger or Trezor hardware wallet for this process, refer to the Foundry documentation for detailed instructions on private key management.


  1. Writing the deployment script:

    Create a file named GMToken.s.sol in the script folder and add the following deployment script:

    script/GMToken.s.sol
    // SPDX-License-Identifier: UNLICENSED
    pragma solidity ^0.8.20;

    import {Script} from "forge-std/Script.sol";
    import {GMToken} from "../src/GMToken.sol";

    contract GMTokenDeploymentScript is Script {
    // Define the initial supply for the GMToken
    uint256 public constant INITIAL_SUPPLY = 1_000_000 * 10**18; // 1 million tokens with 18 decimals

    function run() external {
    // Begin broadcasting transactions
    vm.startBroadcast();

    // Deploy the GMToken contract with the initial supply
    GMToken gmToken = new GMToken(INITIAL_SUPPLY);

    // End broadcasting transactions
    vm.stopBroadcast();
    }
    }

    This script deploys the GMToken contract with an initial supply of 1,000,000 tokens. Execution begins with the run function, the default entry point for Foundry scripts. The vm.startBroadcast method records transactions and contract creations, allowing the deployment of our GMToken to be broadcast on-chain. Transaction details are logged in the broadcast directory by default, though this location can be customized in the foundry.toml file. The script ends with vm.stopBroadcast to finalize the process. You can learn more about Solidity scripting in the Foundry book.


  1. Loading environment variables:

    Run the following command to load the .env variables into your terminal session:

    source .env

Deploying and Verifying the Contract​

In this section, you will build the ERC-20 contract, deploy it to the Soneium Minato testnet, and verify it on the Blockscout explorer.


  1. Building your project:

    Compile the project to ensure all contracts are error-free:

    forge build

    Example Output:

    [⠊] Compiling...
    [β ’] Compiling 6 files with Solc 0.8.28
    [β †] Solc 0.8.28 finished in 117.18ms
    Compiler run successful!

  1. Deploying and verifying your contract:

    Run the following command to deploy the contract to Soneium Minato and verify it:

    forge script script/GMToken.s.sol:GMTokenDeploymentScript \
    --account deployer \
    --broadcast \
    --rpc-url $MINATO_RPC_URL \
    --verify \
    --verifier blockscout \
    --verifier-url $MINATO_BLOCKSCOUT_URL

    Example Output:

    ## Setting up 1 EVM.
    ==========================

    Chain 1946
    Estimated gas price: 0.001000512 gwei
    Estimated total gas used for script: 702965
    Estimated amount required: 0.00000070332491808 ETH

    ==========================

    ##### soneium-minato-testnet
    βœ… [Success] Hash: 0x3e63159fa825293021a64d15151c8851e8b22532115f823a08605298a12d5bec
    Contract Address: 0x11Dd690704f13DB26e6aD2ECADa375b038b66149
    Block: 5068007
    Paid: 0.000000540881430208 ETH (540743 gas * 0.001000256 gwei)

    βœ… Sequence #1 on soneium-minato-testnet | Total Paid: 0.000000540881430208 ETH (540743 gas * avg 0.001000256 gwei)

    ==========================

    ONCHAIN EXECUTION COMPLETE & SUCCESSFUL.
    ##
    Start verification for (1) contracts
    Start verifying contract `0x11Dd690704f13DB26e6aD2ECADa375b038b66149` deployed on soneium-minato-testnet
    Compiler version: 0.8.28
    Optimizations: 200
    Constructor args: 00000000000000000000000000000000000000000000d3c21bcecceda1000000

    -snip-

    Contract verification status:
    Response: `OK`
    Details: `Pass - Verified`
    Contract successfully verified
    All (1) contracts were verified!

Congratulations, you just deployed and verified a contract on Soneium Minato using Foundry.