Tutorial: Your First Foundry Project

Follow this guide to experience the full Blocktools workflow, from creating a new smart contract to securing, testing, and forecasting its costs.


This tutorial will give you a hands-on feel for how the Blocktools suite works together to create a seamless and powerful development experience. By the end, you'll have the confidence to integrate these tools into your own projects.

Prerequisites

  • Foundry is installed.
  • The Blocktools suite is installed.
  • (Optional but Recommended) An Alchemy API key for connecting to live networks.

Pro Tip: Managing Your API Keys

You'll never need to hardcode a private key or API secret. Blocktools offers three flexible ways to provide your keys, checked in this order of priority:

  1. Command-Line Flag (Highest Priority):
    For one-off use. Example: gas-forecaster deploy ... --api-key YOUR_KEY
  2. Environment Variables (Recommended):
    The best method for most developers. Set them once in your shell's configuration file (e.g., .zshrc, .bash_profile), and all your tools will automatically detect them.
    
    export ALCHEMY_API_KEY="your_alchemy_api_key"
    export ETHERSCAN_API_KEY="your_etherscan_api_key"
                                
  3. Global Config File (Set it and Forget it):
    For a permanent, system-wide setting, you can use a tool's built-in config command. This saves your keys to a central file at ~/.config/blocktools/config.toml where all tools can access them.
    
    # Use this command once to save your key permanently
    $ receipt-parse config set alchemy_api_key YOUR_KEY_HERE
    API key saved successfully.
                                

For this tutorial, we'll assume you have configured your Alchemy key using one of these methods.

Step 1: Create a New Foundry Project

First, let's use Foundry's `forge` command to initialize a new project.

$ forge init my-secure-counter
$ cd my-secure-counter

Foundry creates a default contract at src/Counter.sol. This is the contract we will analyze and improve.

Step 2: Security First with `sol-sentry`

Before we even think about deploying, let's run a security scan on the default contract. A professional workflow always starts with security.

$ sol-sentry scan src/Counter.sol

sol-sentry will immediately find two high-severity issues! It correctly identifies that the `increment()` and `setNumber()` functions are public and change the contract's state without any access control. Anyone could call them.

Let's fix this by implementing the standard `Ownable` pattern. Replace the content of src/Counter.sol with this secure version:


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

contract Counter {
    uint256 public number;
    address public owner;

    constructor() {
        owner = msg.sender;
    }

    modifier onlyOwner() {
        require(msg.sender == owner, "Not the owner");
        _;
    }

    function setNumber(uint256 newNumber) public onlyOwner {
        number = newNumber;
    }

    function increment() public onlyOwner {
        number++;
    }
}
                

Now, run the scan again. You will be greeted with a much better result:

$ sol-sentry scan src/Counter.sol
✅ No issues found. Your project looks safe to deploy.

In just a few seconds, you've identified and fixed a critical security flaw. That's the power of `sol-sentry`.

Step 3: Forecast Costs with `gas-forecaster`

Now that our contract is secure, let's find out what it would cost to deploy it to various networks.

$ gas-forecaster deploy src/Counter.sol

The tool compiles your contract and provides a clean, easy-to-read table of estimated deployment costs in USD across Ethereum, Polygon, Arbitrum, and other major chains. You now have a clear budget before writing a single line of deployment script.

Step 4: Interactive Testing with `sol-console`

It's time to interact with our contract. Instead of writing a complex script, let's use `sol-console` to launch a local test node and get an interactive REPL.


# This one command starts a local node, compiles, and deploys your contract
$ sol-console --contract-path src/Counter.sol --standalone
                    

You are now inside a live console connected to your deployed contract. Let's try calling some functions.


# Check the initial value
contract.number()
<-- Return Value: 0

# Increment the number
contract.increment()
✅ Transaction Confirmed
  - Status: Success
  - Gas Used: ...

# Check the new value
contract.number()
<-- Return Value: 1
                    

This provides an incredibly fast feedback loop for testing and debugging your contract's logic without ever leaving the terminal. Type exit to close the console.

Conclusion & Next Steps

Congratulations! You have successfully used the Blocktools suite to secure, analyze, and test a smart contract from scratch. You've experienced how each tool addresses a specific part of the development lifecycle, working together to make you a more effective and secure Web3 developer.

Now that you have a feel for the workflow, we encourage you to explore the detailed documentation for each tool to learn about their advanced features.