HackQuest Articles

Deploying Foundry: Complete End-To-End Tutorial for Smart Contract Development

August 15, 2025
General
Deploying Foundry: Complete End-To-End Tutorial for Smart Contract Development
Master Foundry's powerful toolkit with our comprehensive guide covering installation, project setup, testing, and deployment of smart contracts on Ethereum and EVM-compatible chains.

Table Of Contents

Deploying Foundry: Complete End-To-End Tutorial for Smart Contract Development

Foundry has rapidly emerged as one of the most powerful and developer-friendly toolkits in the Ethereum ecosystem. If you're looking to level up your smart contract development skills, Foundry offers a blazingly fast, highly flexible environment that can significantly enhance your workflow. Unlike other development environments, Foundry is built with Rust at its core, providing exceptional speed and a unique testing approach that has won over many experienced developers.

In this comprehensive guide, we'll walk through the entire process of setting up Foundry, creating projects, writing and testing smart contracts, and finally deploying them to the blockchain. Whether you're transitioning from Hardhat or Truffle, or just starting your smart contract development journey, this tutorial will equip you with the knowledge to leverage Foundry's powerful features effectively.

By the end of this tutorial, you'll have a fully functional development environment and the confidence to build, test, and deploy smart contracts using one of the most advanced toolkits available to blockchain developers today.

Foundry Smart Contract Development

Complete End-to-End Development Workflow

Foundry's Powerful Components

Forge

Core testing framework for compiling, testing, and deploying smart contracts

Cast

Command-line tool for interacting with smart contracts and getting chain data

Anvil

Fast local Ethereum node for development and testing environments

Complete Development Workflow

1

Setup & Installation

Install Foundry with a single command using Foundryup and verify the installation of all components.

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

Project Creation

Initialize a new project with a standard structure including configuration files and directories.

forge init my_foundry_project
3

Contract Development

Write smart contracts in the src/ directory and compile them using Forge's build command.

forge build
4

Testing

Write Solidity-native tests in the test/ directory and run them with detailed output options.

forge test -vv
5

Deployment

Create deployment scripts and deploy to local or public networks with automatic verification.

forge script script/Deploy.s.sol --rpc-url $RPC_URL --private-key $PRIVATE_KEY --broadcast

Why Choose Foundry?

Speed

Built with Rust for exceptional performance compared to JavaScript-based alternatives

Solidity-Native Testing

Test contracts in the same language you write them for more intuitive development

Advanced Testing

Powerful fuzz testing and VM cheatcodes for manipulating blockchain state during tests

Ready to master Foundry?

Take your Web3 development skills to the next level with HackQuest's comprehensive learning tracks

Join HackQuest Today

Created by HackQuest - Your path to Web3 development mastery

Understanding Foundry and Its Components

Before diving into installation and setup, let's understand what makes Foundry special and how its components work together to create a powerful development environment.

Foundry is a smart contract development toolkit that includes everything you need to build, test, debug, and deploy Ethereum applications. Built with Rust, it offers exceptional performance compared to JavaScript-based alternatives. The Foundry toolkit consists of several key components:

  1. Forge: The core testing framework that compiles, runs tests, and manages deployments for your smart contracts
  2. Cast: A command-line tool for interacting with EVM smart contracts, sending transactions, and getting chain data
  3. Anvil: A local Ethereum node designed for development, similar to Ganache but significantly faster
  4. Chisel: An interactive Solidity REPL (Read-Eval-Print Loop) for quick experimentation

What sets Foundry apart is its approach to testing - tests are written in Solidity rather than JavaScript. This means you can test your contracts in the same language you write them, leading to a more intuitive development experience and often uncovering edge cases that might be missed in JavaScript tests.

Setting Up Your Development Environment

Let's start by installing Foundry and configuring your development environment. The process is straightforward across most operating systems.

Installing Foundry

The simplest way to install Foundry is using the Foundryup installation script, which handles downloading and installing the latest version of the toolkit.

bash

For Unix-based systems (MacOS, Linux)

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

Then initialize Foundryup

foundryup

For Windows users, you can use Git Bash or WSL (Windows Subsystem for Linux) to run the same commands.

After installation, verify that everything is working correctly by checking the installed versions:

bash forge --version cast --version anvil --version

Installing Additional Dependencies

You'll need a few additional tools to complete your development environment:

  1. Solidity Compiler: Foundry handles this for you
  2. Git: Required for managing project dependencies
  3. Node.js and npm: While not strictly necessary for Foundry, they're useful for frontend integration

