1 | "use strict";
|
2 | var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
3 | if (k2 === undefined) k2 = k;
|
4 | var desc = Object.getOwnPropertyDescriptor(m, k);
|
5 | if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
6 | desc = { enumerable: true, get: function() { return m[k]; } };
|
7 | }
|
8 | Object.defineProperty(o, k2, desc);
|
9 | }) : (function(o, m, k, k2) {
|
10 | if (k2 === undefined) k2 = k;
|
11 | o[k2] = m[k];
|
12 | }));
|
13 | var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
14 | Object.defineProperty(o, "default", { enumerable: true, value: v });
|
15 | }) : function(o, v) {
|
16 | o["default"] = v;
|
17 | });
|
18 | var __importStar = (this && this.__importStar) || function (mod) {
|
19 | if (mod && mod.__esModule) return mod;
|
20 | var result = {};
|
21 | if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
22 | __setModuleDefault(result, mod);
|
23 | return result;
|
24 | };
|
25 | Object.defineProperty(exports, "__esModule", { value: true });
|
26 | exports.getContractAtFromArtifact = exports.deployContract = exports.getContractAt = exports.getContractFactoryFromArtifact = exports.getContractFactory = exports.getImpersonatedSigner = exports.getSigner = exports.getSigners = void 0;
|
27 | const plugins_1 = require("hardhat/plugins");
|
28 | const pluginName = "hardhat-ethers";
|
29 | function isArtifact(artifact) {
|
30 | const { contractName, sourceName, abi, bytecode, deployedBytecode, linkReferences, deployedLinkReferences, } = artifact;
|
31 | return (typeof contractName === "string" &&
|
32 | typeof sourceName === "string" &&
|
33 | Array.isArray(abi) &&
|
34 | typeof bytecode === "string" &&
|
35 | typeof deployedBytecode === "string" &&
|
36 | linkReferences !== undefined &&
|
37 | deployedLinkReferences !== undefined);
|
38 | }
|
39 | async function getSigners(hre) {
|
40 | const accounts = await hre.ethers.provider.listAccounts();
|
41 | const signersWithAddress = await Promise.all(accounts.map((account) => getSigner(hre, account)));
|
42 | return signersWithAddress;
|
43 | }
|
44 | exports.getSigners = getSigners;
|
45 | async function getSigner(hre, address) {
|
46 | const { SignerWithAddress: SignerWithAddressImpl } = await Promise.resolve().then(() => __importStar(require("../signers")));
|
47 | const signer = hre.ethers.provider.getSigner(address);
|
48 | const signerWithAddress = await SignerWithAddressImpl.create(signer);
|
49 | return signerWithAddress;
|
50 | }
|
51 | exports.getSigner = getSigner;
|
52 | async function getImpersonatedSigner(hre, address) {
|
53 | await hre.ethers.provider.send("hardhat_impersonateAccount", [address]);
|
54 | return getSigner(hre, address);
|
55 | }
|
56 | exports.getImpersonatedSigner = getImpersonatedSigner;
|
57 | async function getContractFactory(hre, nameOrAbi, bytecodeOrFactoryOptions, signer) {
|
58 | if (typeof nameOrAbi === "string") {
|
59 | const artifact = await hre.artifacts.readArtifact(nameOrAbi);
|
60 | return getContractFactoryFromArtifact(hre, artifact, bytecodeOrFactoryOptions);
|
61 | }
|
62 | return getContractFactoryByAbiAndBytecode(hre, nameOrAbi, bytecodeOrFactoryOptions, signer);
|
63 | }
|
64 | exports.getContractFactory = getContractFactory;
|
65 | function isFactoryOptions(signerOrOptions) {
|
66 | const { Signer } = require("ethers");
|
67 | return signerOrOptions !== undefined && !Signer.isSigner(signerOrOptions);
|
68 | }
|
69 | async function getContractFactoryFromArtifact(hre, artifact, signerOrOptions) {
|
70 | let libraries = {};
|
71 | let signer;
|
72 | if (!isArtifact(artifact)) {
|
73 | throw new plugins_1.NomicLabsHardhatPluginError(pluginName, `You are trying to create a contract factory from an artifact, but you have not passed a valid artifact parameter.`);
|
74 | }
|
75 | if (isFactoryOptions(signerOrOptions)) {
|
76 | signer = signerOrOptions.signer;
|
77 | libraries = signerOrOptions.libraries ?? {};
|
78 | }
|
79 | else {
|
80 | signer = signerOrOptions;
|
81 | }
|
82 | if (artifact.bytecode === "0x") {
|
83 | throw new plugins_1.NomicLabsHardhatPluginError(pluginName, `You are trying to create a contract factory for the contract ${artifact.contractName}, which is abstract and can't be deployed.
|
84 | If you want to call a contract using ${artifact.contractName} as its interface use the "getContractAt" function instead.`);
|
85 | }
|
86 | const linkedBytecode = await collectLibrariesAndLink(artifact, libraries);
|
87 | return getContractFactoryByAbiAndBytecode(hre, artifact.abi, linkedBytecode, signer);
|
88 | }
|
89 | exports.getContractFactoryFromArtifact = getContractFactoryFromArtifact;
|
90 | async function collectLibrariesAndLink(artifact, libraries) {
|
91 | const { utils } = require("ethers");
|
92 | const neededLibraries = [];
|
93 | for (const [sourceName, sourceLibraries] of Object.entries(artifact.linkReferences)) {
|
94 | for (const libName of Object.keys(sourceLibraries)) {
|
95 | neededLibraries.push({ sourceName, libName });
|
96 | }
|
97 | }
|
98 | const linksToApply = new Map();
|
99 | for (const [linkedLibraryName, linkedLibraryAddress] of Object.entries(libraries)) {
|
100 | if (!utils.isAddress(linkedLibraryAddress)) {
|
101 | throw new plugins_1.NomicLabsHardhatPluginError(pluginName, `You tried to link the contract ${artifact.contractName} with the library ${linkedLibraryName}, but provided this invalid address: ${linkedLibraryAddress}`);
|
102 | }
|
103 | const matchingNeededLibraries = neededLibraries.filter((lib) => {
|
104 | return (lib.libName === linkedLibraryName ||
|
105 | `${lib.sourceName}:${lib.libName}` === linkedLibraryName);
|
106 | });
|
107 | if (matchingNeededLibraries.length === 0) {
|
108 | let detailedMessage;
|
109 | if (neededLibraries.length > 0) {
|
110 | const libraryFQNames = neededLibraries
|
111 | .map((lib) => `${lib.sourceName}:${lib.libName}`)
|
112 | .map((x) => `* ${x}`)
|
113 | .join("\n");
|
114 | detailedMessage = `The libraries needed are:
|
115 | ${libraryFQNames}`;
|
116 | }
|
117 | else {
|
118 | detailedMessage = "This contract doesn't need linking any libraries.";
|
119 | }
|
120 | throw new plugins_1.NomicLabsHardhatPluginError(pluginName, `You tried to link the contract ${artifact.contractName} with ${linkedLibraryName}, which is not one of its libraries.
|
121 | ${detailedMessage}`);
|
122 | }
|
123 | if (matchingNeededLibraries.length > 1) {
|
124 | const matchingNeededLibrariesFQNs = matchingNeededLibraries
|
125 | .map(({ sourceName, libName }) => `${sourceName}:${libName}`)
|
126 | .map((x) => `* ${x}`)
|
127 | .join("\n");
|
128 | throw new plugins_1.NomicLabsHardhatPluginError(pluginName, `The library name ${linkedLibraryName} is ambiguous for the contract ${artifact.contractName}.
|
129 | It may resolve to one of the following libraries:
|
130 | ${matchingNeededLibrariesFQNs}
|
131 |
|
132 | To fix this, choose one of these fully qualified library names and replace where appropriate.`);
|
133 | }
|
134 | const [neededLibrary] = matchingNeededLibraries;
|
135 | const neededLibraryFQN = `${neededLibrary.sourceName}:${neededLibrary.libName}`;
|
136 |
|
137 |
|
138 |
|
139 | if (linksToApply.has(neededLibraryFQN)) {
|
140 | throw new plugins_1.NomicLabsHardhatPluginError(pluginName, `The library names ${neededLibrary.libName} and ${neededLibraryFQN} refer to the same library and were given as two separate library links.
|
141 | Remove one of them and review your library links before proceeding.`);
|
142 | }
|
143 | linksToApply.set(neededLibraryFQN, {
|
144 | sourceName: neededLibrary.sourceName,
|
145 | libraryName: neededLibrary.libName,
|
146 | address: linkedLibraryAddress,
|
147 | });
|
148 | }
|
149 | if (linksToApply.size < neededLibraries.length) {
|
150 | const missingLibraries = neededLibraries
|
151 | .map((lib) => `${lib.sourceName}:${lib.libName}`)
|
152 | .filter((libFQName) => !linksToApply.has(libFQName))
|
153 | .map((x) => `* ${x}`)
|
154 | .join("\n");
|
155 | throw new plugins_1.NomicLabsHardhatPluginError(pluginName, `The contract ${artifact.contractName} is missing links for the following libraries:
|
156 | ${missingLibraries}
|
157 |
|
158 | Learn more about linking contracts at https://hardhat.org/hardhat-runner/plugins/nomiclabs-hardhat-ethers#library-linking
|
159 | `);
|
160 | }
|
161 | return linkBytecode(artifact, [...linksToApply.values()]);
|
162 | }
|
163 | async function getContractFactoryByAbiAndBytecode(hre, abi, bytecode, signer) {
|
164 | const { ContractFactory } = require("ethers");
|
165 | if (signer === undefined) {
|
166 | const signers = await hre.ethers.getSigners();
|
167 | signer = signers[0];
|
168 | }
|
169 | const abiWithAddedGas = addGasToAbiMethodsIfNecessary(hre.network.config, abi);
|
170 | return new ContractFactory(abiWithAddedGas, bytecode, signer);
|
171 | }
|
172 | async function getContractAt(hre, nameOrAbi, address, signer) {
|
173 | if (typeof nameOrAbi === "string") {
|
174 | const artifact = await hre.artifacts.readArtifact(nameOrAbi);
|
175 | return getContractAtFromArtifact(hre, artifact, address, signer);
|
176 | }
|
177 | const { Contract } = require("ethers");
|
178 | if (signer === undefined) {
|
179 | const signers = await hre.ethers.getSigners();
|
180 | signer = signers[0];
|
181 | }
|
182 |
|
183 |
|
184 | const signerOrProvider = signer !== undefined ? signer : hre.ethers.provider;
|
185 | const abiWithAddedGas = addGasToAbiMethodsIfNecessary(hre.network.config, nameOrAbi);
|
186 | return new Contract(address, abiWithAddedGas, signerOrProvider);
|
187 | }
|
188 | exports.getContractAt = getContractAt;
|
189 | async function deployContract(hre, name, argsOrSignerOrOptions, signerOrOptions) {
|
190 | let args = [];
|
191 | if (Array.isArray(argsOrSignerOrOptions)) {
|
192 | args = argsOrSignerOrOptions;
|
193 | }
|
194 | else {
|
195 | signerOrOptions = argsOrSignerOrOptions;
|
196 | }
|
197 | const factory = await getContractFactory(hre, name, signerOrOptions);
|
198 | return factory.deploy(...args);
|
199 | }
|
200 | exports.deployContract = deployContract;
|
201 | async function getContractAtFromArtifact(hre, artifact, address, signer) {
|
202 | if (!isArtifact(artifact)) {
|
203 | throw new plugins_1.NomicLabsHardhatPluginError(pluginName, `You are trying to create a contract by artifact, but you have not passed a valid artifact parameter.`);
|
204 | }
|
205 | const factory = await getContractFactoryByAbiAndBytecode(hre, artifact.abi, "0x", signer);
|
206 | let contract = factory.attach(address);
|
207 |
|
208 | if (contract.provider === null) {
|
209 | contract = contract.connect(hre.ethers.provider);
|
210 | }
|
211 | return contract;
|
212 | }
|
213 | exports.getContractAtFromArtifact = getContractAtFromArtifact;
|
214 |
|
215 |
|
216 |
|
217 |
|
218 | function addGasToAbiMethodsIfNecessary(networkConfig, abi) {
|
219 | const { BigNumber } = require("ethers");
|
220 | if (networkConfig.gas === "auto" || networkConfig.gas === undefined) {
|
221 | return abi;
|
222 | }
|
223 |
|
224 |
|
225 |
|
226 |
|
227 |
|
228 | const gasLimit = BigNumber.from(networkConfig.gas).sub(1000000).toHexString();
|
229 | const modifiedAbi = [];
|
230 | for (const abiElement of abi) {
|
231 | if (abiElement.type !== "function") {
|
232 | modifiedAbi.push(abiElement);
|
233 | continue;
|
234 | }
|
235 | modifiedAbi.push({
|
236 | ...abiElement,
|
237 | gas: gasLimit,
|
238 | });
|
239 | }
|
240 | return modifiedAbi;
|
241 | }
|
242 | function linkBytecode(artifact, libraries) {
|
243 | let bytecode = artifact.bytecode;
|
244 |
|
245 | for (const { sourceName, libraryName, address } of libraries) {
|
246 | const linkReferences = artifact.linkReferences[sourceName][libraryName];
|
247 | for (const { start, length } of linkReferences) {
|
248 | bytecode =
|
249 | bytecode.substr(0, 2 + start * 2) +
|
250 | address.substr(2) +
|
251 | bytecode.substr(2 + (start + length) * 2);
|
252 | }
|
253 | }
|
254 | return bytecode;
|
255 | }
|
256 |
|
\ | No newline at end of file |