Back

Level Up: Building with Foundry

Written by RH

Sep 09, 2024 · 11 min read

In Level Up, this Foundry module is designed to reduce friction by immediately equipping you with fundamental skills to develop smart contracts on Scroll Sepolia.

In order to facilitate this process, we have curated a simplified structure to help you get started with Foundry on Scroll Sepolia.

If you are feeling adventurous, jump into your code editor and follow along!

Introduction

What is Foundry?

Foundry is a blazingly fast, portable and modular toolkit for Ethereum application development written in Rust.

Why Foundry?

  • Write all your code ONLY in Solidity (i.e. scripts, tests, all in Solidity)!
  • Speedrun your developer journey without having to learn multiple languages.

How Foundry?

Glad you asked 🔥.

Let's dive right in!

[0]: Install Foundry

Foundry is installed using Foundryup.

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

Source your .zshenv file to ensure the path is updated.

source /Users/your_username/.zshenv

To verify the installation, run the following command:

forge --version // forge 0.x.x ... cast --version // cast 0.x.x ...

Additional resource from Foundry Book specific to installation

[1]: Create a Foundry Project

Create a new project and navigate into it.

mkdir foundry-project cd foundry-project

Run forge init in your terminal to create a new Foundry project.

$foundry-project forge init

[2]: Compiling a Foundry Project

In this example, we will use a simple EtherWallet example below:

// SPDX-License-Identifier: MIT pragma solidity ^0.8.24; contract EtherWallet { address payable public owner; constructor() { owner = payable(msg.sender); } receive() external payable {} function withdraw(uint _amount) external { require(msg.sender == owner, "caller is not owner"); payable(msg.sender).transfer(_amount); } function getBalance() external view returns (uint) { return address(this).balance; } }

Rename Contract.sol in src/Contract.sol to EtherWallet.sol.

Delete src/test folder. We will not be using it in this Speedrun lesson.

Run forge build to compile the contract:

$foundry-project forge build

Navigate to the out folder and you will see the compiled contract EtherWallet.json.

[3]: Deploying on anvil

Anvil is a local testnet node shipped with Foundry.

Run anvil in your terminal.

$foundry-project anvil

This command spins up a local server hosted on http://localhost:8545 that runs the test network. (Server URL can vary depending on user environment)

To deploy on anvil, run:

// $foundry-project forge create <NAME CONTRACT> --rpc-url <LOCALHOST> --interactive forge create EtherWallet --rpc-url http://localhost:8545 --interactive

You will be prompted to enter your private key. Go into the anvil terminal, then copy any private key from the terminal.

Paste it in the terminal where you are deploying the contract.

// $foundry-project forge create <NAME CONTRACT> --rpc-url <LOCALHOST> --interactive forge create EtherWallet --rpc-url http://localhost:8545 --interactive // paste anvil private key

After running the command, you should see an output similar to this:

Deployer: 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 Deployed to: 0x5FbDB2315678afecb367f032d93F642f64180aa3 Transaction hash: 0x4b1d82d3d33674496088b5e92e99494280ffcc1f27035269873a5ca04c432c93

[4]: Deploying with Script

Foundry allows you to deploy smart contracts by running a script. Scripts are recognisable through the s.sol extension and stored in /scripts folder.

This is what a script example named DeployEtherWallet.s.sol would look like:

// SPDX-License-Identifier: MIT pragma solidity ^0.8.24; import { Script, console2 } from "forge-std/Script.sol"; import { EtherWallet } from "../src/EtherWallet.sol"; contract EtherWalletScript is Script { function run() external returns (EtherWallet) { vm.startBroadcast(); EtherWallet etherWallet = new EtherWallet(); vm.stopBroadcast(); return etherWallet; } }

Use anvil to simulate onchain transactions.

$foundry-project forge script script/DeployEtherWallet.s.sol --rpc-url http://localhost:8545 --broadcast

Forge simulates the script and —broadcast flag was added to broadcast the transaction.

[5]: Setting up Deployment Environment

There are two ways to do this in Foundry. One is the traditional way of using a .env file and the other is by using Foundry tools. Patrick Collins did an amazing job explaining it here!

We'll start off with explaining the awesome way using Foundry!

Using Foundry Tools

Open your local machine terminal and run:

// cast wallet import <ACCOUNT_NAME> --interactive cast wallet import defaultKey --interactive

You will be prompted to enter your private key and a password to secure <ACCOUNT_NAME>.

REMINDER: We recommend to pass your private key and a password on your computer's terminal and NOT the code editor.

For additional security measures:

Leveled up security - Delete your history by running the following command:

history -c

Godlike security - Run rm <TERMINAL_HISTORY> to delete your terminal history!

rm .bash_history // or rm .zsh_history if you use zsh shell

Finally, run the command below to see the list of all accounts available:

cast wallet list

Using .env File