bash

Installing Git (if not already installed)

For Ubuntu/Debian

sudo apt update && sudo apt install git

For macOS (using Homebrew)

brew install git

Setting Up VS Code Extensions (Optional)

For the best development experience, we recommend setting up Visual Studio Code with the following extensions:

  • Solidity by Nomic Foundation
  • Solidity Visual Developer
  • Foundry VS Code Extensions

This combination provides syntax highlighting, error checking, and enhanced development features specific to Foundry projects.

Creating Your First Foundry Project

Now that your environment is set up, let's create your first Foundry project.

Initializing a New Project

To create a new project, use the forge init command followed by your project name:

bash forge init my_foundry_project cd my_foundry_project

This command creates a new directory with a standard Foundry project structure:

my_foundry_project/ ├── .git/ ├── .gitignore ├── .gitmodules ├── foundry.toml # Configuration file ├── lib/ # Dependencies ├── script/ # Deployment scripts ├── src/ # Smart contracts └── test/ # Test files

Understanding the Project Structure

Let's examine each component of the project structure:

  • foundry.toml: Configuration file for your Foundry project where you can set compiler versions, optimizer settings, and other project parameters
  • lib/: Contains project dependencies, managed by Forge's dependency system
  • script/: Deployment and other executable scripts
  • src/: Your smart contract source files
  • test/: Test files for your contracts

Configuring Your Project

The foundry.toml file is the heart of your project configuration. Let's look at a basic configuration and customize it for our needs:

toml [profile.default] src = "src" out = "out" libs = ["lib"] solc = "0.8.20" optimizer = true optimizer_runs = 200

[rpc_endpoints] mainnet = "${MAINNET_RPC_URL}" sepolia = "${SEPOLIA_RPC_URL}"

[etherscan] sepolia = { key = "${ETHERSCAN_API_KEY}" }

You can customize this file to specify different compiler versions, optimization settings, and network configurations for your project.

Writing Smart Contracts with Forge

Now let's create a simple smart contract to demonstrate Foundry's capabilities.

Creating a Basic Token Contract

In the src/ directory, create a new file called MyToken.sol:

solidity // SPDX-License-Identifier: MIT pragma solidity ^0.8.20;

contract MyToken { string public name = "MyToken"; string public symbol = "MTK"; uint8 public decimals = 18; uint256 public totalSupply = 1000000 * 10**18;

mapping(address => uint256) public balanceOf;
mapping(address => mapping(address => uint256)) public allowance;

event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);

constructor() {
    balanceOf[msg.sender] = totalSupply;
}

function transfer(address to, uint256 value) public returns (bool success) {
    require(balanceOf[msg.sender] >= value, "Insufficient balance");
    
    balanceOf[msg.sender] -= value;
    balanceOf[to] += value;
    
    emit Transfer(msg.sender, to, value);
    return true;
}

function approve(address spender, uint256 value) public returns (bool success) {
    allowance[msg.sender][spender] = value;
    emit Approval(msg.sender, spender, value);
    return true;
}

function transferFrom(address from, address to, uint256 value) public returns (bool success) {
    require(value <= balanceOf[from], "Insufficient balance");
    require(value <= allowance[from][msg.sender], "Insufficient allowance");
    
    balanceOf[from] -= value;
    balanceOf[to] += value;
    allowance[from][msg.sender] -= value;
    
    emit Transfer(from, to, value);
    return true;
}

}

This is a basic ERC-20-like token contract that we'll use to demonstrate Foundry's testing and deployment capabilities.

Compiling Your Contract

To compile your contract, run:

bash forge build

Foundry will compile your contracts and store the artifacts in the out/ directory. If there are any compilation errors, they will be displayed in the console.

Testing Your Smart Contracts

One of Foundry's standout features is its approach to testing. Tests are written in Solidity, which allows for more direct and powerful testing of your contracts.

Writing Tests in Solidity

Create a new file in the test/ directory called MyToken.t.sol:

solidity // SPDX-License-Identifier: MIT pragma solidity ^0.8.20;

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

