Back to Blog

Foundry Anvil: Complete Guide to Local Ethereum Node, Mainnet Forking & JSON-RPC Cheatcodes


TL;DR: Anvil is Foundry's high-performance local Ethereum node built for smart contract development. It ships with 10 pre-funded accounts (10,000 ETH each), three mining modes (instant, interval, manual), and mainnet forking that can be pinned to any block number. Advanced features include account impersonation, custom JSON-RPC cheatcodes (anvil_setBalance, anvil_snapshot, anvil_impersonateAccount), and persistent state serialization for reproducible test environments.

Table of Contents


Foundry is a key tool for working with smart contracts in Solidity and EVM networks. Foundry provides a set of tools to facilitate the development, testing, and deployment of smart contracts. One of these tools is Anvil.

Anvil is a local Ethereum node that runs on your machine. It is designed to be fast and lightweight. It allows developers to test and debug their smart contracts locally without needing to connect to a remote Ethereum network. Anvil provides a set of features that make it easy to work with smart contracts, such as instant mining, automatic account creation, and support for multiple networks. In this post, we will explore some examples of how to use Anvil in real-world scenarios.

Anvil examples


In this section, we will see some practical examples of how to use Anvil in different scenarios.

If you want to copy the commands, just click on the command box and it will be copied to your clipboard.


Basic initialization


The simplest scenario is to run Anvil with the default configuration. This will start a local Ethereum node on your machine with default settings. You can do this by running the following command in your terminal:

anvil

This command will create a local Ethereum node that listens on http://127.0.0.1:8545 and it will create accounts with pre-funded Ether for testing purposes. The chainId will be 31337 by default. Specifically, here are the main default parameters:

Default Configuration:

  • RPC endpoint: http://127.0.0.1:8545
  • ChainId: 31337
  • Accounts created: 10 pre-funded accounts (all of them corresponding to the same mnemonic)
  • Initial balance per account: 10,000 ETH
  • Block time: Instant mining (0 seconds)
  • Gas limit: 30,000,000
  • Base fee: 1 gwei
  • Genesis block timestamp: Current time
  • Genesis block number: 0

These defaults are ideal for rapid development and testing without waiting for block confirmations. You can use this network to deploy and test your smart contracts locally, to connect your dApps, or to run scripts that interact with the blockchain.

Custom initialization flags


Anvil exposes a rich set of CLI flags to tailor the local node to your exact needs. The most commonly used options are:

| Flag | Default | Purpose | |------|---------|----------| | --chain-id <ID> | 31337 | Custom chain ID for the local network | | --accounts <N> | 10 | Number of dev accounts to generate | | --balance <ETH> | 10000 | Initial ETH balance per account | | --mnemonic <PHRASE> | Random | BIP-39 mnemonic for deterministic accounts | | --block-time <SECS> | 0 (instant) | Mine a block every N seconds | | --no-mining | — | Disable auto-mining; use evm_mine manually | | --gas-limit <GAS> | 30000000 | Per-block gas limit | | --base-fee <GWEI> | 1 | Base fee override (set to 0 for gasless txs) | | --port <PORT> | 8545 | RPC port to bind | | --host <HOST> | 127.0.0.1 | RPC host (use 0.0.0.0 for LAN access) |

Example — zero-cost local network with 20 accounts:

anvil --chain-id 1337 --accounts 20 --balance 50000 --base-fee 0

This configuration is ideal when testing scripts that perform many transactions, since the zero base fee eliminates any ETH balance concern.

Mining modes


Anvil supports three distinct mining modes, each suited to different testing scenarios:

1. Instant mining (default)

Every transaction is mined immediately in its own block. This is the fastest mode and the default when no --block-time flag is supplied. It is ideal for unit tests and Forge test suites where speed matters most.

2. Interval mining

A new block is produced every N seconds, simulating realistic block cadence. Useful for testing time-dependent logic such as staking rewards, vesting schedules, or auction deadlines.

anvil --block-time 12

This mimics post-Merge Ethereum's 12-second slot time. Use --block-time 2 for Polygon-like chains.

3. Manual (on-demand) mining

Disable auto-mining entirely and trigger block production yourself via evm_mine. This gives full control over transaction ordering and block inclusion:

anvil --no-mining

Then trigger a block with Cast:

cast rpc evm_mine --rpc-url http://127.0.0.1:8545

Forking real networks


One of the most common use cases of Anvil is to fork real blockchain networks. This allows you to create a local copy of the state of a real network, such as Mainnet, Goerli, or Sepolia.

In the following example, we will fork the Ethereum Mainnet using an RPC URL from a public provider. You can replace the URL with your own provider if you have one.

anvil --fork-url https://eth.blockrazor.xyz

