Multichain support
Hardhat 3 was designed for the multichain world. When you use it with a supported chain, it’ll precisely simulate that chain, giving you confidence in your test runs. This is a fundamental shift from earlier versions and other tools, where every test ran simulating Ethereum Mainnet, with the hope that it’d work on other chains.
Beyond accurate simulation, Hardhat 3 makes it easy to encode tests and workflows that connect to multiple chains. Learn more in the Network Management explanation.
Hardhat 3 also allows plugins, like hardhat-viem, to offer chain-specific capabilities in a seamless way, adapting their behavior based on the chain you’re working with.
Understanding Chain Types
Section titled “Understanding Chain Types”Hardhat 3 introduced the concept of a Chain Type. It’s a way to classify different blockchains according to their behavior.
Two blockchains have the same Chain Type if they behave exactly the same. For example, Ethereum Mainnet and its testnets have the same Chain Type, while Ethereum Mainnet and Polygon PoS Chain don’t, as they have slightly different behaviors.
Currently supported Chain Types
Section titled “Currently supported Chain Types”Hardhat 3 supports three Chain Types at the moment:
l1: For Ethereum Mainnet and its testnets.op: For OP Mainnet and its testnets.generic: A permissive approximation of how Ethereum Mainnet and other EVM-compatible chains work. This is equivalent to how Hardhat 2 and other tools work.
In the near future, we plan to add Chain Types for other Layer 2 chains, starting with other networks of the Optimism Superchain.
Mid-term, other chains should be able to define their own Chain Types with plugins.
How Chain Types work
Section titled “How Chain Types work”When using EDR with a certain Chain Type, it’ll change its behavior to strictly mimic the actual blockchain. This can mean:
- Changing gas costs of certain opcodes
- Introducing new opcodes
- Adding new precompiles
- Adding predeployed contracts
- Changing how gas and L1 gas (if applicable) are handled
- Changing how some JSON-RPC methods work, like
eth_estimateGas - Changing the response formats of some JSON-RPC methods to use the same ones as the actual chain
You can specify a Chain Type when creating blockchain simulations with the Network Manager or when running Solidity tests. This lets you catch chain-specific errors early in development, ensuring your contracts work correctly on your target blockchain.
Chain Types and the Network Manager
Section titled “Chain Types and the Network Manager”When you connect to a network using the Network Manager like this:
import { network } from "hardhat";
const { viem } = await network.connect({ network: "hardhatOp", chainType: "op",});
const publicClient = await viem.getPublicClient();const l1Gas = await publicClient.estimateL1Gas({ account: "0x1111111111111111111111111111111111111111", to: "0x2222222222222222222222222222222222222222", value: 1n,});The network simulation will be created using the op Chain Type and its simulation will be stricter.
Moreover, the Chain Type information will be available to network-related plugins, both at runtime and at type-level. This allows them to modify their behavior and the result of network.connect() depending on the Chain Type, potentially adding more functionality.
For example, the method highlighted in the snippet above is only available when you’re using the op Chain Type.
You can also define the Chain Type of a network in the config. To learn how to do it, read the Network Manager reference.
Running Solidity tests with a Chain Type
Section titled “Running Solidity tests with a Chain Type”Solidity tests run by default with the l1 Chain Type. To change it, run them like this:
npx hardhat test --chain-type oppnpm hardhat test --chain-type opyarn hardhat test --chain-type opOr only the Solidity tests with:
npx hardhat test solidity --chain-type oppnpm hardhat test solidity --chain-type opyarn hardhat test solidity --chain-type op