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.
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.
-
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.solExplanation:
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 usingforge test
. - Script folder: Used for deployment and interaction scripts written in Solidity with a
.s.sol
extension, which can be executed withforge script
.
-
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-contractsCreate a file called
GMToken.sol
in thesrc
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 symbolGM
. TheinitialSupply
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.
-
Adding the Soneium Minato network:
Create a
.env
file in your project directory and add the RPC endpoint and Blockscout API URL:.envMINATO_RPC_URL="https://rpc.minato.soneium.org"
MINATO_BLOCKSCOUT_URL="https://soneium-minato.blockscout.com/api/"infoProviding a Blockscout API key is optional for contract verification.
-
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
warningNever share your private key. It grants full access to your wallet.
tipRefer to the MetaMask documentation for instructions on exporting your account's private key.
tipTo use a Ledger or Trezor hardware wallet for this process, refer to the Foundry documentation for detailed instructions on private key management.
-
Writing the deployment script:
Create a file named
GMToken.s.sol
in thescript
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 of1,000,000
tokens. Execution begins with therun
function, the default entry point for Foundry scripts. Thevm.startBroadcast
method records transactions and contract creations, allowing the deployment of ourGMToken
to be broadcast on-chain. Transaction details are logged in thebroadcast
directory by default, though this location can be customized in thefoundry.toml
file. The script ends withvm.stopBroadcast
to finalize the process. You can learn more about Solidity scripting in the Foundry book.
-
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.
-
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!
-
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_URLExample 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.