UNPKG

4.75 kBPlain TextView Raw
1import chalk from "chalk";
2import debug from "debug";
3import { BN, bufferToHex, privateToAddress, toBuffer } from "ethereumjs-util";
4
5import {
6 JsonRpcServer,
7 JsonRpcServerConfig,
8} from "../internal/buidler-evm/jsonrpc/server";
9import { BUIDLEREVM_NETWORK_NAME } from "../internal/constants";
10import { task, types } from "../internal/core/config/config-env";
11import { BuidlerError } from "../internal/core/errors";
12import { ERRORS } from "../internal/core/errors-list";
13import { createProvider } from "../internal/core/providers/construction";
14import { Reporter } from "../internal/sentry/reporter";
15import { lazyObject } from "../internal/util/lazy";
16import {
17 BuidlerNetworkConfig,
18 EthereumProvider,
19 ResolvedBuidlerConfig,
20} from "../types";
21
22import { TASK_NODE } from "./task-names";
23import { watchCompilerOutput } from "./utils/watch";
24
25const log = debug("buidler:core:tasks:node");
26
27function _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
46function 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)
62Private Key: ${privateKey}
63`);
64 }
65}
66
67export 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 // We normally set the default network as buidlerArguments.network,
86 // so this check isn't enough, and we add the next one. This has the
87 // effect of `--network <defaultNetwork>` being a false negative, but
88 // not a big deal.
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}