Create a .env file in the root directory of your project.

$foundry-project touch .env

File contents would look like this:

PRIVATE_KEY=0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef RPC_URL=http://localhost:8545

Load .env file in foundry by running:

$foundry-project source .env

To deploy a contract, you can now run:

$foundry-project forge script script/DeployEtherWallet.s.sol --rpc-url $RPC_URL --broadcast --private-key $PRIVATE_KEY

REMINDER: You should NEVER place a private key or a secret phrase in a .env file that is associated with real funds! This is a HUGE security risk. (If you have not taken the .env pledge, do it NOW!)

[6]: Deploy on Scroll Sepolia Network

Setting up Scroll Sepolia Network & Testnet Funds

We're almost there to deployment!

First let's add the Scroll network to your metamask.

Head over to Scroll Sepolia and add Scroll Sepolia testnet to your wallet.

Note: Check out this quick video on X if you prefer adding Scroll Sepolia via Chainlist

Now that we've added the network to our MetaMask, click here to join Level Up Telegram group for Scroll Sepolia ETH or visit the faucet links in Scroll's Faucet documentation.

If you run into issues with testnet eth, please let us know in the Level Up Telegram group.

Deploying to Scroll Sepolia

Contract deployment uses forge create command.

$foundry-project forge create <CONTRACT_NAME> --rpc-url <NETWORK> --account <ACCOUNT_NAME>

In this case, the command will look like this:

$foundry-project forge create EtherWallet --rpc-url https://sepolia-rpc.scroll.io/ --account defaultKey --broadcast // optional: add -vvv for verbose output (add v's as needed to increase verbosity)

Enter your password and voila! Your contract is deployed on Scroll Sepolia!

If you are updating the RPC_URL in .env, remember to run source .env to reload the environment variable changes.

[7]: Contract Verification

Verifying your contract makes your contract readable on a block explorer like Etherscan or Scrollscan. This also provides a user interface for contract interaction.

You will first need API keys to verify your contract via Foundry. Here's how to do this:

  1. Create an account at https://scrollscan.com/register
  2. Get API Keys from your account

Here's an explainer video if you are stuck.

Update your .env file to include two new variables:

  1. VERIFIER_URL
  2. SCROLLSCAN_API_KEY

Reload the environment variables by running source .env.

The command structure for verifying contract is as follows:

forge verify-contract <CONTRACT_ADDRESS> <CONTRACT_NAME> --verifier-url <BLOCK_EXPLORER_URL> \ --etherscan-api-key <SCROLLSCAN_API_KEY> \ --constructor-args <CONSTRUCTOR_ARGUMENTS> //if any

This is an example of my command with a random contract address:

forge verify-contract 0x998608B4f83249c4217ADb9060Fb739d4A52C6A2 EtherWallet --verifier-url $VERIFIER_URL \ --etherscan-api-key $SCROLLSCAN_API_KEY \

[8]: Contract Interaction

You can interact with your smart contract by using the cast command.

Here is the general structure to using cast:

cast [options] <CONTRACT_FUNCTION> [args]

While there are many options available to interact with contracts, we focus on the two common options: call and send.

call

To retrieve data from the contract in the blockchain:

// Get the balance of the contract $foundry-project cast call 0x998608B4f83249c4217ADb9060Fb739d4A52C6A2 "getBalance()" --rpc-url $RPC_URL

NOTE: Private key does not need to be passed in call command as it does not require any transaction to be sent.

send

To execute function in the contract:

// Send 0.1 Ether to the contract $foundry-project cast send 0x998608B4f83249c4217ADb9060Fb739d4A52C6A2 --value 100000000000000000 --private-key $PRIVATE_KEY --rpc-url $RPC_URL
// Withdraw 0.000099999999999999 Ether $foundry-project cast send 0x998608B4f83249c4217ADb9060Fb739d4A52C6A2 "withdraw(uint)" 99999999999999990 --private-key $PRIVATE_KEY --rpc-url $RPC_URL

Foundry summary

Congratulations! You made it to the end of speedrunning Foundry Smart Contract Development! 🎉

We have learned that:

  • Foundry is a smart contract development toolchain that simplifies the smart contract development.
  • Comes with HUGEEE set of tools to compile, deploy, and interact with smart contracts.

At Level Up, we have identified the five tools that you will commonly use in Foundry. These include:

1. Create a Foundry project

forge init

2. Compiling

forge build

3. Initializing a local blockchain on Foundry

anvil

4. Contract Deployment

forge create <CONTRACT_NAME> --rpc-url <NETWORK> --account <ACCOUNT_NAME>

5. Contract Interaction

cast [options] <CONTRACT_FUNCTION> [args]

Now that you have grasped Level Zero of Foundry, you are ready to dive into the world of smart contract development! 🚀

© 2024 Scroll Foundation | All rights reserved

Terms of UsePrivacy Policy