Skip to content

Commit d1d1089

Browse files
committed
wip
1 parent 71d666f commit d1d1089

File tree

8 files changed

+305
-0
lines changed

8 files changed

+305
-0
lines changed

docs/src/content/hh3/_dirinfo.yaml

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
section-type: group
2+
section-title: Hardhat 3 Alpha
3+
order:
4+
- title: Overview
5+
href: '#overview'
6+
- title: Initializing a project
7+
href: '#initializing-a-project'
8+
- title: Solidity tests
9+
href: '#solidity-tests'
10+
- title: TypeScript tests
11+
href: '#typescript-tests'
12+
- title: Multichain support
13+
href: '#multichain-support'
14+
- title: Deploying contracts
15+
href: '#deploying-contracts'
16+
- title: Build profiles
17+
href: '#build-profiles'
18+
- title: Managing dependencies
19+
href: '#managing-dependencies'
20+
- title: Configuration
21+
href: '#configuration'
22+
- title: Extensibility
23+
href: '#extensibility'
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
section-type: single
2+
section-title: Differences with Hardhat 2
+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
---
2+
prev: false
3+
---
4+
5+
# Differences with Harhdat 2
6+
7+
Hardhat 3 brings major improvements and new features, with a focus on testing capabilities and multichain development. This document outlines the key differences and innovations introduced in Hardhat 3. While this list is long, most of these changes are either backwards-compatible, or easy to adapt in existing projects.
8+
9+
## Support for Solidity Tests
10+
11+
Hardhat 3 introduces support for writing tests directly in Solidity, a feature designed to streamline Solidity-based testing. This makes it easier to test contracts without switching contexts or relying exclusively on JavaScript/TypeScript. These tests are compatible with those written in Foundry. Learn more in the deep dive into Solidity tests.
12+
13+
## Multichain Development Workflows
14+
15+
Hardhat 2 assumed a mainnet-like environment for simulations, which is the approach used by most existing tools. Hardhat 3 instead offers native support for multiple chain types, enabling developers to tailor their workflows to specific blockchain environments. Chain types represent the characteristics of different blockchains, such as mainnet, testnet, or custom configurations. Read more in the deep dive into multichain support.
16+
17+
## Declarative Configuration
18+
19+
In Hardhat 2, configuration was defined using a DSL that could involve side effects. Hardhat 3 simplifies this by introducing a declarative configuration style. Configuration is now a plain JavaScript object, making it more predictable and easier to understand. This also allows developers to create Hardhat environments dynamically at runtime.
20+
21+
## ESM-First
22+
23+
Hardhat 3 embraces modern JavaScript by making ECMAScript Modules (ESM) the default. Projects must now use ESM, although CommonJS (CJS) modules are still usable within ESM projects for compatibility. For more details, check out the deep dive into ESM.
24+
25+
## Test Runner Plugins
26+
27+
In Hardhat 2, Mocha was bundled with the framework. In Hardhat 3, Mocha has been moved to a plugin, alongside a new plugin for the Node.js test runner. This provides developers with the flexibility to choose their preferred test runner. Mocha remains fully supported for those who wish to continue using it. Learn more in the Node test runner deep dive.
28+
29+
## Network Manager
30+
31+
The relationship between executions and connections has been revamped in Hardhat 3. In Hardhat 2, each execution was tied to a single connection. In Hardhat 3, connections are explicitly created and managed, allowing for multiple connections and dynamic workflows. Find more information in the Network Manager deep dive.
32+
33+
## Build Profiles
34+
35+
Build profiles are now a first-class concept in Hardhat 3, simplifying development and production configurations. In Hardhat 2, this was achieved through a mix of code in configuration files and environment variables. In Hardhat 3, profiles integrate seamlessly with built-in tasks. For instance, a development profile is used when running tests and a production profile when deploying and verifying.
36+
37+
## Improved Compilation Pipeline
38+
39+
The compilation process in Hardhat 3 has been significantly enhanced, with better support for managing dependencies through npm and improved handling of remappings. Learn more in the deep dive into dependency management. While remappings are fully supported, they shouldn't be needed; you only use with them if you want to.
40+
41+
## Lazy and Extensible Configuration Variables
42+
43+
Hardhat 3 builds on Hardhat 2's configuration variable system, making it more powerful and flexible. Variables are now defined lazily, meaning they are only required if a specific workflow needs them. Learn more in the deep dive into configuration variables. Their fetching is handled by plugins, with Hardhat shipping a default plugin that stores them encrypted on disk. Plugins can also be created to fetch and store variables using other systems, such as AWS Secrets Manager or HashiCorp Vault.
44+
45+
## Hooks
46+
47+
Hardhat 3 introduces a powerful hooks system, enabling greater extensibility for plugin authors. Learn more in the deep dive into hooks. This feature is primarily for plugin developers and is not something most users will need to interact with directly.

