Getting Started with Foundry

Foundry is a smart contract development toolchain, and user-friendly development environment for writing and testing smart contracts in Solidity. It manages dependencies, compiles, run tests, deploy contracts and allows for interaction with EVM-compatible chains using a command-line tool called Forge.

In this guide, we will learn about Foundry and its benefits for smart contract development, how to setup your environment, create a Foundry project and execute a deployment script.

Why use Foundry?

Forge is ideal for advanced smart contract analysis, auditing, and for fast execution of smart contract tests.

Note: Use the hardhat-foundry plugin to have your Foundry project work alongside Hardhat.

Here are some reason why you may prefer Foundry:

  1. Local Networks:

It provides a local blockchain environment using the anvil tool, allowing developers to deploy contracts, run tests, and debug code. It can also be used to fork other EVM compatible networks.

  1. Advanced Testing:

Forge comes with a number of advanced testing methods including:

  • Fuzz testing
  • Invariant testing
  • Differential testing
  • Symbolic Execution
  • Mutation Testing
  1. Advanced Debugging:

Forge allows for advanced debugging using an interactive debugger.

The debugger terminal is divided into four quadrants:

  • Quadrant 1
    • The opcodes in the debugging session, with the current opcode highlighted. Additionally, the address of the current account, the program counter and the accumulated gas usage is also displayed.
  • Quadrant 2
    • The current stack, as well as the size of the stack
  • Quadrant 3
    • The source view.
  • Quadrant 4
    • The current memory of the EVM.

Getting Started

Prerequisites

To get started with Foundry, ensure the following tools are installed:

  • The Rust Compiler
  • Cargo Package Manager

For an easy installation of the above tools, use the rustup installer.

Installation

To install, use Foundryup. Foundryup is the Foundry toolchain installer. You can find more information in the Foundry README.

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

Running foundryup by itself will install the latest (nightly) precompiled binaries: forge, cast, anvil, and chisel.

Visit the installation guides for more information.

Create a foundry project

To start a new project with Foundry, use forge init.

forge init hello_foundry

See more details on how to create a new project using the Foundry guide.

Write your first contract

Let’s view the file structure for a default foundry project:

$ cd hello_foundry
$ tree . -d -L 1
.
├── lib
├── script
├── src
└── test

4 directories

The src directory contains counter smart contract with test written in the test directory. Now, let's build the foundry project.

forge build

And then run tests.

forge test

Deploy contract on the Rootstock

To deploy the counter contract on Rootstock mainnet or testnet, further configure Foundry by setting up a Rootstock RPC url and a private key of an account that’s funded with tRBTC.

Environment Configuration

Once you have an account with a private key, create a .env file in the root of the foundry project and add the variables.

Foundry automatically loads a .env file present in the project directory.

The .env file should follow this format:

ROOTSTOCK_RPC_URL=https://public-node.testnet.rsk.co
PRIVATE_KEY=0x...

At the root of the project, run:

# To load the variables in the .env file
source .env

Modify Deployment Script

Modify the deployment counter deploy script in the scripts directory to use the private key by modifying the run method, see below example:

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

import {Script, console} from "forge-std/Script.sol";

import "../src/Counter.sol";


contract CounterScript is Script {
    function setUp() public {}

    function run() public {
        vm.startBroadcast(vm.envUint("PRIVATE_KEY"));

        new Counter();

        vm.stopBroadcast();

    }
}

By default, scripts are executed by calling the function named run at the entrypoint.

uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY");
  • CAUTION: Be cautious when exposing private keys in a .env file and loading them into programs.
  • This is only recommended for use with non-privileged deployers or for local / test setups.

When calling vm.startBroadcast(), the contract creation will be recorded by Forge, and we can broadcast the transaction to deploy the contract on-chain.

Execute the deployment script

We will use Forge to run our script and broadcast the transactions - this can take a little while, since Forge also waits for the transaction receipts.

forge script script/Counter.s.sol --rpc-url $ROOTSTOCK_RPC_URL --broadcast --legacy

  • Note:
    • EIP-1559 is not supported or not activated on the Rootstock RPC url
    • The --legacy flag is passed to use legacy transactions instead of EIP-1559.

The result should look like this:

[] Compiling...
No files changed, compilation skipped
Script ran successfully.

== Logs ==
  Counter: 

## Setting up 1 EVM.

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

Chain 31

Estimated gas price: 0.065164 gwei

Estimated total gas used for script: 138734

Estimated amount required: 0.000009040462376 ETH

==========================
##
Sending transactions [0 - 0].
⠁ [00:00:00] [###############################################################################################################################################] 1/1 txes (0.0s)##
Waiting for receipts.
⠉ [00:00:25] [###########################################################################################################################################] 1/1 receipts (0.0s)
##### 31[Success]Hash: 0x015de35ffae94f491d4630f2aec84c49ae8170d5ecf3f4c1cdc8718bc4a00052
Contract Address: 0x64B24E046259042e16a337Be4648CeAAF8Eb72C6
Block: 5071408
Gas Used: 106719

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

ONCHAIN EXECUTION COMPLETE & SUCCESSFUL.
Total Paid: 0. ETH (106719 gas * avg 0 gwei)

Transactions saved to: /hello_foundry/broadcast/Counter.s.sol/31/run-latest.json

Sensitive values saved to: /hello_foundry/cache/Counter.s.sol/31/run-latest.json

The broadcast directory will be updated automatically with the latest output of the deployment.

See the foundry deployment documentation.

Related Docs

Receive updates

Get the latest updates from the Rootstock ecosystem

Loading...