hardhat 2.6.6 → 2.8.0-dev.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +39 -0
- package/builtin-tasks/compile.js +9 -0
- package/builtin-tasks/compile.js.map +1 -1
- package/builtin-tasks/node.js +26 -9
- package/builtin-tasks/node.js.map +1 -1
- package/internal/artifacts.d.ts +49 -0
- package/internal/artifacts.d.ts.map +1 -1
- package/internal/artifacts.js +191 -55
- package/internal/artifacts.js.map +1 -1
- package/internal/cli/analytics.js +2 -2
- package/internal/cli/analytics.js.map +1 -1
- package/internal/cli/cli.js +1 -1
- package/internal/cli/cli.js.map +1 -1
- package/internal/constants.d.ts +2 -0
- package/internal/constants.d.ts.map +1 -1
- package/internal/constants.js +3 -1
- package/internal/constants.js.map +1 -1
- package/internal/core/config/config-loading.d.ts.map +1 -1
- package/internal/core/config/config-loading.js +16 -2
- package/internal/core/config/config-loading.js.map +1 -1
- package/internal/core/config/config-resolution.d.ts.map +1 -1
- package/internal/core/config/config-resolution.js +42 -4
- package/internal/core/config/config-resolution.js.map +1 -1
- package/internal/core/config/config-validation.d.ts +1 -0
- package/internal/core/config/config-validation.d.ts.map +1 -1
- package/internal/core/config/config-validation.js +126 -13
- package/internal/core/config/config-validation.js.map +1 -1
- package/internal/core/config/default-config.d.ts +1 -0
- package/internal/core/config/default-config.d.ts.map +1 -1
- package/internal/core/config/default-config.js +69 -4
- package/internal/core/config/default-config.js.map +1 -1
- package/internal/core/errors-list.d.ts +14 -0
- package/internal/core/errors-list.d.ts.map +1 -1
- package/internal/core/errors-list.js +21 -2
- package/internal/core/errors-list.js.map +1 -1
- package/internal/core/jsonrpc/types/output/log.d.ts +1 -0
- package/internal/core/jsonrpc/types/output/log.d.ts.map +1 -1
- package/internal/core/jsonrpc/types/output/log.js +1 -0
- package/internal/core/jsonrpc/types/output/log.js.map +1 -1
- package/internal/core/jsonrpc/types/output/receipt.d.ts +1 -0
- package/internal/core/jsonrpc/types/output/receipt.d.ts.map +1 -1
- package/internal/core/params/hardhat-params.js +2 -2
- package/internal/core/params/hardhat-params.js.map +1 -1
- package/internal/core/providers/accounts.d.ts.map +1 -1
- package/internal/core/providers/accounts.js +14 -0
- package/internal/core/providers/accounts.js.map +1 -1
- package/internal/core/providers/construction.d.ts.map +1 -1
- package/internal/core/providers/construction.js +4 -2
- package/internal/core/providers/construction.js.map +1 -1
- package/internal/core/providers/gas-providers.d.ts.map +1 -1
- package/internal/core/providers/gas-providers.js +1 -1
- package/internal/core/providers/gas-providers.js.map +1 -1
- package/internal/core/typescript-support.d.ts +1 -1
- package/internal/core/typescript-support.d.ts.map +1 -1
- package/internal/core/typescript-support.js +4 -1
- package/internal/core/typescript-support.js.map +1 -1
- package/internal/hardhat-network/jsonrpc/client.d.ts +2 -0
- package/internal/hardhat-network/jsonrpc/client.d.ts.map +1 -1
- package/internal/hardhat-network/provider/BlockchainData.d.ts +1 -1
- package/internal/hardhat-network/provider/TransactionQueue.d.ts +2 -1
- package/internal/hardhat-network/provider/TransactionQueue.d.ts.map +1 -1
- package/internal/hardhat-network/provider/TransactionQueue.js +16 -2
- package/internal/hardhat-network/provider/TransactionQueue.js.map +1 -1
- package/internal/hardhat-network/provider/fork/ForkBlockchain.d.ts.map +1 -1
- package/internal/hardhat-network/provider/fork/ForkBlockchain.js +1 -3
- package/internal/hardhat-network/provider/fork/ForkBlockchain.js.map +1 -1
- package/internal/hardhat-network/provider/modules/hardhat.d.ts +3 -0
- package/internal/hardhat-network/provider/modules/hardhat.d.ts.map +1 -1
- package/internal/hardhat-network/provider/modules/hardhat.js +16 -0
- package/internal/hardhat-network/provider/modules/hardhat.js.map +1 -1
- package/internal/hardhat-network/provider/modules/personal.d.ts +9 -0
- package/internal/hardhat-network/provider/modules/personal.d.ts.map +1 -0
- package/internal/hardhat-network/provider/modules/personal.js +31 -0
- package/internal/hardhat-network/provider/modules/personal.js.map +1 -0
- package/internal/hardhat-network/provider/node-types.d.ts +7 -1
- package/internal/hardhat-network/provider/node-types.d.ts.map +1 -1
- package/internal/hardhat-network/provider/node-types.js.map +1 -1
- package/internal/hardhat-network/provider/node.d.ts +11 -2
- package/internal/hardhat-network/provider/node.d.ts.map +1 -1
- package/internal/hardhat-network/provider/node.js +108 -31
- package/internal/hardhat-network/provider/node.js.map +1 -1
- package/internal/hardhat-network/provider/output.d.ts +1 -1
- package/internal/hardhat-network/provider/output.d.ts.map +1 -1
- package/internal/hardhat-network/provider/output.js +9 -6
- package/internal/hardhat-network/provider/output.js.map +1 -1
- package/internal/hardhat-network/provider/provider.d.ts +8 -3
- package/internal/hardhat-network/provider/provider.d.ts.map +1 -1
- package/internal/hardhat-network/provider/provider.js +14 -2
- package/internal/hardhat-network/provider/provider.js.map +1 -1
- package/internal/hardhat-network/stack-traces/error-inferrer.d.ts.map +1 -1
- package/internal/hardhat-network/stack-traces/error-inferrer.js +14 -0
- package/internal/hardhat-network/stack-traces/error-inferrer.js.map +1 -1
- package/internal/hardhat-network/stack-traces/solidityTracer.d.ts +1 -1
- package/internal/hardhat-network/stack-traces/solidityTracer.js +1 -1
- package/package.json +5 -5
- package/register.js +1 -1
- package/register.js.map +1 -1
- package/src/builtin-tasks/compile.ts +14 -0
- package/src/builtin-tasks/node.ts +41 -9
- package/src/internal/artifacts.ts +268 -71
- package/src/internal/cli/analytics.ts +1 -1
- package/src/internal/cli/cli.ts +1 -1
- package/src/internal/constants.ts +3 -0
- package/src/internal/core/config/config-loading.ts +24 -2
- package/src/internal/core/config/config-resolution.ts +61 -3
- package/src/internal/core/config/config-validation.ts +217 -15
- package/src/internal/core/config/default-config.ts +67 -2
- package/src/internal/core/errors-list.ts +21 -2
- package/src/internal/core/jsonrpc/types/output/log.ts +1 -0
- package/src/internal/core/params/hardhat-params.ts +2 -2
- package/src/internal/core/providers/accounts.ts +19 -0
- package/src/internal/core/providers/construction.ts +9 -2
- package/src/internal/core/providers/gas-providers.ts +1 -1
- package/src/internal/core/typescript-support.ts +5 -1
- package/src/internal/hardhat-network/provider/TransactionQueue.ts +31 -4
- package/src/internal/hardhat-network/provider/fork/ForkBlockchain.ts +1 -3
- package/src/internal/hardhat-network/provider/modules/hardhat.ts +23 -0
- package/src/internal/hardhat-network/provider/modules/personal.ts +39 -0
- package/src/internal/hardhat-network/provider/node-types.ts +8 -1
- package/src/internal/hardhat-network/provider/node.ts +164 -29
- package/src/internal/hardhat-network/provider/output.ts +9 -9
- package/src/internal/hardhat-network/provider/provider.ts +18 -1
- package/src/internal/hardhat-network/stack-traces/error-inferrer.ts +19 -0
- package/src/internal/hardhat-network/stack-traces/solidityTracer.ts +1 -1
- package/src/register.ts +1 -1
- package/src/types/config.ts +42 -0
- package/src/utils/contract-names.ts +112 -0
- package/src/utils/source-names.ts +1 -1
- package/types/config.d.ts +26 -0
- package/types/config.d.ts.map +1 -1
- package/utils/contract-names.d.ts +10 -0
- package/utils/contract-names.d.ts.map +1 -1
- package/utils/contract-names.js +92 -1
- package/utils/contract-names.js.map +1 -1
- package/utils/source-names.d.ts +1 -1
- package/utils/source-names.js +1 -1
|
@@ -20,6 +20,7 @@ import {
|
|
|
20
20
|
JsonRpcServer,
|
|
21
21
|
} from "../types";
|
|
22
22
|
|
|
23
|
+
import { HARDHAT_NETWORK_MNEMONIC } from "../internal/core/config/default-config";
|
|
23
24
|
import {
|
|
24
25
|
TASK_NODE,
|
|
25
26
|
TASK_NODE_CREATE_SERVER,
|
|
@@ -31,10 +32,23 @@ import { watchCompilerOutput } from "./utils/watch";
|
|
|
31
32
|
|
|
32
33
|
const log = debug("hardhat:core:tasks:node");
|
|
33
34
|
|
|
35
|
+
function printDefaultConfigWarning() {
|
|
36
|
+
console.log(
|
|
37
|
+
chalk.bold(
|
|
38
|
+
"WARNING: These accounts, and their private keys, are publicly known."
|
|
39
|
+
)
|
|
40
|
+
);
|
|
41
|
+
console.log(
|
|
42
|
+
chalk.bold(
|
|
43
|
+
"Any funds sent to them on Mainnet or any other live network WILL BE LOST."
|
|
44
|
+
)
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
|
|
34
48
|
function logHardhatNetworkAccounts(networkConfig: HardhatNetworkConfig) {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
49
|
+
const isDefaultConfig =
|
|
50
|
+
!Array.isArray(networkConfig.accounts) &&
|
|
51
|
+
networkConfig.accounts.mnemonic === HARDHAT_NETWORK_MNEMONIC;
|
|
38
52
|
|
|
39
53
|
const { BN, bufferToHex, privateToAddress, toBuffer } =
|
|
40
54
|
require("ethereumjs-util") as typeof EthereumjsUtilT;
|
|
@@ -42,20 +56,38 @@ function logHardhatNetworkAccounts(networkConfig: HardhatNetworkConfig) {
|
|
|
42
56
|
console.log("Accounts");
|
|
43
57
|
console.log("========");
|
|
44
58
|
|
|
59
|
+
if (isDefaultConfig) {
|
|
60
|
+
console.log();
|
|
61
|
+
printDefaultConfigWarning();
|
|
62
|
+
console.log();
|
|
63
|
+
}
|
|
64
|
+
|
|
45
65
|
const accounts = normalizeHardhatNetworkAccountsConfig(
|
|
46
66
|
networkConfig.accounts
|
|
47
67
|
);
|
|
48
68
|
|
|
49
69
|
for (const [index, account] of accounts.entries()) {
|
|
50
70
|
const address = bufferToHex(privateToAddress(toBuffer(account.privateKey)));
|
|
51
|
-
|
|
71
|
+
|
|
52
72
|
const balance = new BN(account.balance)
|
|
53
73
|
.div(new BN(10).pow(new BN(18)))
|
|
54
74
|
.toString(10);
|
|
55
75
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
76
|
+
let entry = `Account #${index}: ${address} (${balance} ETH)`;
|
|
77
|
+
|
|
78
|
+
if (isDefaultConfig) {
|
|
79
|
+
const privateKey = bufferToHex(toBuffer(account.privateKey));
|
|
80
|
+
entry += `
|
|
81
|
+
Private Key: ${privateKey}`;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
console.log(entry);
|
|
85
|
+
console.log();
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
if (isDefaultConfig) {
|
|
89
|
+
printDefaultConfigWarning();
|
|
90
|
+
console.log();
|
|
59
91
|
}
|
|
60
92
|
}
|
|
61
93
|
|
|
@@ -268,7 +300,7 @@ task(TASK_NODE, "Starts a JSON-RPC server on top of Hardhat Network")
|
|
|
268
300
|
forkUrl,
|
|
269
301
|
});
|
|
270
302
|
|
|
271
|
-
// the default hostname is "
|
|
303
|
+
// the default hostname is "127.0.0.1" unless we are inside a docker
|
|
272
304
|
// container, in that case we use "0.0.0.0"
|
|
273
305
|
let hostname: string;
|
|
274
306
|
if (hostnameParam !== undefined) {
|
|
@@ -278,7 +310,7 @@ task(TASK_NODE, "Starts a JSON-RPC server on top of Hardhat Network")
|
|
|
278
310
|
if (insideDocker) {
|
|
279
311
|
hostname = "0.0.0.0";
|
|
280
312
|
} else {
|
|
281
|
-
hostname = "
|
|
313
|
+
hostname = "127.0.0.1";
|
|
282
314
|
}
|
|
283
315
|
}
|
|
284
316
|
|
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
getFullyQualifiedName,
|
|
16
16
|
isFullyQualifiedName,
|
|
17
17
|
parseFullyQualifiedName,
|
|
18
|
+
findDistance,
|
|
18
19
|
} from "../utils/contract-names";
|
|
19
20
|
import { replaceBackslashes } from "../utils/source-names";
|
|
20
21
|
|
|
@@ -23,6 +24,7 @@ import {
|
|
|
23
24
|
BUILD_INFO_DIR_NAME,
|
|
24
25
|
BUILD_INFO_FORMAT_VERSION,
|
|
25
26
|
DEBUG_FILE_FORMAT_VERSION,
|
|
27
|
+
EDIT_DISTANCE_THRESHOLD,
|
|
26
28
|
} from "./constants";
|
|
27
29
|
import { HardhatError } from "./core/errors";
|
|
28
30
|
import { ERRORS } from "./core/errors-list";
|
|
@@ -45,71 +47,13 @@ export class Artifacts implements IArtifacts {
|
|
|
45
47
|
}
|
|
46
48
|
|
|
47
49
|
public async readArtifact(name: string): Promise<Artifact> {
|
|
48
|
-
const { trueCasePath } = await import("true-case-path");
|
|
49
50
|
const artifactPath = await this._getArtifactPath(name);
|
|
50
|
-
|
|
51
|
-
try {
|
|
52
|
-
const trueCaseArtifactPath = await trueCasePath(
|
|
53
|
-
path.relative(this._artifactsPath, artifactPath),
|
|
54
|
-
this._artifactsPath
|
|
55
|
-
);
|
|
56
|
-
|
|
57
|
-
if (artifactPath !== trueCaseArtifactPath) {
|
|
58
|
-
throw new HardhatError(ERRORS.ARTIFACTS.WRONG_CASING, {
|
|
59
|
-
correct: trueCaseArtifactPath,
|
|
60
|
-
incorrect: artifactPath,
|
|
61
|
-
});
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
return await fsExtra.readJson(trueCaseArtifactPath);
|
|
65
|
-
} catch (error) {
|
|
66
|
-
if (
|
|
67
|
-
typeof error.message === "string" &&
|
|
68
|
-
error.message.includes("no matching file exists")
|
|
69
|
-
) {
|
|
70
|
-
throw new HardhatError(ERRORS.INTERNAL.WRONG_ARTIFACT_PATH, {
|
|
71
|
-
contractName: name,
|
|
72
|
-
artifactPath,
|
|
73
|
-
});
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
// eslint-disable-next-line @nomiclabs/hardhat-internal-rules/only-hardhat-error
|
|
77
|
-
throw error;
|
|
78
|
-
}
|
|
51
|
+
return fsExtra.readJson(artifactPath);
|
|
79
52
|
}
|
|
80
53
|
|
|
81
54
|
public readArtifactSync(name: string): Artifact {
|
|
82
|
-
const { trueCasePathSync } = require("true-case-path");
|
|
83
55
|
const artifactPath = this._getArtifactPathSync(name);
|
|
84
|
-
|
|
85
|
-
try {
|
|
86
|
-
const trueCaseArtifactPath = trueCasePathSync(
|
|
87
|
-
path.relative(this._artifactsPath, artifactPath),
|
|
88
|
-
this._artifactsPath
|
|
89
|
-
);
|
|
90
|
-
|
|
91
|
-
if (artifactPath !== trueCaseArtifactPath) {
|
|
92
|
-
throw new HardhatError(ERRORS.ARTIFACTS.WRONG_CASING, {
|
|
93
|
-
correct: trueCaseArtifactPath,
|
|
94
|
-
incorrect: artifactPath,
|
|
95
|
-
});
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
return fsExtra.readJsonSync(trueCaseArtifactPath);
|
|
99
|
-
} catch (error) {
|
|
100
|
-
if (
|
|
101
|
-
typeof error.message === "string" &&
|
|
102
|
-
error.message.includes("no matching file exists")
|
|
103
|
-
) {
|
|
104
|
-
throw new HardhatError(ERRORS.INTERNAL.WRONG_ARTIFACT_PATH, {
|
|
105
|
-
contractName: name,
|
|
106
|
-
artifactPath,
|
|
107
|
-
});
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
// eslint-disable-next-line @nomiclabs/hardhat-internal-rules/only-hardhat-error
|
|
111
|
-
throw error;
|
|
112
|
-
}
|
|
56
|
+
return fsExtra.readJsonSync(artifactPath);
|
|
113
57
|
}
|
|
114
58
|
|
|
115
59
|
public async artifactExists(name: string): Promise<boolean> {
|
|
@@ -130,7 +74,7 @@ export class Artifacts implements IArtifacts {
|
|
|
130
74
|
fullyQualifiedName: string
|
|
131
75
|
): Promise<BuildInfo | undefined> {
|
|
132
76
|
const artifactPath =
|
|
133
|
-
this.
|
|
77
|
+
this.formArtifactPathFromFullyQualifiedName(fullyQualifiedName);
|
|
134
78
|
|
|
135
79
|
const debugFilePath = this._getDebugFilePath(artifactPath);
|
|
136
80
|
const buildInfoPath = await this._getBuildInfoFromDebugFile(debugFilePath);
|
|
@@ -173,7 +117,7 @@ export class Artifacts implements IArtifacts {
|
|
|
173
117
|
);
|
|
174
118
|
|
|
175
119
|
const artifactPath =
|
|
176
|
-
this.
|
|
120
|
+
this.formArtifactPathFromFullyQualifiedName(fullyQualifiedName);
|
|
177
121
|
|
|
178
122
|
await fsExtra.ensureDir(path.dirname(artifactPath));
|
|
179
123
|
|
|
@@ -280,6 +224,18 @@ export class Artifacts implements IArtifacts {
|
|
|
280
224
|
}
|
|
281
225
|
}
|
|
282
226
|
|
|
227
|
+
/**
|
|
228
|
+
* Returns the absolute path to the given artifact
|
|
229
|
+
*/
|
|
230
|
+
public formArtifactPathFromFullyQualifiedName(
|
|
231
|
+
fullyQualifiedName: string
|
|
232
|
+
): string {
|
|
233
|
+
const { sourceName, contractName } =
|
|
234
|
+
parseFullyQualifiedName(fullyQualifiedName);
|
|
235
|
+
|
|
236
|
+
return path.join(this._artifactsPath, sourceName, `${contractName}.json`);
|
|
237
|
+
}
|
|
238
|
+
|
|
283
239
|
private _getBuildInfoName(
|
|
284
240
|
solcVersion: string,
|
|
285
241
|
solcLongVersion: string,
|
|
@@ -307,7 +263,7 @@ export class Artifacts implements IArtifacts {
|
|
|
307
263
|
*/
|
|
308
264
|
private async _getArtifactPath(name: string): Promise<string> {
|
|
309
265
|
if (isFullyQualifiedName(name)) {
|
|
310
|
-
return this.
|
|
266
|
+
return this._getValidArtifactPathFromFullyQualifiedName(name);
|
|
311
267
|
}
|
|
312
268
|
|
|
313
269
|
const files = await this.getArtifactPaths();
|
|
@@ -346,9 +302,11 @@ export class Artifacts implements IArtifacts {
|
|
|
346
302
|
}
|
|
347
303
|
|
|
348
304
|
private _getArtifactPathsSync(): string[] {
|
|
349
|
-
|
|
305
|
+
const paths = globSync(path.join(this._artifactsPath, "**/*.json"), {
|
|
350
306
|
ignore: [this._buildInfosGlob, this._dbgsGlob],
|
|
351
307
|
});
|
|
308
|
+
|
|
309
|
+
return paths.sort();
|
|
352
310
|
}
|
|
353
311
|
|
|
354
312
|
/**
|
|
@@ -356,13 +314,69 @@ export class Artifacts implements IArtifacts {
|
|
|
356
314
|
*/
|
|
357
315
|
private _getArtifactPathSync(name: string): string {
|
|
358
316
|
if (isFullyQualifiedName(name)) {
|
|
359
|
-
return this.
|
|
317
|
+
return this._getValidArtifactPathFromFullyQualifiedNameSync(name);
|
|
360
318
|
}
|
|
361
319
|
|
|
362
320
|
const files = this._getArtifactPathsSync();
|
|
363
321
|
return this._getArtifactPathFromFiles(name, files);
|
|
364
322
|
}
|
|
365
323
|
|
|
324
|
+
/**
|
|
325
|
+
* Same signature as imported function, but abstracted to handle the only error we consistently care about
|
|
326
|
+
*/
|
|
327
|
+
private async _trueCasePath(
|
|
328
|
+
filePath: string,
|
|
329
|
+
basePath?: string
|
|
330
|
+
): Promise<string | null> {
|
|
331
|
+
const { trueCasePath } = await import("true-case-path");
|
|
332
|
+
|
|
333
|
+
try {
|
|
334
|
+
const result = await trueCasePath(filePath, basePath);
|
|
335
|
+
return result;
|
|
336
|
+
} catch (error: unknown) {
|
|
337
|
+
if (error instanceof Error) {
|
|
338
|
+
if (error.message.includes("no matching file exists")) {
|
|
339
|
+
return null;
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
// eslint-disable-next-line @nomiclabs/hardhat-internal-rules/only-hardhat-error
|
|
344
|
+
throw error;
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
/**
|
|
349
|
+
* Same signature as imported function, but abstracted to handle the only error we consistently care about
|
|
350
|
+
* and synchronous
|
|
351
|
+
*/
|
|
352
|
+
private _trueCasePathSync(
|
|
353
|
+
filePath: string,
|
|
354
|
+
basePath?: string
|
|
355
|
+
): string | null {
|
|
356
|
+
const { trueCasePathSync } = require("true-case-path");
|
|
357
|
+
|
|
358
|
+
try {
|
|
359
|
+
const result = trueCasePathSync(filePath, basePath);
|
|
360
|
+
return result;
|
|
361
|
+
} catch (error: unknown) {
|
|
362
|
+
if (error instanceof Error) {
|
|
363
|
+
if (error.message.includes("no matching file exists")) {
|
|
364
|
+
return null;
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
// eslint-disable-next-line @nomiclabs/hardhat-internal-rules/only-hardhat-error
|
|
369
|
+
throw error;
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
/**
|
|
374
|
+
* DO NOT DELETE OR CHANGE
|
|
375
|
+
*
|
|
376
|
+
* use this.formArtifactPathFromFullyQualifiedName instead
|
|
377
|
+
* @deprecated until typechain migrates to public version
|
|
378
|
+
* @see https://github.com/dethcrypto/TypeChain/issues/544
|
|
379
|
+
*/
|
|
366
380
|
private _getArtifactPathFromFullyQualifiedName(
|
|
367
381
|
fullyQualifiedName: string
|
|
368
382
|
): string {
|
|
@@ -372,6 +386,191 @@ export class Artifacts implements IArtifacts {
|
|
|
372
386
|
return path.join(this._artifactsPath, sourceName, `${contractName}.json`);
|
|
373
387
|
}
|
|
374
388
|
|
|
389
|
+
private async _getValidArtifactPathFromFullyQualifiedName(
|
|
390
|
+
fullyQualifiedName: string
|
|
391
|
+
): Promise<string> {
|
|
392
|
+
const artifactPath =
|
|
393
|
+
this.formArtifactPathFromFullyQualifiedName(fullyQualifiedName);
|
|
394
|
+
|
|
395
|
+
const trueCaseArtifactPath = await this._trueCasePath(
|
|
396
|
+
path.relative(this._artifactsPath, artifactPath),
|
|
397
|
+
this._artifactsPath
|
|
398
|
+
);
|
|
399
|
+
|
|
400
|
+
if (trueCaseArtifactPath === null) {
|
|
401
|
+
return this._handleWrongArtifactForFullyQualifiedName(fullyQualifiedName);
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
if (artifactPath !== trueCaseArtifactPath) {
|
|
405
|
+
throw new HardhatError(ERRORS.ARTIFACTS.WRONG_CASING, {
|
|
406
|
+
correct: trueCaseArtifactPath,
|
|
407
|
+
incorrect: artifactPath,
|
|
408
|
+
});
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
return artifactPath;
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
private _getAllContractNamesFromFiles(files: string[]): string[] {
|
|
415
|
+
return files.map((file) => {
|
|
416
|
+
const fqn = this._getFullyQualifiedNameFromPath(file);
|
|
417
|
+
return parseFullyQualifiedName(fqn).contractName;
|
|
418
|
+
});
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
private _getAllFullyQualifiedNamesSync(): string[] {
|
|
422
|
+
const paths = this._getArtifactPathsSync();
|
|
423
|
+
return paths.map((p) => this._getFullyQualifiedNameFromPath(p)).sort();
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
private _formatSuggestions(names: string[], contractName?: string): string {
|
|
427
|
+
switch (names.length) {
|
|
428
|
+
case 0:
|
|
429
|
+
return "";
|
|
430
|
+
case 1:
|
|
431
|
+
return `Did you mean "${names[0]}"?`;
|
|
432
|
+
default:
|
|
433
|
+
return `We found some that were similar:
|
|
434
|
+
|
|
435
|
+
${names.map((n) => ` * ${n}`).join(os.EOL)}
|
|
436
|
+
|
|
437
|
+
Please replace "${contractName}" for the correct contract name wherever you are trying to read its artifact.
|
|
438
|
+
`;
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
private _handleWrongArtifactForFullyQualifiedName(
|
|
443
|
+
fullyQualifiedName: string
|
|
444
|
+
): never {
|
|
445
|
+
const names = this._getAllFullyQualifiedNamesSync();
|
|
446
|
+
|
|
447
|
+
const similarNames = this._getSimilarContractNames(
|
|
448
|
+
fullyQualifiedName,
|
|
449
|
+
names
|
|
450
|
+
);
|
|
451
|
+
|
|
452
|
+
throw new HardhatError(ERRORS.ARTIFACTS.NOT_FOUND, {
|
|
453
|
+
contractName: fullyQualifiedName,
|
|
454
|
+
suggestion: this._formatSuggestions(similarNames),
|
|
455
|
+
});
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
private _handleWrongArtifactForContractName(
|
|
459
|
+
contractName: string,
|
|
460
|
+
files: string[]
|
|
461
|
+
): never {
|
|
462
|
+
const names = this._getAllContractNamesFromFiles(files);
|
|
463
|
+
|
|
464
|
+
let similarNames = this._getSimilarContractNames(contractName, names);
|
|
465
|
+
|
|
466
|
+
if (similarNames.length > 1) {
|
|
467
|
+
similarNames = this._filterDuplicatesAsFullyQualifiedNames(
|
|
468
|
+
files,
|
|
469
|
+
similarNames
|
|
470
|
+
);
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
throw new HardhatError(ERRORS.ARTIFACTS.NOT_FOUND, {
|
|
474
|
+
contractName,
|
|
475
|
+
suggestion: this._formatSuggestions(similarNames, contractName),
|
|
476
|
+
});
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
/**
|
|
480
|
+
* If the project has these contracts:
|
|
481
|
+
* - 'contracts/Greeter.sol:Greeter'
|
|
482
|
+
* - 'contracts/Meeter.sol:Greeter'
|
|
483
|
+
* - 'contracts/Greater.sol:Greater'
|
|
484
|
+
* And the user tries to get an artifact with the name 'Greter', then
|
|
485
|
+
* the suggestions will be 'Greeter', 'Greeter', and 'Greater'.
|
|
486
|
+
*
|
|
487
|
+
* We don't want to show duplicates here, so we use FQNs for those. The
|
|
488
|
+
* suggestions will then be:
|
|
489
|
+
* - 'contracts/Greeter.sol:Greeter'
|
|
490
|
+
* - 'contracts/Meeter.sol:Greeter'
|
|
491
|
+
* - 'Greater'
|
|
492
|
+
*/
|
|
493
|
+
private _filterDuplicatesAsFullyQualifiedNames(
|
|
494
|
+
files: string[],
|
|
495
|
+
similarNames: string[]
|
|
496
|
+
): string[] {
|
|
497
|
+
const outputNames = [];
|
|
498
|
+
const groups = similarNames.reduce((obj, cur) => {
|
|
499
|
+
obj[cur] = obj[cur] ? obj[cur] + 1 : 1;
|
|
500
|
+
return obj;
|
|
501
|
+
}, {} as { [k: string]: number });
|
|
502
|
+
|
|
503
|
+
for (const [name, occurrences] of Object.entries(groups)) {
|
|
504
|
+
if (occurrences > 1) {
|
|
505
|
+
for (const file of files) {
|
|
506
|
+
if (path.basename(file) === `${name}.json`) {
|
|
507
|
+
outputNames.push(this._getFullyQualifiedNameFromPath(file));
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
continue;
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
outputNames.push(name);
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
return outputNames;
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
/**
|
|
520
|
+
*
|
|
521
|
+
* @param givenName can be FQN or contract name
|
|
522
|
+
* @param names MUST match type of givenName (i.e. array of FQN's if givenName is FQN)
|
|
523
|
+
* @returns
|
|
524
|
+
*/
|
|
525
|
+
private _getSimilarContractNames(
|
|
526
|
+
givenName: string,
|
|
527
|
+
names: string[]
|
|
528
|
+
): string[] {
|
|
529
|
+
let shortestDistance = EDIT_DISTANCE_THRESHOLD;
|
|
530
|
+
let mostSimilarNames: string[] = [];
|
|
531
|
+
for (const name of names) {
|
|
532
|
+
const distance = findDistance(givenName, name);
|
|
533
|
+
|
|
534
|
+
if (distance < shortestDistance) {
|
|
535
|
+
shortestDistance = distance;
|
|
536
|
+
mostSimilarNames = [name];
|
|
537
|
+
continue;
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
if (distance === shortestDistance) {
|
|
541
|
+
mostSimilarNames.push(name);
|
|
542
|
+
continue;
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
return mostSimilarNames;
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
private _getValidArtifactPathFromFullyQualifiedNameSync(
|
|
550
|
+
fullyQualifiedName: string
|
|
551
|
+
): string {
|
|
552
|
+
const artifactPath =
|
|
553
|
+
this.formArtifactPathFromFullyQualifiedName(fullyQualifiedName);
|
|
554
|
+
|
|
555
|
+
const trueCaseArtifactPath = this._trueCasePathSync(
|
|
556
|
+
path.relative(this._artifactsPath, artifactPath),
|
|
557
|
+
this._artifactsPath
|
|
558
|
+
);
|
|
559
|
+
|
|
560
|
+
if (trueCaseArtifactPath === null) {
|
|
561
|
+
return this._handleWrongArtifactForFullyQualifiedName(fullyQualifiedName);
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
if (artifactPath !== trueCaseArtifactPath) {
|
|
565
|
+
throw new HardhatError(ERRORS.ARTIFACTS.WRONG_CASING, {
|
|
566
|
+
correct: trueCaseArtifactPath,
|
|
567
|
+
incorrect: artifactPath,
|
|
568
|
+
});
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
return artifactPath;
|
|
572
|
+
}
|
|
573
|
+
|
|
375
574
|
private _getDebugFilePath(artifactPath: string): string {
|
|
376
575
|
return artifactPath.replace(/\.json$/, ".dbg.json");
|
|
377
576
|
}
|
|
@@ -385,15 +584,13 @@ export class Artifacts implements IArtifacts {
|
|
|
385
584
|
});
|
|
386
585
|
|
|
387
586
|
if (matchingFiles.length === 0) {
|
|
388
|
-
|
|
389
|
-
contractName,
|
|
390
|
-
});
|
|
587
|
+
return this._handleWrongArtifactForContractName(contractName, files);
|
|
391
588
|
}
|
|
392
589
|
|
|
393
590
|
if (matchingFiles.length > 1) {
|
|
394
|
-
const candidates = matchingFiles
|
|
395
|
-
|
|
396
|
-
|
|
591
|
+
const candidates = matchingFiles.map((file) =>
|
|
592
|
+
this._getFullyQualifiedNameFromPath(file)
|
|
593
|
+
);
|
|
397
594
|
|
|
398
595
|
throw new HardhatError(ERRORS.ARTIFACTS.MULTIPLE_FOUND, {
|
|
399
596
|
contractName,
|
|
@@ -3,7 +3,7 @@ import debug from "debug";
|
|
|
3
3
|
import fetch from "node-fetch";
|
|
4
4
|
import os from "os";
|
|
5
5
|
import qs from "qs";
|
|
6
|
-
import uuid from "uuid
|
|
6
|
+
import { v4 as uuid } from "uuid";
|
|
7
7
|
|
|
8
8
|
import * as builtinTaskNames from "../../builtin-tasks/task-names";
|
|
9
9
|
import { isLocalDev } from "../core/execution-mode";
|
package/src/internal/cli/cli.ts
CHANGED
|
@@ -20,10 +20,13 @@ export const HARDHAT_NETWORK_SUPPORTED_HARDFORKS = [
|
|
|
20
20
|
"london",
|
|
21
21
|
];
|
|
22
22
|
|
|
23
|
+
export const HARDHAT_MEMPOOL_SUPPORTED_ORDERS = <const>["fifo", "priority"];
|
|
24
|
+
|
|
23
25
|
export const ARTIFACT_FORMAT_VERSION = "hh-sol-artifact-1";
|
|
24
26
|
export const DEBUG_FILE_FORMAT_VERSION = "hh-sol-dbg-1";
|
|
25
27
|
export const BUILD_INFO_FORMAT_VERSION = "hh-sol-build-info-1";
|
|
26
28
|
export const BUILD_INFO_DIR_NAME = "build-info";
|
|
29
|
+
export const EDIT_DISTANCE_THRESHOLD = 3;
|
|
27
30
|
|
|
28
31
|
export const HARDHAT_NETWORK_RESET_EVENT = "hardhatNetworkReset";
|
|
29
32
|
export const HARDHAT_NETWORK_REVERT_SNAPSHOT_EVENT =
|
|
@@ -92,6 +92,7 @@ export function loadConfigAndTasks(
|
|
|
92
92
|
|
|
93
93
|
if (showSolidityConfigWarnings) {
|
|
94
94
|
checkUnsupportedSolidityConfig(resolved);
|
|
95
|
+
checkUnsupportedRemappings(resolved);
|
|
95
96
|
}
|
|
96
97
|
|
|
97
98
|
return resolved;
|
|
@@ -223,7 +224,7 @@ function checkMissingSolidityConfig(userConfig: any) {
|
|
|
223
224
|
if (userConfig.solidity === undefined) {
|
|
224
225
|
console.warn(
|
|
225
226
|
chalk.yellow(
|
|
226
|
-
`Solidity compiler is not configured. Version ${DEFAULT_SOLC_VERSION} will be used by default. Add a 'solidity' entry to your configuration to
|
|
227
|
+
`Solidity compiler is not configured. Version ${DEFAULT_SOLC_VERSION} will be used by default. Add a 'solidity' entry to your configuration to suppress this warning.
|
|
227
228
|
|
|
228
229
|
Learn more about compiler configuration at https://hardhat.org/config"
|
|
229
230
|
`
|
|
@@ -255,7 +256,28 @@ function checkUnsupportedSolidityConfig(resolvedConfig: HardhatConfig) {
|
|
|
255
256
|
unsupportedVersions.length === 1 ? "is" : "are"
|
|
256
257
|
} not fully supported yet. You can still use Hardhat, but some features, like stack traces, might not work correctly.
|
|
257
258
|
|
|
258
|
-
Learn more at https://hardhat.org/reference/solidity-support
|
|
259
|
+
Learn more at https://hardhat.org/reference/solidity-support
|
|
260
|
+
`
|
|
261
|
+
)
|
|
262
|
+
);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
function checkUnsupportedRemappings({ solidity }: HardhatConfig) {
|
|
267
|
+
const solcConfigs = [
|
|
268
|
+
...solidity.compilers,
|
|
269
|
+
...Object.values(solidity.overrides),
|
|
270
|
+
];
|
|
271
|
+
const remappings = solcConfigs.filter(
|
|
272
|
+
({ settings }) => settings.remappings !== undefined
|
|
273
|
+
);
|
|
274
|
+
|
|
275
|
+
if (remappings.length > 0) {
|
|
276
|
+
console.warn(
|
|
277
|
+
chalk.yellow(
|
|
278
|
+
`Solidity remappings are not currently supported; you may experience unexpected compilation results. Remove any 'remappings' fields from your configuration to suppress this warning.
|
|
279
|
+
|
|
280
|
+
Learn more about compiler configuration at https://hardhat.org/config
|
|
259
281
|
`
|
|
260
282
|
)
|
|
261
283
|
);
|