docs/src/content/hh3/index.md

+180
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
---
2+
prev: false
3+
---
4+
5+
# Hardhat 3 Alpha
6+
7+
## Overview
8+
9+
\<Intro to the public alpha tutorial. Summary of the content of this tutorial. Familiarity with HH2 assumptions. State of HH3.>
10+
11+
\<Feedback welcome>
12+
13+
## Initializing a project
14+
15+
- Create an empty directory
16+
- Initialize an npm/pnpm project
17+
- Make it ESM.
18+
- Short explanation about ESM and link to deep dive
19+
- Run hardhat init
20+
- Select the first option, Node test runner + viem
21+
- Mocha and ethers will continue to be supported
22+
- Short explanation about node test runner and link to deep dive
23+
- Install the dependencies
24+
- All set up now, let’s see what new features are in store
25+
26+
27+
## Solidity tests
28+
29+
One of Hardhat 3's new features is support for writing tests in Solidity. You can run this project's Solidity tests with the `test solidity` task:
30+
31+
```
32+
$ npx hardhat test solidity
33+
<output>
34+
```
35+
36+
A Solidity tests is a normal Solidity contract that will be executed in a special way. Let's see the example in this project. The contract we want to test is in the `contracts/Counter.sol` file:
37+
38+
```solidity
39+
contract Counter {
40+
uint public x;
41+
42+
function inc() public {
43+
x++;
44+
}
45+
46+
function incBy(uint by) public {
47+
require(by > 0, "Counter: by must be greater than 0");
48+
x += by;
49+
}
50+
}
51+
```
52+
53+
And this is the content of the `contracts/Counter.t.sol` Solidity test file:
54+
55+
```solidity
56+
import { Test } from "forge-std/Test.sol";
57+
58+
import "./Counter.sol";
59+
60+
contract CounterTest is Test {
61+
Counter counter;
62+
63+
function setUp() public {
64+
counter = new Counter();
65+
}
66+
67+
function test_InitialValue() public view {
68+
require(counter.x() == 0, "Initial value should be 0");
69+
}
70+
71+
function test_Inc() public {
72+
counter.inc();
73+
require(counter.x() == 1, "Value after calling inc should be 1");
74+
}
75+
76+
function testFuzz_Inc(uint8 x) public {
77+
for (uint8 i = 0; i < x; i++) {
78+
counter.inc();
79+
}
80+
require(counter.x() == x, "Value after calling inc x times should be x");
81+
}
82+
83+
function test_IncBy() public {
84+
counter.incBy(5);
85+
require(counter.x() == 5, "Value after calling incBy(5) should be 5");
86+
}
87+
88+
function test_IncByZero() public {
89+
vm.expectRevert("Counter: 'by' must be greater than 0");
90+
counter.incBy(0);
91+
}
92+
}
93+
```
94+
95+
The `CounterTest` contract represents a suite of tests. All functions that start with `test` will be considered test functions. This contract will be deployed and all its tests functions will be called. If a test function reverts, that test will be considered failed. There's also a `setUp` function which will be called before each test.
96+
97+
Functions that start with `test` and don't have any parameters are unit tests. But if a test function has parameters, it's considered a fuzz test. These tests will be called multiple times with different, random values as arguments. If any of these calls reverts, the test will be considered failed and the arguments that produced the failure will be printed.
98+
99+
Another thing that is different between normal Solidity code and Solidity tests is the possibility of using cheatcodes. These are special functions that can be called during a test execution to modify the state or behavior of the EVM in non-standard ways. For example, in `test_IncByZero` we are using the `vm.expectRevert` cheatcode. When used, the next call will be expected to revert and, if it doesn't, the test will fail. There are many other cheatcodes. For example, you can change the value of `block.number` by using the `vm.roll` cheatcode.
100+
101+
Hardhat 3's Solidity tests are compatible with Foundry-style tests. You can write unit, fuzz, and invariant tests, and all testing-related cheatcodes are supported. You can write tests using any Solidity testing library, like forge-std or PRBTest.
102+
103+
You can learn more about Hardhat 3's Solidity tests [here](/hh3/under-the-hood/solidity-tests).
104+
105+
## TypeScript tests
106+
107+
While Solidity tests are excellent for unit-like testing, there are scenarios where they fall short. For example:
108+
109+
- Complex test setups can become unwieldy in Solidity due to language constraints.
110+
- Some tests require interaction with a real blockchain and real transactions. Although you can simulate this using cheatcodes, doing so can be cumbersome and error-prone.
111+
112+
To address these limitations, Hardhat 3, like its predecessor, supports writing tests in TypeScript (or JavaScript). In the sample project, you can run TypeScript-based tests using the `test js` task.
113+
114+
\<example>
115+
116+
With TypeScript, you can easily manage advanced test setups, perform assertions, and leverage the full capabilities of modern JavaScript tooling, making it the preferred choice for integration and more complex tests.
117+
118+
Another major improvement in Hardhat 3 is its flexibility with test runners. The sample project uses the **Node.js test runner**, but you can now use any JavaScript test runner, including Mocha (with our plugin for backward compatibility), Jest, or Vitest. Writing plugins for additional test runners is also feasible, and we may release official support for them in the future.
119+
120+
To run all your tests—both Solidity and TypeScript—simply execute the `test` task:
121+
122+
\<output>
123+
124+
## Multichain support
125+
126+
- There is an implicit assumption across the Ethereum development ecosystem that you are developing for mainnet, but then you might actually deploy in some other chain, like Optimism or Arbitrum, and hope for the best. This is not ideal.
127+
- Hardhat 3 lets you select for which chain you are developing, by selecting a certain chain type that you want to simulate locally. Initially it supports three chain types: ethereum mainnet, optimism, and a generic chain type that works as a sort of common denominator and it’s the closest one to the Hardhat 2 behavior. More chain types will be added in the future.
128+
- Example: run a script that estimates the Optimism L1 fee.
129+
- That script also illustrates another change in HH3. In Hardhat 2, each execution connected automatically to one, and only one, network. There wasn’t a good way to connect to multiple networks, or to change which network you are connected to. In Hardhat 3, on the other hand, you create network connections explicitly, you can have as many as you want, and you can create and close them at any point.
130+
- Example, explanation about the `network.connect` API
131+
- Show that this combines with viem’s powerful typescript support: if you change the chain type to mainnet, you’ll get compilation errors.
132+
133+
## Deploying contracts
134+
135+
- The default deployment solution in Hardhat 3 is Ignition.
136+
- Short description about Ignition.
137+
- While this is our recommended approach for deploying contracts, you can choose to use anything else: scripts, or any other deployment plugins that could be developed by the community in the future
138+
- Example: ignition module
139+
- Run an ignition deploy in process
140+
- Run an ignition deploy in a hardhat node. Run it again. You can try adding a new step and checking that only that is executed.
141+
- Ignition is already available and being used in Hardhat 2. Its docs assume Hardhat 2, but most of it should be compatible with Hardhat 3.
142+
143+
## Build profiles
144+
145+
- HH3 introduces support for build profiles.
146+
- Build profiles let you have compile your project in different ways depending on what you are doing. For example, you can have a development profile that disables the optimizer and a production profile that enables it. The development profile is then used when running tests locally, while the production profile is used for deployments or when running tests in the CI
147+
- Some profiles are already used by Hardhat tasks, but you can create new ones and use them in your project however you want. For example: \<example>
148+
- In the sample project, we \<description>
149+
- You don't need to define build profiles if you don't need them, you can define a single configuration and that will be used for everything, \<example>
150+
151+
## Managing dependencies
152+
153+
- Like Hardhat 2, Hardhat 3 uses npm to manage dependencies. For simple use cases, the user experience will be the same. But Hardhat 3 revamps how npm is used under the hood to handle advanced use cases much better.
154+
- One such use case relates to transitive dependencies. \<Short explanation of the problem. HH3 handles this under the hood so that it just works. Link to explainer.>
155+
- Hardhat 3 also has built-in support for remappings, but they are not necessary under any circumstance: you use it only if you want to.
156+
157+
## Configuration
158+
159+
- Like Hardhat 2, Hardhat 3 is configured with a JavaScript file, but in Hardhat 3 the configuration is completely declarative. This contrasts with Hardhat 2, where part of the configuration was done by importing modules or calling functions that had side effects.
160+
- Most things should look and feel the same though.
161+
- Example: configuration in sample project.
162+
- This approach allows us to have much faster load times, even if you have a lot of plugins.
163+
- This also allows creating Hardhat environments in runtime, for advanced use cases.
164+
165+
## Extensibility
166+
167+
- The main extensibility point of Hardhat 3 is the same as in Hardhat 2: the ability to create custom tasks. These haven't changed a lot.
168+
- Example: \<TBD>.
169+
- This is pretty much the same as in Hardhat 2, except for two differences: the task needs to be included in the configuration object, and you need to call a `build` function at the end.
170+
- Hardhat 3 also includes a new and powerful hook system that lets you easily extend its functionality, and lets plugin authors add their own extensibility functions for their plugins. \<Link to explainer>
171+
172+
## Closing words
173+
174+
- This tutorial was an overview of the most important things included in the HH3 alpha.
175+
- This is an alpha, things can and will change. If there’s anything here that you don’t like, an API that is confusing, or anything else, we’d love you hear your feedback.
176+
- Join our telegram group
177+
- Open an issue
178+
- Wen HH3 stable
179+
- More features will be gradually added to the alpha, stay in tune by following us on Twitter, watching our releases page, or joining the public alpha telegram group.
180+
- Eventually we’ll have a feature-complete beta version and with a stable API. There won’t be breaking changes unless it’s unavoidable. At this point, you should be able to start using Hardhat 3 for real projects, or migrate existing projects to it, if you are comfortable with using beta-stage software.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
section-type: group
2+
section-title: Under the hood
3+
order:
4+
- title: ESM
5+
href: /esm
6+
- title: Solidity Tests
7+
href: /solidity-tests
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
prev: false
3+
next: true
4+
---
5+
6+
# ESM
7+
8+
\<what and why>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
---
2+
prev: true
3+
---
4+
5+
# Solidity Tests
6+
7+
Hardhat 3 introduces support for Solidity tests, alongside the existing TypeScript-based test framework. This feature wasn’t feasible in Hardhat 2 due to technical limitations, but with the architectural improvements in Hardhat 3, we’re able to deliver Solidity testing with the quality you’ve come to expect from Hardhat.
8+
9+
Hardhat’s Solidity testing framework is compatible with the Dapptools-style Solidity tests, refined and popularized by Foundry. With this feature, you can write unit tests, fuzz tests, and invariant tests in Solidity, and leverage many of the Foundry-inspired cheatcodes you may already know. We designed Hardhat's Solidity tests to be as similar as possible to Foundry’s, minimizing unnecessary fragmentation in the developer community.
10+
11+
That said, there are some key differences in how Hardhat handles Solidity tests compared to Foundry. These differences are detailed in a section below.
12+
13+
## How Solidity tests work in Hardhat 3
14+
15+
Hardhat treats Solidity files that follow specific conventions as test files. A Solidity file is considered a test file if it's under the contracts directory and has `.t.sol` as its extension, or if its under the `paths.tests.solidity` directory in Hardhat's configuration.
16+
17+
All contracts in a test file are considered test contracts. The functions in these contracts whose names that start with `test` are considered test functions. These functions will be called by Hardhat when running the tests. If a test function reverts, the test will be considered failed.
18+
19+
All the developer experience features of Hardhat, such as console.log debugging, Solidity stack traces, and error inference, are fully compatible with Solidity tests. This ensures you get the same comprehensive insights into your tests as you would with TypeScript-based tests.
20+
21+
Moreover, multichain workflows (a major feature of Hardhat 3) will eventually extend to Solidity tests, allowing you to test across multiple chain types. However, this functionality is not yet available in the alpha version.
22+
23+
## Differences between Hardhat and Foundry-style Solidity tests
24+
25+
While Hardhat and Foundry share many similarities in their Solidity testing frameworks, there are a few differences:
26+
27+
1. `testFail` behavior. Foundry’s testFail prefix indicates that the test passes only if the transaction reverts. In Hardhat, this is considered an anti-pattern because it is less explicit than using revert-expectation cheatcodes like vm.expectRevert. Hardhat does not support testFail by default but provides an opt-in mechanism for teams migrating legacy tests.
28+
2. No Inline Configuration via NatSpec. Unlike Foundry, Hardhat does not support configuring tests inline using NatSpec comments. Test configuration must be handled programmatically in your test files.
29+
3. Unsupported Scripting Cheatcodes Foundry includes cheatcodes that facilitate scripting, such as startBroadcast and stopBroadcast. These are not currently supported in Hardhat since they are beyond the scope of its testing-focused architecture.
30+
4. No Fixture Support Foundry's fixture cheatcodes are not compatible with Hardhat’s approach to test isolation. Instead, Hardhat relies on programmatic test setup and fixtures defined in JavaScript/TypeScript.
31+
5. Cheatcodes: getCode and getDeployedCode Foundry’s getCode and getDeployedCode cheatcodes are not supported in Hardhat because they conflict with how Hardhat handles runtime deployments and its dynamic testing environment.

docs/src/content/layouts.yaml

+7
Original file line numberDiff line numberDiff line change
@@ -67,3 +67,10 @@ tutorial:
6767
title: tutorial
6868
folders:
6969
- tutorial
70+
71+
hh3:
72+
title: hh3
73+
folders:
74+
- hh3
75+
- hh3/comparison
76+
- hh3/under-the-hood

0 commit comments

Comments
 (0)