In the following image, there is an example of the output you will get when you run this command. You can see that Anvil is forking the Ethereum Mainnet and it is creating a local node with the same state as the Mainnet at the moment of forking.

Anvil forking Ethereum Mainnet
Anvil forking Ethereum Mainnet

This strategy is very useful for testing smart contracts in a realistic environment, as you can interact with real contracts and data without risking real funds. One of the most common use cases is to test DeFi protocols, as you can simulate trades, liquidity provision, and other interactions with real assets. In general, you can test any smart contract which has been already deployed on the network you are forking.

Anvil also supports additional fork configuration flags such as CORS, request timeouts, per-request limits, and response headers to fully adapt the RPC endpoint to your use case.

Fork pinning by block number


By default, Anvil forks from the latest block, meaning state can differ between test runs as the chain advances. For reproducible results, always pin to a specific block number using --fork-block-number:

anvil --fork-url https://eth.blockrazor.xyz --fork-block-number 21500000

Pinning to a specific block ensures:

  • Deterministic state — identical contract bytecodes, balances, and storage slots every run
  • Cached RPC responses — Anvil caches responses under ~/.foundry/cache, so subsequent forks at the same block are near-instant
  • CI/CD reproducibility — test pipelines produce consistent results regardless of when they run

Forking multiple networks


Anvil also allows you to fork multiple networks at the same time. This is useful if you want to test interactions between different networks, such as cross-chain bridges or multi-chain dApps. To fork multiple networks,you can open several terminal windows and run the Anvil command with different RPC URLs in each one. However, by default, when you would open the second Anvil instance, it would try to bind to the same port (8545) and it would fail. To avoid this, you can specify a different port for each instance using the --port option.

anvil --fork-url https://eth.blockrazor.xyz --port 8546

This is the perfect strategy to create a multi-chain testing environment where you can simulate how a Dapp works in several chains at the same time.

Account impersonation


Account impersonation lets you send transactions as any address — including contract owners, governance multisigs, or whale wallets — without knowing their private key. This is one of the most powerful features for DeFi fork testing.

Unlock a specific address on startup:

anvil --fork-url https://eth.blockrazor.xyz --unlock 0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045

Send a transaction from the impersonated account using Cast:

cast send --unlocked --from 0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045 0xRecipient --value 1ether --rpc-url http://127.0.0.1:8545

You can also impersonate accounts dynamically via JSON-RPC without restarting Anvil:

cast rpc anvil_impersonateAccount 0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045 --rpc-url http://127.0.0.1:8545

Stop impersonating when done:

cast rpc anvil_stopImpersonatingAccount 0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045 --rpc-url http://127.0.0.1:8545

Anvil custom JSON-RPC methods


Anvil exposes a set of non-standard JSON-RPC methods (compatible with Hardhat Network) that give fine-grained control over node state. All are callable via cast rpc <method> [params].

State manipulation:

| Method | Parameters | Description | |--------|-----------|-------------| | anvil_setBalance | address, balance (hex wei) | Set the ETH balance of any address | | anvil_setCode | address, bytecode | Inject arbitrary bytecode at any address | | anvil_setStorageAt | address, slot, value | Write directly to any storage slot | | anvil_setNonce | address, nonce | Override the nonce of any account |

Example — fund an address with 100 ETH:

cast rpc anvil_setBalance 0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045 0x56BC75E2D63100000 --rpc-url http://127.0.0.1:8545

Time and block control:

| Method | Parameters | Description | |--------|-----------|-------------| | evm_mine | — | Mine one block immediately | | anvil_mine | count (hex) | Mine N blocks instantly | | evm_increaseTime | seconds | Advance the clock by N seconds | | evm_setNextBlockTimestamp | unix timestamp | Set the exact timestamp of the next block |

Example — advance time by 30 days then mine a block:

cast rpc evm_increaseTime 2592000 --rpc-url http://127.0.0.1:8545
cast rpc evm_mine --rpc-url http://127.0.0.1:8545

Snapshot and revert:

| Method | Parameters | Description | |--------|-----------|-------------| | anvil_snapshot | — | Snapshot current state, returns a snapshot ID | | anvil_revert | snapshot ID | Revert chain to a previous snapshot |

These are equivalent to the vm.snapshot() / vm.revertTo() Foundry cheatcodes but accessible from any HTTP client.

Example — take a snapshot:

cast rpc anvil_snapshot --rpc-url http://127.0.0.1:8545

Persistent state management


By default, Anvil state is fully in-memory and discarded when the process exits. You can persist and restore state using three flags:

| Flag | Behavior | |------|----------| | --dump-state <FILE> | Serialize all state to a JSON file on exit | | --load-state <FILE> | Restore state from a JSON file on startup | | --state <FILE> | Combined: load if file exists, then dump on exit |

