1 | import chalk from "chalk";
|
2 | import debug from "debug";
|
3 | import { BN, bufferToHex, privateToAddress, toBuffer } from "ethereumjs-util";
|
4 |
|
5 | import {
|
6 | JsonRpcServer,
|
7 | JsonRpcServerConfig,
|
8 | } from "../internal/buidler-evm/jsonrpc/server";
|
9 | import { BUIDLEREVM_NETWORK_NAME } from "../internal/constants";
|
10 | import { task, types } from "../internal/core/config/config-env";
|
11 | import { BuidlerError } from "../internal/core/errors";
|
12 | import { ERRORS } from "../internal/core/errors-list";
|
13 | import { createProvider } from "../internal/core/providers/construction";
|
14 | import { Reporter } from "../internal/sentry/reporter";
|
15 | import { lazyObject } from "../internal/util/lazy";
|
16 | import {
|
17 | BuidlerNetworkConfig,
|
18 | EthereumProvider,
|
19 | ResolvedBuidlerConfig,
|
20 | } from "../types";
|
21 |
|
22 | import { TASK_NODE } from "./task-names";
|
23 | import { watchCompilerOutput } from "./utils/watch";
|
24 |
|
25 | const log = debug("buidler:core:tasks:node");
|
26 |
|
27 | function _createBuidlerEVMProvider(
|
28 | config: ResolvedBuidlerConfig
|
29 | ): EthereumProvider {
|
30 | log("Creating BuidlerEVM Provider");
|
31 |
|
32 | const networkName = BUIDLEREVM_NETWORK_NAME;
|
33 | const networkConfig = config.networks[networkName] as BuidlerNetworkConfig;
|
34 |
|
35 | return lazyObject(() => {
|
36 | log(`Creating buidlerevm provider for JSON-RPC sever`);
|
37 | return createProvider(
|
38 | networkName,
|
39 | { loggingEnabled: true, ...networkConfig },
|
40 | config.solc.version,
|
41 | config.paths
|
42 | );
|
43 | });
|
44 | }
|
45 |
|
46 | function logBuidlerEvmAccounts(networkConfig: BuidlerNetworkConfig) {
|
47 | if (networkConfig.accounts === undefined) {
|
48 | return;
|
49 | }
|
50 |
|
51 | console.log("Accounts");
|
52 | console.log("========");
|
53 |
|
54 | for (const [index, account] of networkConfig.accounts.entries()) {
|
55 | const address = bufferToHex(privateToAddress(toBuffer(account.privateKey)));
|
56 | const privateKey = bufferToHex(toBuffer(account.privateKey));
|
57 | const balance = new BN(account.balance)
|
58 | .div(new BN(10).pow(new BN(18)))
|
59 | .toString(10);
|
60 |
|
61 | console.log(`Account #${index}: ${address} (${balance} ETH)
|
62 | Private Key: ${privateKey}
|
63 | `);
|
64 | }
|
65 | }
|
66 |
|
67 | export default function () {
|
68 | task(TASK_NODE, "Starts a JSON-RPC server on top of Buidler EVM")
|
69 | .addOptionalParam(
|
70 | "hostname",
|
71 | "The host to which to bind to for new connections",
|
72 | "localhost",
|
73 | types.string
|
74 | )
|
75 | .addOptionalParam(
|
76 | "port",
|
77 | "The port on which to listen for new connections",
|
78 | 8545,
|
79 | types.int
|
80 | )
|
81 | .setAction(
|
82 | async ({ hostname, port }, { network, buidlerArguments, config }) => {
|
83 | if (
|
84 | network.name !== BUIDLEREVM_NETWORK_NAME &&
|
85 |
|
86 |
|
87 |
|
88 |
|
89 | buidlerArguments.network !== undefined &&
|
90 | buidlerArguments.network !== config.defaultNetwork
|
91 | ) {
|
92 | throw new BuidlerError(
|
93 | ERRORS.BUILTIN_TASKS.JSONRPC_UNSUPPORTED_NETWORK
|
94 | );
|
95 | }
|
96 |
|
97 | try {
|
98 | const serverConfig: JsonRpcServerConfig = {
|
99 | hostname,
|
100 | port,
|
101 | provider: _createBuidlerEVMProvider(config),
|
102 | };
|
103 |
|
104 | const server = new JsonRpcServer(serverConfig);
|
105 |
|
106 | const { port: actualPort, address } = await server.listen();
|
107 |
|
108 | console.log(
|
109 | chalk.green(
|
110 | `Started HTTP and WebSocket JSON-RPC server at http://${address}:${actualPort}/`
|
111 | )
|
112 | );
|
113 |
|
114 | console.log();
|
115 |
|
116 | try {
|
117 | await watchCompilerOutput(
|
118 | server.getProvider(),
|
119 | config.solc,
|
120 | config.paths
|
121 | );
|
122 | } catch (error) {
|
123 | console.warn(
|
124 | chalk.yellow(
|
125 | "There was a problem watching the compiler output, changes in the contracts won't be reflected in the Buidler EVM. Run Buidler with --verbose to learn more."
|
126 | )
|
127 | );
|
128 |
|
129 | log(
|
130 | "Compilation output can't be watched. Please report this to help us improve Buidler.\n",
|
131 | error
|
132 | );
|
133 |
|
134 | Reporter.reportError(error);
|
135 | }
|
136 |
|
137 | const networkConfig = config.networks[
|
138 | BUIDLEREVM_NETWORK_NAME
|
139 | ] as BuidlerNetworkConfig;
|
140 | logBuidlerEvmAccounts(networkConfig);
|
141 |
|
142 | await server.waitUntilClosed();
|
143 | } catch (error) {
|
144 | if (BuidlerError.isBuidlerError(error)) {
|
145 | throw error;
|
146 | }
|
147 |
|
148 | throw new BuidlerError(
|
149 | ERRORS.BUILTIN_TASKS.JSONRPC_SERVER_ERROR,
|
150 | {
|
151 | error: error.message,
|
152 | },
|
153 | error
|
154 | );
|
155 | }
|
156 | }
|
157 | );
|
158 | }
|