EVM Developer Tools Explained + Foundry Setup
I’m currently open to collaborations and development projects across blockchain, smart contracts, and full-stack systems, feel free to connect if you’re building something interesting
Before diving into bytecode and raw EVM traces, it’s worth looking at the developer tools that make this kind of exploration possible.
Every modern Ethereum framework: Foundry, Hardhat, Tenderly, Blockscout. Builds on the same foundation: EVM traces. These traces capture every opcode executed, every internal call, and every gas unit spent, allowing developers to test, debug, and understand exactly what their contracts are doing.In this Post you will learn about:
Foundry
Hardhat
Tenderly
Blockscout
In this post, we’ll compare how these tools use traces in practice and then set up a local debugging environment with Foundry, so you can deploy, test, and inspect contracts step by step no mainnet transactions required.
Developer Tools for EVM
Before we dive into raw EVM internals, it’s worth looking at how real developer tools use traces in practice and what problems those traces help solve.
Most smart contract tooling today depends on traces to inspect transactions at a low level: how they executed, where they failed, what internal calls they made, and how state was modified. Whether you’re running tests, debugging reverts, or analyzing contracts post-deployment, you’re almost always relying on trace data behind the scenes.
A trace shows:
Every opcode that was executed
The stack, memory, and program counter (PC) at each step
When sub-calls (like external contract calls) occurred
What storage was read or written
Where and why a revert happened (if it did)
Let’s look at how some of the most popular tools in the ecosystem make use of EVM traces:
Foundry → Fast, CLI-native framework for developing and testing smart contracts. It uses EVM traces to simulate and analyze transactions during tests, making it easy to catch errors, understand failures, and verify contract behavior before deployment. Foundry gives you this visibility locally without needing to deploy or wait for on-chain execution. It’s designed to let developers build confidently and debug efficiently, with trace data deeply integrated into the testing workflow. Network fork and impersonation available locally.
Hardhat → Flexible development environment that uses EVM traces primarily through plugins and internal dev tooling. While it doesn’t expose traces directly by default, it leverages them to enhance test feedback surfacing error messages, stack traces, and call data when transactions fail. Network fork and impersonation available locally.
Tenderly → Visual platform for simulating and debugging smart contract transactions. It uses EVM traces to reconstruct execution in a rich UI — showing opcodes, stack values, memory, storage diffs, and gas costs at every step. Tenderly supports network forking, allowing you to simulate transactions against a snapshot of mainnet or supported testnets in an isolated environment. While it doesn’t offer the same local control as Foundry or Hardhat, it provides powerful simulation capabilities through the browser or API — including the ability to test changes, impersonate accounts, and preview gas usage without sending real transactions. It’s especially useful for inspecting live transaction behavior and debugging complex contracts post-deployment.
Blockscout → This is a block explorer for Ethereum-compatible chains. It uses traces to display internal contract calls, nested execution flows, and value transfers that aren’t visible in the basic transaction list. Works on already-mined transactions and doesn’t provide simulation. Its role is observational: helping developers and users understand what happened inside a given transaction after it’s been confirmed.
All of these tools rely on EVM traces but they use them in different ways.
Foundry and Hardhat bring traces into your local workflow, giving you control over execution, state, and impersonation for fast, iterative testing.
Tenderly offers a visual simulation platform with support for network forking, account impersonation, and deep trace inspection — but through a hosted UI or API rather than local control.
Blockscout focuses on trace visualization, not simulation — it’s great for inspecting already-mined transactions, but doesn’t let you fork or test hypotheticals.
In the rest of this post, we’ll be using Foundry, which gives us complete trace visibility in a local, scriptable environment perfect for understanding how the EVM really works.
Deploying Locally with Foundry: From Setup to Contract
let’s start from zero and set up Foundry, deploy a contract, and simulate a transaction locally.
pragma solidity ^0.8.12;
contract Storage {
struct my_storage_struct {
uint256 number;
string owner;
}
my_storage_struct my_storage;
function store(my_storage_struct calldata new_storage) public {
if (new_storage.number > 100) {
revert(”Number too large”);
}
my_storage = new_storage;
}
function retrieve() public view returns (my_storage_struct memory){
return my_storage;
}
}Before we can trace anything lets do this walkthrough that assumes you have basic command-line experience and git installed.
Step 1: Install Foundry
Foundry provides a fast CLI for testing, deploying, and interacting with smart contracts. Install it with:
curl -L https://foundry.paradigm.xyz | bash
foundryupThis installs forge (test runner), cast (transaction + RPC CLI), and anvil (local EVM node)
forge --version
cast --version
anvil --versionStep 2: Initialize a New Project
mkdir evm-trace-demo
cd evm-trace-demo
forge initThis gives you:
src/folder for contractstest/folder for testsscript/folder for solidity scriptsfoundry.tomlconfig file
Step 3: Write the Contract
Inside src/Storage.sol, paste the contract from above.
Step 4: Compile the Contract
run forge build . You should see no errors and a generated out/Storage.sol/Storage.json ABI artifact.
Step 5: Launch a Local Node
Start Anvil, Foundry’s local EVM by running the command:
anvilThis will spin up a local fork-compatible chain and give you 10 pre-funded test accounts with their private key listed in the same order.
Note: Note the first private key and address printed we’ll use them to deploy,
and you will see that our newly forked chain running on
http://localhost:8545
Step 6: Deploy the Contract
Deploy the contract with forge :
forge create src/Storage.sol:Storage \
--rpc-url http://localhost:8545 \
--private-key <your-key> \
--broadcastThe output should look like:
[⠊] Compiling...
[⠒] Compiling 1 files with Solc 0.8.30
[⠢] Solc 0.8.30 finished in 37.11ms
Compiler run successful!
Deployer: <your-address>
Deployed to: <the-address-of-the-smart-contract>
Transaction hash: <some-tx-hash>Note:
<your-key>is one of the keys printed in the previous terminal.
Without--braodcastforge will just dry-run without deploying on anvil.
This completes your local setup. At this point, you have:
A contract compiled and deployed
A local node running
Full control over transactions, storage, and tracing
Next, we’ll simulate a call to the store() function and explore how the EVM processes that call step by step.
Summary
EVM traces power modern Ethereum tooling. This post compared Foundry, Hardhat, Tenderly, and Blockscout, then walked you through spinning up a local Foundry lab: install, init, build, run Anvil, and deploy. So you can test and inspect transactions step by step without touching mainnet.