Example — reproducible forked state:

anvil --fork-url https://eth.blockrazor.xyz --fork-block-number 21500000 --state ./anvil-state.json

The first run forks mainnet at block 21500000 and saves the complete state. Every subsequent run loads the serialized state instantly — no RPC calls required, even for forked state. This is ideal for local test suites that need realistic mainnet state but must run offline or without hitting provider rate limits.

Similar alternatives to Anvil


There are other similar alternatives to Anvil that you can use for local Ethereum development. Some of the most popular ones are compared below:

FeatureAnvilHardhat NetworkGanache
Startup SpeedVery FastFastModerate
Fork SupportYesYesYes
LanguageRustJavaScriptJavaScript
Memory UsageLowModerateHigh
Foundry IntegrationNativeVia pluginManual

Despite the existence of these alternatives, Anvil stands out for its performance, ease of use, and seamless integration with the Foundry suite. It is designed to be a high-performance local Ethereum node that can handle complex scenarios and large state sizes without compromising speed or reliability.

Frequently Asked Questions


What is Anvil used for?

Anvil is Foundry's local Ethereum node for testing and debugging Solidity smart contracts without a remote connection. It simulates a full EVM with instant mining, mainnet forking, account impersonation, and custom JSON-RPC cheatcodes — making it the most feature-complete local EVM available.

How does Anvil differ from Hardhat Network?

Anvil is implemented in Rust and is significantly faster than Hardhat Network (Node.js-based). It handles larger forked state sizes, supports more concurrent connections, and integrates natively with Forge and Cast. Hardhat Network is better suited for JavaScript/TypeScript-centric workflows with ethers.js or viem.

What are the Anvil default settings?

Anvil listens on http://127.0.0.1:8545 with chain ID 31337, creates 10 accounts pre-funded with 10,000 ETH each, uses instant mining with a 30,000,000 gas limit, and sets base fee at 1 gwei.

How do I change the Anvil default port?

Use --port 8546 to change the port. Combine with --host 0.0.0.0 to expose Anvil on your local network for connecting wallets from other devices.

How do I fork Ethereum mainnet with Anvil?

Run anvil --fork-url <RPC_URL> to fork from the latest block, or add --fork-block-number 21500000 to pin to a specific block for deterministic, reproducible state.

How do I pin a fork to a specific block number?

Use --fork-block-number: anvil --fork-url <RPC_URL> --fork-block-number 21500000. Pinning activates Anvil's RPC response cache at ~/.foundry/cache, making subsequent forks at the same block near-instant.

How do I impersonate an account in Anvil?

Pass --unlock <address> on startup, then use cast send --unlocked --from <address>. Alternatively, call cast rpc anvil_impersonateAccount <address> dynamically at any time without restarting the node.

How do I advance the block timestamp in Anvil?

Call cast rpc evm_increaseTime <seconds> to shift the clock forward, or cast rpc evm_setNextBlockTimestamp <unix_timestamp> for an exact timestamp. Follow either with cast rpc evm_mine to include the change in a new block.

How do I save and restore Anvil state?

Use --state ./state.json to automatically load state on startup and dump it on exit. This works with forked mainnet state, enabling fully offline test runs that load from disk without any RPC calls.

Can I use Anvil with MetaMask?

Yes. Add a custom network in MetaMask with RPC URL http://127.0.0.1:8545 and chain ID 31337. Import one of the 10 default private keys printed at Anvil startup to access the pre-funded accounts. Use --host 0.0.0.0 to connect from mobile devices on the same LAN.

What are Anvil's custom JSON-RPC methods?

Anvil exposes anvil_setBalance, anvil_setCode, anvil_setStorageAt, anvil_setNonce, anvil_impersonateAccount, anvil_stopImpersonatingAccount, anvil_snapshot, anvil_revert, anvil_mine, evm_mine, evm_increaseTime, and evm_setNextBlockTimestamp. All are callable via cast rpc <method> [args].

How do I use Anvil in CI/CD pipelines?

Start Anvil in the background with a pinned state: anvil --fork-url $RPC_URL --fork-block-number 21500000 --state ./anvil-state.json --silent &. Loading from a cached state file avoids RPC rate limits and ensures reproducibility across all pipeline runs.

Extra resources


If you want to learn more about Anvil and all the scenarios it supports, you can check the official documentation at Anvil official docs

Furthermore, if you want to learn more about other Foundry tools, you can check the Foundry Cast tutorial for smart contract interaction, where we explain how to use Cast, the command-line tool from Foundry to interact with Ethereum nodes and smart contracts or if you want to learn how to use Forge, the compiling and testing framework from Foundry, you can check the Foundry Forge tutorial for smart contract testing.