1 | [](https://www.npmjs.com/package/@nomiclabs/hardhat-ethers) [](https://hardhat.org)
|
2 |
|
3 | # hardhat-ethers
|
4 |
|
5 | [Hardhat](https://hardhat.org) plugin for integration with [ethers.js](https://github.com/ethers-io/ethers.js/).
|
6 |
|
7 | ## What
|
8 |
|
9 | This plugin brings to Hardhat the Ethereum library `ethers.js`, which allows you to interact with the Ethereum blockchain in a simple way.
|
10 |
|
11 | ## Installation
|
12 |
|
13 | ```bash
|
14 | npm install --save-dev @nomiclabs/hardhat-ethers 'ethers@^5.0.0'
|
15 | ```
|
16 |
|
17 | And add the following statement to your `hardhat.config.js`:
|
18 |
|
19 | ```js
|
20 | require("@nomiclabs/hardhat-ethers");
|
21 | ```
|
22 |
|
23 | Or, if you are using TypeScript, add this to your `hardhat.config.ts`:
|
24 |
|
25 | ```js
|
26 | import "@nomiclabs/hardhat-ethers";
|
27 | ```
|
28 |
|
29 | ## Tasks
|
30 |
|
31 | This plugin creates no additional tasks.
|
32 |
|
33 | ## Environment extensions
|
34 |
|
35 | This plugins adds an `ethers` object to the Hardhat Runtime Environment.
|
36 |
|
37 | This object has the [same API](https://docs.ethers.io/v5/single-page/) as `ethers.js`, with some extra Hardhat-specific functionality.
|
38 |
|
39 | ### Provider object
|
40 |
|
41 | A `provider` field is added to `ethers`, which is an [`ethers.providers.Provider`](https://docs.ethers.io/v5/single-page/#/v5/api/providers/provider/) automatically connected to the selected network.
|
42 |
|
43 | ### Helpers
|
44 |
|
45 | These helpers are added to the `ethers` object:
|
46 |
|
47 | ```typescript
|
48 | interface Libraries {
|
49 | [libraryName: string]: string;
|
50 | }
|
51 |
|
52 | interface FactoryOptions {
|
53 | signer?: ethers.Signer;
|
54 | libraries?: Libraries;
|
55 | }
|
56 |
|
57 | function deployContract(name: string, constructorArgs?: any[], signer?: ethers.Signer): Promise<ethers.Contract>;
|
58 |
|
59 | function getContractFactory(name: string, signer?: ethers.Signer): Promise<ethers.ContractFactory>;
|
60 |
|
61 | function getContractFactory(name: string, factoryOptions: FactoryOptions): Promise<ethers.ContractFactory>;
|
62 |
|
63 | function getContractFactory(abi: any[], bytecode: ethers.utils.BytesLike, signer?: ethers.Signer): Promise<ethers.ContractFactory>;
|
64 |
|
65 | function getContractAt(name: string, address: string, signer?: ethers.Signer): Promise<ethers.Contract>;
|
66 |
|
67 | function getContractAt(abi: any[], address: string, signer?: ethers.Signer): Promise<ethers.Contract>;
|
68 |
|
69 | function getSigners() => Promise<ethers.Signer[]>;
|
70 |
|
71 | function getSigner(address: string) => Promise<ethers.Signer>;
|
72 |
|
73 | function getImpersonatedSigner(address: string) => Promise<ethers.Signer>;
|
74 |
|
75 | function getContractFactoryFromArtifact(artifact: Artifact, signer?: ethers.Signer): Promise<ethers.ContractFactory>;
|
76 |
|
77 | function getContractFactoryFromArtifact(artifact: Artifact, factoryOptions: FactoryOptions): Promise<ethers.ContractFactory>;
|
78 |
|
79 | function getContractAtFromArtifact(artifact: Artifact, address: string, signer?: ethers.Signer): Promise<ethers.Contract>;
|
80 | ```
|
81 |
|
82 | The [`Contract`s](https://docs.ethers.io/v5/single-page/#/v5/api/contract/contract/) and [`ContractFactory`s](https://docs.ethers.io/v5/single-page/#/v5/api/contract/contract-factory/) returned by these helpers are connected to the first [signer](https://docs.ethers.io/v5/single-page/#/v5/api/signer/) returned by `getSigners` by default.
|
83 |
|
84 | If there is no signer available, `getContractAt` returns [read-only](https://docs.ethers.io/v5/single-page/#/v5/api/contract/contract/-%23-Contract--readonly) contracts.
|
85 |
|
86 | ## Usage
|
87 |
|
88 | There are no additional steps you need to take for this plugin to work.
|
89 |
|
90 | Install it and access ethers through the Hardhat Runtime Environment anywhere you need it (tasks, scripts, tests, etc). For example, in your `hardhat.config.js`:
|
91 |
|
92 | ```js
|
93 | require("@nomiclabs/hardhat-ethers");
|
94 |
|
95 | // task action function receives the Hardhat Runtime Environment as second argument
|
96 | task(
|
97 | "blockNumber",
|
98 | "Prints the current block number",
|
99 | async (_, { ethers }) => {
|
100 | await ethers.provider.getBlockNumber().then((blockNumber) => {
|
101 | console.log("Current block number: " + blockNumber);
|
102 | });
|
103 | }
|
104 | );
|
105 |
|
106 | module.exports = {};
|
107 | ```
|
108 |
|
109 | And then run `npx hardhat blockNumber` to try it.
|
110 |
|
111 | Read the documentation on the [Hardhat Runtime Environment](https://hardhat.org/hardhat-runner/docs/advanced/hardhat-runtime-environment) to learn how to access the HRE in different ways to use ethers.js from anywhere the HRE is accessible.
|
112 |
|
113 | ### Library linking
|
114 |
|
115 | Some contracts need to be linked with libraries before they are deployed. You can pass the addresses of their libraries to the `getContractFactory` function with an object like this:
|
116 |
|
117 | ```js
|
118 | const contractFactory = await this.env.ethers.getContractFactory("Example", {
|
119 | libraries: {
|
120 | ExampleLib: "0x...",
|
121 | },
|
122 | });
|
123 | ```
|
124 |
|
125 | This allows you to create a contract factory for the `Example` contract and link its `ExampleLib` library references to the address `"0x..."`.
|
126 |
|
127 | To create a contract factory, all libraries must be linked. An error will be thrown informing you of any missing library.
|
128 |
|
129 | ## Troubleshooting
|
130 |
|
131 | ### Events are not being emitted
|
132 |
|
133 | Ethers.js polls the network to check if some event was emitted (except when a `WebSocketProvider` is used; see below). This polling is done every 4 seconds. If you have a script or test that is not emitting an event, it's likely that the execution is finishing before the event is detected by the polling mechanism.
|
134 |
|
135 | If you are connecting to a Hardhat node using a `WebSocketProvider`, events should be emitted immediately. But keep in mind that you'll have to create this provider manually, since Hardhat only supports configuring networks via http. That is, you can't add a `localhost` network with a URL like `ws://127.0.0.1:8545`.
|
136 |
|
137 | ### Gas transaction parameters in `hardhat.config` are not used
|
138 |
|
139 | When using this plugin, the `gas`, `gasPrice` and `gasMultiplier` parameters from your `hardhat.config` are not automatically applied to transactions. In order to provide such values to your transactions, specify them as [overrides](https://docs.ethers.io/v5/single-page/#/v5/api/contract/contract/-%23-contract-functionsSend) on the transaction itself.
|