contract MyTokenTest is Test { MyToken public token; address public deployer = address(1); address public user1 = address(2); address public user2 = address(3);

function setUp() public {
    vm.startPrank(deployer);
    token = new MyToken();
    vm.stopPrank();
}

function testInitialBalance() public {
    assertEq(token.balanceOf(deployer), token.totalSupply());
}

function testTransfer() public {
    uint256 amount = 1000 * 10**18;
    
    vm.prank(deployer);
    bool success = token.transfer(user1, amount);
    
    assertTrue(success);
    assertEq(token.balanceOf(user1), amount);
    assertEq(token.balanceOf(deployer), token.totalSupply() - amount);
}

function testApproveAndTransferFrom() public {
    uint256 amount = 1000 * 10**18;
    
    vm.startPrank(deployer);
    token.approve(user1, amount);
    vm.stopPrank();
    
    assertEq(token.allowance(deployer, user1), amount);
    
    vm.prank(user1);
    bool success = token.transferFrom(deployer, user2, amount);
    
    assertTrue(success);
    assertEq(token.balanceOf(user2), amount);
    assertEq(token.balanceOf(deployer), token.totalSupply() - amount);
    assertEq(token.allowance(deployer, user1), 0);
}

function testFailTransferInsufficientBalance() public {
    uint256 amount = token.totalSupply() + 1;
    
    vm.prank(deployer);
    token.transfer(user1, amount); // This should fail
}

}

This test file includes several tests that verify our token contract behaves as expected.

Running Tests

To run the tests, use the following command:

bash forge test

You should see output indicating that the tests have passed. Foundry provides detailed information about gas usage and execution traces for each test.

To get more verbose output, you can use:

bash forge test -vv

The -vv flag increases verbosity, showing more details about test execution. You can add more 'v's (like -vvv or -vvvv) for even more detail.

Deploying Smart Contracts with Foundry

Now that we've written and tested our contract, it's time to deploy it to a blockchain network. Foundry offers several ways to handle deployments.

Creating a Deployment Script

First, let's create a deployment script in the script/ directory. Create a file called DeployMyToken.s.sol:

solidity // SPDX-License-Identifier: MIT pragma solidity ^0.8.20;

import "forge-std/Script.sol"; import "../src/MyToken.sol";

contract DeployMyToken is Script { function run() external { uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY");

    vm.startBroadcast(deployerPrivateKey);
    
    MyToken token = new MyToken();
    console.log("MyToken deployed at:", address(token));
    
    vm.stopBroadcast();
}

}

This script reads a private key from the environment variables and uses it to deploy our token contract.

Setting Up Environment Variables

Before deploying, create a .env file in your project root with your private key and RPC URLs:

PRIVATE_KEY=your_private_key_here_without_0x_prefix SEPOLIA_RPC_URL=https://sepolia.infura.io/v3/your_infura_key MAINNET_RPC_URL=https://mainnet.infura.io/v3/your_infura_key ETHERSCAN_API_KEY=your_etherscan_api_key

Make sure to add .env to your .gitignore file to avoid exposing your private keys.

Deploying to a Local Network

First, let's test the deployment on a local Anvil network. Open a new terminal and start Anvil:

bash anvil

This will start a local Ethereum node with several pre-funded accounts. Take note of one of the private keys displayed.

In another terminal, deploy your contract to the local network:

bash forge script script/DeployMyToken.s.sol --rpc-url http://localhost:8545 --private-key <private_key_from_anvil> --broadcast

Deploying to a Testnet

Once you've confirmed the deployment works locally, you can deploy to a testnet like Sepolia:

bash source .env forge script script/DeployMyToken.s.sol --rpc-url $SEPOLIA_RPC_URL --private-key $PRIVATE_KEY --broadcast --verify --etherscan-api-key $ETHERSCAN_API_KEY

The --verify flag will automatically verify your contract on Etherscan, making the source code publicly viewable.

Verifying Contract Deployment

After deployment, you should see output with the transaction hash and contract address. You can verify the deployment by checking the contract address on Etherscan or by using Cast to interact with your contract:

bash cast call <contract_address> "name()" --rpc-url $SEPOLIA_RPC_URL

This should return your token's name, confirming that the contract was deployed successfully.

Advanced Foundry Features

Now that you've mastered the basics, let's explore some of Foundry's more advanced features that can enhance your development workflow.

Fuzz Testing

Foundry excels at fuzz testing, which automatically generates random inputs to test your contracts. Modify your test file to include a fuzz test:

solidity function testFuzzTransfer(uint256 amount) public { // Bound the amount to something reasonable vm.assume(amount > 0 && amount <= token.totalSupply());

vm.prank(deployer);
bool success = token.transfer(user1, amount);

assertTrue(success);
assertEq(token.balanceOf(user1), amount);
assertEq(token.balanceOf(deployer), token.totalSupply() - amount);

}

