Foundry: Smart Contract Development Toolk

Foundry: Smart Contract Development Toolk

·

7 min read

Foundry is easy to use and has added benefits over other smart contract development frameworks. First it's VERY fast. Secondly, where Foundry especially makes a difference is for testing. You can write tests in Solidity, which streamlines the testing process, a crucial and often overlooked part of the software development cycle.

This post is overdue; I've been interested in Foundry for a long time and decided to put this post to cover the basics & provide a quick starter.

In this post, I want to answer the following:

  • Introduction to Foundry: what & why?

  • How to get started w/Foundry: create, deploy and test smart contracts in Solidity

  • Pros & Cons

Let's get to it!

👉 Here's the Foundry Book and Github Repo.


Intro to Foundry

Foundry is a toolkit for Ethereum application development written in Rust. It's a framework for testing, debugging and deploying Solidity smart contracts.

Foundry is created by Paradigm, an investment firm focused on web3/crypto.

Foundry_Ink_2-1024x516.jpeg

Before getting hands-on with Foundry, let's provide a primer and some pointers on why Ethereum app developers should care about it.

Why use Foundry?

  • You can write tests in Solidity (when using Hardhat or other smart contract development frameworks, you would generally write the tests in Javascript. Writing smart contracts in Solidity streamlines the testing process. You can read on why you should be writing tests in Solidity here. It's much easier to write tests in the same language as your smart contract.

  • Built-in Fuzzing. Fuzzing is a software testing technique that refers to giving random data as inputs. You can use fuzzing with Foundry for extensive testing.

  • Can personally testify that it's really fast. You can read about how it compares to other frameworks over here.

About Foundry

Foundry is a toolkit similar to Hardhat or Truffle for Ethereum.

Foundry is a smart contract development toolchain.

Foundry manages your dependencies, compiles your project, runs tests, deploys, and lets you interact with the chain from the command-line and via Solidity scripts.

Foundry consists of 3 main CLI tools:

  • Forge: compile, test, and deploy your smart contracts

  • Cast: interact with EVM smart contracts (send transactions and get chain data)

  • Anvil : spin up a local node (like hardhat node) This is optional and can be used for a local blockchain environment

Here's a curated list of Foundry resources including tools, tutorials, libraries & projects using Foundry.


Build, Test & Deploy Smart Contracts w/Foundry

Tools

Installation

On Linux and macOS:

  1. Run the command below to get the Foundry toolchain installer
curl -L https://foundry.paradigm.xyz | bash
  1. On a new terminal run the command below to install Foundry:
foundryup

You can verify that the installation went well by running the following commands:

forge --help
anvil --help
cast --help

On Windows:

You need to build from source to install Foundry. You can checkout the latest instructions over here.

Getting Started w/Foundry

  1. Initialize a new project
forge init foundry-example

This will create a new project folder called foundry-example. 
Lets look into the folder structure:

  • src: default directory for your smart contracts.

  • tests: default directory for tests.

  • foundry.toml: project configuration file.

  • lib: contains the dependencies.

  • script: solidity scripting files.

There's a sample smart contract that has a "number" variable that can be set by the setNumber function and incremented by the increment function.

  1. Compile the smart contract from the project directory.
 cd foundry-example
 forge build

Notice that this will create a new folder called out which contains the ABI's of the smart contracts. (The command will also create a cache folder.)

  1. Checkout the test file in test/Counter.t.sol and run the tests.
 forge test

If all goes well the tests should pass. Notice how fast the tests & compile happened, you can also see the gas cost being printed.

Screen Shot 2022-10-27 at 09.36.29.png

You can make changes to the tests to observe a test that fails. (I've modified the testSetNumber to return a specific number by default.)

Screen Shot 2022-10-27 at 09.38.54.png

  1. Foundry can be used to deploy a smart contract using Solidity.

Here's more details on solidity scripting and deployment options.

First we'll be deploying the contract to the Goerli Testnet, you'll need some Goerli ETH for this step. From your crypto wallet get your private key. This is the account from which we will be deploying the smart contract from. Let's use environmental variables to store the private key.

export privateKey=abc123

Now we can deploy the smart contract, here's the CLI command:

forge create --rpc-url https://rpc.ankr.com/eth_goerli --private-key $privateKey src/Counter.sol:Counter

I'm using the instant Ankr RPC endpoint. You also create an account on Alchemy or Infura to get an RPC endpoint.

If all goes well the command will print the details of the deployed contract, you can check it out on the Goerli Block Explorer.

You can checkout forge --help for other commands to use, for example:

  • forge script : to deploy and verify a smart contract

  • forge verify-contract : to verify the contract on Etherscan

Fuzzing

Fuzzing is a software testing technique in which instead of specifying static inputs to a function, fuzzed tests will give random values as inputs.

Head over to test/Counter.t.sol file. I've added a new function called "testSetNumberStatic()" with a static input to compare it with a fuzz test.

Here's how the updated file looks like:

// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.13;

import "forge-std/Test.sol";
import "../src/Counter.sol";

contract CounterTest is Test {
    Counter public counter;

    function setUp() public {
        counter = new Counter();
        counter.setNumber(0);
    }

    function testIncrement() public {
        counter.increment();
        assertEq(counter.number(), 1);
    }

    function testSetNumber(uint256 x) public {
        counter.setNumber(x);
        assertEq(counter.number(), x);
    }

    function testSetNumberStatic() public {
        testSetNumber(5);
    }
}

Now lets run the tests with the following command:

forge test

Screen Shot 2022-10-27 at 11.34.00.png

From the output, we can see that the setNumber() function ran 256 times with different inputs in contrast to our testSetNumberStatic(), which ran once with the given input.

Anvil for Local Testing

You can use anvil for local testing. It's a local Ethereum node designed for forge.

anvil --help gives you the details on the usage and commands.

  1. On a new terminal, spin up an Anvil node
anvil
  1. Now on a new terminal let's use environmental variables to store the local private key. Get one of the private keys from the previous terminal. You can also use an .env file to store the private key.
export localPrivateKey=abc123
  1. Deploy the contract to anvil.
forge create --private-key $localPrivateKey src/Counter.sol:Counter

You'll see the transaction details on both the two terminals.

Screen Shot 2022-10-27 at 10.25.32.png

Interacting w/Smart Contracts using Cast

Cast allows making Ethereum RPC calls. With cast, you can interact with the smart contract to get on-chain data.

Checkout cast --help for more details on what you do.

Here's an example command on how you can get the total balance on the USDT contract.

cast call 0xdac17f958d2ee523a2206206994597c13d831ec7 "totalSupply()(uint256)" --rpc-url https://eth-mainnet.alchemyapi.io/v2/Lc7oIGYeL_QvInzI0Wiu_pOZZDEKBrdf

Basically, you can go to Etherscan, get the contract address, search for the available functions, and then run the command above with the new inputs.

You can also get a gas estimation with the command below; I've run an estimation on the Counter contract I deployed to Goerli in the previous step:

cast estimate 0x5fe5a74b7628c43514DB077d5E112cf6593ed8D3 "increment()" --rpc-url https://rpc.ankr.com/eth_goerli

Pro's/Con's of Foundry

These are just some of my pros/cons of using Foundry:

Pros:

  • It makes testing way more convenient. Before going to the deployment environment, you can use Foundry for excessive testing. You can quickly test other smart contracts.

  • Speed. Lot faster compared to Hardhat; that's the primary Ethereum development toolkit I've been using.

Con's:

  • Hardhat can be better for deployment scripts, especially if you're used to Javascript. Worth noting that I'm just used to deploying smart contracts in Hardhat.

  • Not many educational materials and tutorials, most education material uses Hardhat. This can also be seen as an opportunity for those interested in building the material. (Really impressed that Damn Vulnerability DeFi has a Foundry Version)

  • Hardhat has a large ecosystem and established tools. Foundry has yet to create more integrations and a developer community.

I could see cases where I would want to use Foundry and other cases where I'd want to use Foundry.


Foundry provides a fast and efficient framework for testing and auditing. Smart contract security is one of the most crucial topics, and Foundry has a very important role here.

This was a brief overview of Foundry. You can do a lot more, and I recommend you head over to the repo and Foundry book to learn more.

I hope that this was helpful! If you have any questions, please drop them below. Catch you on the next one!

6yilkq.jpeg