Using Cheatcodes

Foundry provides "cheatcodes" through the VM interface that let you manipulate the blockchain state during tests. We've already used some (vm.prank, vm.startPrank), but there are many more:

solidity function testTimeManipulation() public { // Skip forward in time vm.warp(block.timestamp + 1 days);

// Do something time-dependent
// ...

// Advance block number
vm.roll(block.number + 100);

}

Debug Traces

When a test fails, you can use Foundry's debug traces to understand exactly what went wrong:

bash forge test --match-test testFailTransferInsufficientBalance -vvvv

This will show a detailed execution trace that helps pinpoint the issue.

Using Cast for Contract Interaction

Cast is Foundry's command-line tool for interacting with smart contracts. You can use it to call functions, send transactions, and query blockchain data:

bash

Call a read function

cast call <token_address> "balanceOf(address)"

--rpc-url $SEPOLIA_RPC_URL

Send a transaction

cast send <token_address> "transfer(address,uint256)" <recipient_address> 1000000000000000000 --private-key $PRIVATE_KEY --rpc-url $SEPOLIA_RPC_URL

Troubleshooting Common Issues

Even with a powerful toolkit like Foundry, you may encounter some common issues during development. Here's how to troubleshoot them:

Dependency Management Issues

If you're having trouble with dependencies, try:

bash forge update # Update all dependencies forge remove # Remove a dependency forge install # Reinstall a dependency

Gas Estimation Errors

If you encounter gas estimation errors during deployment, you can specify a gas limit:

bash forge script script/DeployMyToken.s.sol --gas-limit 3000000 --broadcast

Solidity Version Conflicts

If you encounter compiler version conflicts, you can specify the version in your foundry.toml file:

toml [profile.default] solc = "0.8.20" # Specify exact version

RPC Connection Issues

If you're having trouble connecting to an RPC endpoint, verify your URL and network status:

bash cast chain-id --rpc-url $SEPOLIA_RPC_URL # Should return the chain ID if connection is working

Next Steps in Your Foundry Journey

Congratulations! You've successfully set up Foundry, created a project, written and tested a smart contract, and deployed it to a blockchain network. Here are some next steps to continue your Foundry journey:

Explore More Complex Projects

Try building more complex projects with multiple contracts and dependencies. Foundry excels at managing complex project structures.

Integrate with Frontend Applications

Connect your deployed contracts to a frontend application using libraries like ethers.js or web3.js.

Participate in the Foundry Community

Join the Foundry community on Discord and GitHub to learn from other developers and stay updated on new features.

Contribute to Foundry

Foundry is an open-source project. Consider contributing by reporting bugs, improving documentation, or adding features.

Practice with Real-World Examples

Study real-world projects built with Foundry to learn best practices and advanced techniques. Many leading DeFi protocols now use Foundry for their development needs.

Deep dive into leading ecosystems and become a certified developer to expand your knowledge and skills in blockchain development.

Conclusion

Foundry represents a significant evolution in Ethereum development tooling, offering a powerful, Rust-based alternative to JavaScript frameworks like Hardhat and Truffle. Its speed, Solidity-native testing approach, and comprehensive toolkit make it an excellent choice for serious smart contract developers.

In this guide, we've covered the complete workflow for smart contract development with Foundry:

  1. Setting up your development environment with Foundry's components
  2. Creating and configuring a new Foundry project
  3. Writing smart contracts and compiling them with Forge
  4. Testing contracts using Solidity-based tests
  5. Deploying contracts to local and public networks
  6. Exploring advanced features like fuzz testing and cheatcodes
  7. Troubleshooting common issues

By mastering Foundry, you've added a valuable skill to your blockchain development toolkit that will make you more efficient and effective at building smart contracts and decentralized applications.

Remember that blockchain development is a rapidly evolving field, and staying updated with the latest tools and techniques is essential. Continue learning, experimenting, and building to deepen your expertise.

Ready to take your Web3 development skills to the next level? Join HackQuest today to access our comprehensive learning tracks, interactive tutorials, and vibrant developer community. From blockchain fundamentals to advanced smart contract development, we'll guide you through every step of your Web3 journey with hands-on projects and expert instruction. Become a certified blockchain developer and unlock exciting career opportunities in the decentralized future!