evm-contracts-tools 0.0.1
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/AUTHORS.rst +37 -0
- package/COPYING +661 -0
- package/README.md +101 -0
- package/fs-worker.js +1 -0
- package/lib/bytecode-creation-get +438 -0
- package/lib/bytecode-runtime-get +411 -0
- package/lib/contract-get +485 -0
- package/lib/deployer-get +446 -0
- package/lib/deployer-verify +369 -0
- package/lib/evm-contract-call-dynamic +1050 -0
- package/lib/evm-contract-call-static +456 -0
- package/libevm-contracts-tools +206 -0
- package/package.json +115 -0
|
@@ -0,0 +1,1050 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// SPDX-License-Identifier: AGPL-3.0-or-later
|
|
4
|
+
|
|
5
|
+
/** ----------------------------------------------------------------------
|
|
6
|
+
* Copyright ©
|
|
7
|
+
* Pellegrino Prevete
|
|
8
|
+
* 2024, 2025, 2026
|
|
9
|
+
*
|
|
10
|
+
* All rights reserved
|
|
11
|
+
* ----------------------------------------------------------------------
|
|
12
|
+
*
|
|
13
|
+
* This program is free software: you can redistribute it and/or modify
|
|
14
|
+
* it under the terms of the GNU General Public License as published by
|
|
15
|
+
* the Free Software Foundation, either version 3 of the License, or
|
|
16
|
+
* (at your option) any later version.
|
|
17
|
+
*
|
|
18
|
+
* This program is distributed in the hope that it will be useful,
|
|
19
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
20
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
21
|
+
* GNU General Public License for more details.
|
|
22
|
+
*
|
|
23
|
+
* You should have received a copy of the GNU General Public License
|
|
24
|
+
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
const
|
|
28
|
+
_libcrash =
|
|
29
|
+
require(
|
|
30
|
+
"crash-js");
|
|
31
|
+
_cmdline_check =
|
|
32
|
+
_libcrash._cmdline_check;
|
|
33
|
+
_dirname =
|
|
34
|
+
_libcrash._dirname;
|
|
35
|
+
_error_display =
|
|
36
|
+
_libcrash._error_display;
|
|
37
|
+
_msg_info =
|
|
38
|
+
_libcrash._msg_info;
|
|
39
|
+
_msg_error =
|
|
40
|
+
_libcrash._msg_error;
|
|
41
|
+
_path_join =
|
|
42
|
+
_libcrash._path_join;
|
|
43
|
+
_sleep =
|
|
44
|
+
_libcrash._sleep;
|
|
45
|
+
const
|
|
46
|
+
{ ethers } =
|
|
47
|
+
require(
|
|
48
|
+
"ethers");
|
|
49
|
+
_ethers =
|
|
50
|
+
ethers;
|
|
51
|
+
_wei_to_ether =
|
|
52
|
+
_ethers.formatEther;
|
|
53
|
+
_parse_units =
|
|
54
|
+
_ethers.parseUnits;
|
|
55
|
+
const
|
|
56
|
+
_price_gas_transaction_get_module =
|
|
57
|
+
require(
|
|
58
|
+
'../evm-wallet/price-gas-transaction-get');
|
|
59
|
+
_price_gas_transaction_get =
|
|
60
|
+
_price_gas_transaction_get_module._price_gas_transaction_get;
|
|
61
|
+
const
|
|
62
|
+
_contract_get_module =
|
|
63
|
+
require(
|
|
64
|
+
'./contract-get');
|
|
65
|
+
_contract_get =
|
|
66
|
+
_contract_get_module._contract_get;
|
|
67
|
+
|
|
68
|
+
function
|
|
69
|
+
_global_variables() {
|
|
70
|
+
app_name =
|
|
71
|
+
"evm-contract-call-dynamic";
|
|
72
|
+
retries_max =
|
|
73
|
+
"";
|
|
74
|
+
call_timeout =
|
|
75
|
+
"";
|
|
76
|
+
wallet_seed =
|
|
77
|
+
"";
|
|
78
|
+
wallet_password =
|
|
79
|
+
"";
|
|
80
|
+
api_key_path =
|
|
81
|
+
"";
|
|
82
|
+
price_gas =
|
|
83
|
+
"";
|
|
84
|
+
msg_value =
|
|
85
|
+
"";
|
|
86
|
+
measure_unit =
|
|
87
|
+
"";
|
|
88
|
+
target_network =
|
|
89
|
+
"";
|
|
90
|
+
contract_address =
|
|
91
|
+
"";
|
|
92
|
+
contract_abi_path =
|
|
93
|
+
"";
|
|
94
|
+
contract_bytecode_path =
|
|
95
|
+
"";
|
|
96
|
+
contract_compiler_output_path =
|
|
97
|
+
"";
|
|
98
|
+
contract_method =
|
|
99
|
+
"";
|
|
100
|
+
method_args =
|
|
101
|
+
[];
|
|
102
|
+
quiet =
|
|
103
|
+
"";
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
function
|
|
107
|
+
_msg_info_wallet_selected(
|
|
108
|
+
_wallet_path) {
|
|
109
|
+
let
|
|
110
|
+
_msg,
|
|
111
|
+
_template;
|
|
112
|
+
_template =
|
|
113
|
+
"Selecting '{_wallet_path}'.";
|
|
114
|
+
_msg =
|
|
115
|
+
_template.replaceAll(
|
|
116
|
+
"{_wallet_path}",
|
|
117
|
+
_wallet_path);
|
|
118
|
+
_msg_info(
|
|
119
|
+
_msg);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
async function
|
|
123
|
+
_msg_info_contract_obtained(
|
|
124
|
+
_contract) {
|
|
125
|
+
let
|
|
126
|
+
_msg,
|
|
127
|
+
_template;
|
|
128
|
+
_template =
|
|
129
|
+
"Contract object '{_contract}' obtained.";
|
|
130
|
+
_msg =
|
|
131
|
+
_template.replaceAll(
|
|
132
|
+
"{_contract}",
|
|
133
|
+
_contract);
|
|
134
|
+
_msg_info(
|
|
135
|
+
_msg);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
function
|
|
139
|
+
_msg_info_method_obtained(
|
|
140
|
+
_method) {
|
|
141
|
+
let
|
|
142
|
+
_msg;
|
|
143
|
+
_msg =
|
|
144
|
+
"Method obtained.";
|
|
145
|
+
_msg_info(
|
|
146
|
+
_msg);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
function
|
|
150
|
+
_msg_error_transaction_undefined(
|
|
151
|
+
_attempt) {
|
|
152
|
+
let
|
|
153
|
+
_msg,
|
|
154
|
+
_template;
|
|
155
|
+
_template =
|
|
156
|
+
"Transaction undefined at attempt '{_attempt}'.";
|
|
157
|
+
_msg =
|
|
158
|
+
_template.replaceAll(
|
|
159
|
+
"{_attempt}",
|
|
160
|
+
_attempt);
|
|
161
|
+
_msg_info(
|
|
162
|
+
_msg);
|
|
163
|
+
_msg_error(
|
|
164
|
+
_msg,
|
|
165
|
+
0);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
function
|
|
169
|
+
_msg_error_transaction_failed(
|
|
170
|
+
_attempt) {
|
|
171
|
+
let
|
|
172
|
+
_msg;
|
|
173
|
+
_msg =
|
|
174
|
+
`Transaction failed at attempt '${_attempt}'.`;
|
|
175
|
+
_msg_error(
|
|
176
|
+
_msg,
|
|
177
|
+
0);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
function
|
|
181
|
+
_ethers_to_wei(
|
|
182
|
+
_amount) {
|
|
183
|
+
return _parse_units(
|
|
184
|
+
_amount,
|
|
185
|
+
"ether");
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
async function
|
|
189
|
+
_contract_call_dynamic(
|
|
190
|
+
_call_timeout,
|
|
191
|
+
_wallet_seed,
|
|
192
|
+
_wallet_password,
|
|
193
|
+
_api_key_path,
|
|
194
|
+
_price_gas,
|
|
195
|
+
_msg_value,
|
|
196
|
+
_measure_unit,
|
|
197
|
+
_target_network,
|
|
198
|
+
_contract_address,
|
|
199
|
+
_contract_abi_path,
|
|
200
|
+
_contract_bytecode_path,
|
|
201
|
+
_contract_compiler_output_path,
|
|
202
|
+
_contract_method,
|
|
203
|
+
_method_args) {
|
|
204
|
+
let
|
|
205
|
+
_amount,
|
|
206
|
+
_contract,
|
|
207
|
+
_contract_get_opts,
|
|
208
|
+
_fee_priority,
|
|
209
|
+
_gas_fee,
|
|
210
|
+
_method,
|
|
211
|
+
_msg,
|
|
212
|
+
_eip_1559,
|
|
213
|
+
_price_feasible_retries,
|
|
214
|
+
_price_feasible_retries_max,
|
|
215
|
+
_price_gas_max,
|
|
216
|
+
_price_gas_transaction_get_args,
|
|
217
|
+
_price_gas_transaction_get_retries_max,
|
|
218
|
+
_price_gas_transaction_get_selection_mode,
|
|
219
|
+
_retries_max,
|
|
220
|
+
_send_opts,
|
|
221
|
+
_receipt,
|
|
222
|
+
_tx;
|
|
223
|
+
_eip_1559 =
|
|
224
|
+
true;
|
|
225
|
+
_price_gas_max =
|
|
226
|
+
100000000;
|
|
227
|
+
_send_opts =
|
|
228
|
+
{};
|
|
229
|
+
if ( typeof(
|
|
230
|
+
_measure_unit) === "undefined" ||
|
|
231
|
+
_measure_unit == "" ) {
|
|
232
|
+
_measure_unit =
|
|
233
|
+
"wei";
|
|
234
|
+
}
|
|
235
|
+
if ( typeof(
|
|
236
|
+
_price_gas) === "undefined" ||
|
|
237
|
+
_price_gas == "" ) {
|
|
238
|
+
_price_gas =
|
|
239
|
+
0;
|
|
240
|
+
}
|
|
241
|
+
if ( _price_gas == "auto" ||
|
|
242
|
+
_price_gas == "fast" ||
|
|
243
|
+
_price_gas == "nextblock" ) {
|
|
244
|
+
_msg =
|
|
245
|
+
`Auto-detecting gas price.`;
|
|
246
|
+
_msg_info(
|
|
247
|
+
_msg);
|
|
248
|
+
_price_gas_transaction_get_selection_mode =
|
|
249
|
+
_price_gas;
|
|
250
|
+
_retries_max =
|
|
251
|
+
3;
|
|
252
|
+
_price_feasible_retries_max =
|
|
253
|
+
_retries_max;
|
|
254
|
+
_price_gas_transaction_get_retries_max =
|
|
255
|
+
_retries_max;
|
|
256
|
+
_price_gas_transaction_get_args = [
|
|
257
|
+
_target_network,
|
|
258
|
+
_price_gas_transaction_get_selection_mode,
|
|
259
|
+
_api_key_path,
|
|
260
|
+
_measure_unit,
|
|
261
|
+
"", // wallet seed
|
|
262
|
+
"", // target address,
|
|
263
|
+
"price", // output type
|
|
264
|
+
"", // output file
|
|
265
|
+
_price_gas_transaction_get_retries_max
|
|
266
|
+
];
|
|
267
|
+
_price_gas = await
|
|
268
|
+
_price_gas_transaction_get.apply(
|
|
269
|
+
null,
|
|
270
|
+
_price_gas_transaction_get_args);
|
|
271
|
+
_price_gas_transaction_get_args = [
|
|
272
|
+
_target_network,
|
|
273
|
+
_price_gas_transaction_get_selection_mode,
|
|
274
|
+
_api_key_path,
|
|
275
|
+
_measure_unit,
|
|
276
|
+
"", // wallet seed
|
|
277
|
+
"", // target address,
|
|
278
|
+
"fee", // output type
|
|
279
|
+
"", // output file
|
|
280
|
+
_price_gas_transaction_get_retries_max
|
|
281
|
+
];
|
|
282
|
+
_gas_fee = await
|
|
283
|
+
_price_gas_transaction_get.apply(
|
|
284
|
+
null,
|
|
285
|
+
_price_gas_transaction_get_args);
|
|
286
|
+
_price_gas_transaction_get_args = [
|
|
287
|
+
_target_network,
|
|
288
|
+
_price_gas_transaction_get_selection_mode,
|
|
289
|
+
_api_key_path,
|
|
290
|
+
_measure_unit,
|
|
291
|
+
"", // wallet seed
|
|
292
|
+
"", // target address,
|
|
293
|
+
"priority", // output type
|
|
294
|
+
"", // output file
|
|
295
|
+
_price_gas_transaction_get_retries_max
|
|
296
|
+
];
|
|
297
|
+
_fee_priority = await
|
|
298
|
+
_price_gas_transaction_get.apply(
|
|
299
|
+
null,
|
|
300
|
+
_price_gas_transaction_get_args);
|
|
301
|
+
_msg =
|
|
302
|
+
`Got gas price '${_price_gas}' ` +
|
|
303
|
+
`${_measure_unit} with '${_gas_fee}' ` +
|
|
304
|
+
`'${_measure_unit}' with priority fee ` +
|
|
305
|
+
`'${_fee_priority}' '${_measure_unit}' from rpc ` +
|
|
306
|
+
`'${_target_network}' using ` +
|
|
307
|
+
`selection mode ` +
|
|
308
|
+
`'${_price_gas_transaction_get_selection_mode}'.`;
|
|
309
|
+
_msg_info(
|
|
310
|
+
_msg);
|
|
311
|
+
}
|
|
312
|
+
else {
|
|
313
|
+
_msg =
|
|
314
|
+
`Setting gas price '${_price_gas}'.`;
|
|
315
|
+
_msg_info(
|
|
316
|
+
_msg);
|
|
317
|
+
}
|
|
318
|
+
_price_gas =
|
|
319
|
+
Number(
|
|
320
|
+
_price_gas);
|
|
321
|
+
if ( typeof(
|
|
322
|
+
_msg_value) === "undefined" ) {
|
|
323
|
+
_msg_value =
|
|
324
|
+
0;
|
|
325
|
+
}
|
|
326
|
+
_msg_value =
|
|
327
|
+
Number(
|
|
328
|
+
_msg_value);
|
|
329
|
+
if ( typeof(
|
|
330
|
+
_call_timeout) === "undefined" ||
|
|
331
|
+
_call_timeout == "" ) {
|
|
332
|
+
_msg_info(
|
|
333
|
+
"Setting timeout to '300' seconds.");
|
|
334
|
+
_call_timeout =
|
|
335
|
+
300000;
|
|
336
|
+
}
|
|
337
|
+
else {
|
|
338
|
+
_call_timeout =
|
|
339
|
+
Number(
|
|
340
|
+
_call_timeout);
|
|
341
|
+
}
|
|
342
|
+
_contract_get_opts = [
|
|
343
|
+
_wallet_seed,
|
|
344
|
+
_wallet_password,
|
|
345
|
+
_contract_address,
|
|
346
|
+
_contract_abi_path,
|
|
347
|
+
_contract_bytecode_path,
|
|
348
|
+
_contract_compiler_output_path,
|
|
349
|
+
_target_network,
|
|
350
|
+
_api_key_path,
|
|
351
|
+
];
|
|
352
|
+
try {
|
|
353
|
+
_contract =
|
|
354
|
+
await _contract_get.apply(
|
|
355
|
+
null,
|
|
356
|
+
_contract_get_opts);
|
|
357
|
+
await _msg_info_contract_obtained(
|
|
358
|
+
_contract);
|
|
359
|
+
_method =
|
|
360
|
+
await _contract.getFunction(
|
|
361
|
+
_contract_method);
|
|
362
|
+
_msg_info_method_obtained(
|
|
363
|
+
_method);
|
|
364
|
+
if ( _price_gas > 0 ) {
|
|
365
|
+
try {
|
|
366
|
+
_tx = await
|
|
367
|
+
_method.populateTransaction.apply(
|
|
368
|
+
null,
|
|
369
|
+
_method_args);
|
|
370
|
+
}
|
|
371
|
+
catch(
|
|
372
|
+
_error) {
|
|
373
|
+
_msg =
|
|
374
|
+
"Error populating transaction.";
|
|
375
|
+
_error_display(
|
|
376
|
+
_error);
|
|
377
|
+
_msg_error(
|
|
378
|
+
_msg,
|
|
379
|
+
0);
|
|
380
|
+
}
|
|
381
|
+
_gas_limit =
|
|
382
|
+
Math.floor(
|
|
383
|
+
15803479 * 12 / 10);
|
|
384
|
+
// 17000000;
|
|
385
|
+
// _gas_limit =
|
|
386
|
+
// _price_gas * 2;
|
|
387
|
+
_msg =
|
|
388
|
+
`Setting gas price '${_price_gas}' ` +
|
|
389
|
+
`${_measure_unit}, gas limit '${_gas_limit}' ` +
|
|
390
|
+
`'${_measure_unit}' gas fee '${_gas_fee}' ` +
|
|
391
|
+
`${_measure_unit}' and fee priority ` +
|
|
392
|
+
`'${_fee_priority}' '${_measure_unit}'.`;
|
|
393
|
+
_msg_info(
|
|
394
|
+
_msg);
|
|
395
|
+
if ( _eip_1559 == false ) {
|
|
396
|
+
_tx[
|
|
397
|
+
"gasPrice"] =
|
|
398
|
+
_price_gas;
|
|
399
|
+
}
|
|
400
|
+
else if ( _eip_1559 == true ) {
|
|
401
|
+
_price_feasible_retries =
|
|
402
|
+
0;
|
|
403
|
+
while( _price_gas_max < Number(_price_gas) &&
|
|
404
|
+
_price_feasible_retries <= _price_feasible_retries_max ) {
|
|
405
|
+
_price_feasible_retries =
|
|
406
|
+
_price_feasible_retries + 1;
|
|
407
|
+
_msg =
|
|
408
|
+
`Current gas price '${_price_gas}', ` +
|
|
409
|
+
`maximum gas price '${_price_gas_max}'. ` +
|
|
410
|
+
`Waiting 30 seconds before retrying.`;
|
|
411
|
+
_msg_info(
|
|
412
|
+
_msg);
|
|
413
|
+
await _sleep(
|
|
414
|
+
30000);
|
|
415
|
+
_price_gas_transaction_get_args = [
|
|
416
|
+
_target_network,
|
|
417
|
+
_price_gas_transaction_get_selection_mode,
|
|
418
|
+
_api_key_path,
|
|
419
|
+
_measure_unit,
|
|
420
|
+
"", // wallet seed
|
|
421
|
+
"", // target address,
|
|
422
|
+
"price", // output type
|
|
423
|
+
"", // output file
|
|
424
|
+
_price_gas_transaction_get_retries_max
|
|
425
|
+
];
|
|
426
|
+
_price_gas = await
|
|
427
|
+
_price_gas_transaction_get.apply(
|
|
428
|
+
null,
|
|
429
|
+
_price_gas_transaction_get_args);
|
|
430
|
+
// _gas_limit =
|
|
431
|
+
// Math.floor(
|
|
432
|
+
// 15803479 * 12 / 10);
|
|
433
|
+
// 17000000;
|
|
434
|
+
// 15803479 * 2;
|
|
435
|
+
// _price_gas;
|
|
436
|
+
if ( Number(_price_gas) <= _price_gas_max ) {
|
|
437
|
+
_gas_fee = await
|
|
438
|
+
_price_gas_transaction_get.apply(
|
|
439
|
+
null,
|
|
440
|
+
_price_gas_transaction_get_args);
|
|
441
|
+
_price_gas_transaction_get_args = [
|
|
442
|
+
_target_network,
|
|
443
|
+
_price_gas_transaction_get_selection_mode,
|
|
444
|
+
_api_key_path,
|
|
445
|
+
_measure_unit,
|
|
446
|
+
"", // wallet seed
|
|
447
|
+
"", // target address,
|
|
448
|
+
"priority", // output type
|
|
449
|
+
"", // output file
|
|
450
|
+
_price_gas_transaction_get_retries_max
|
|
451
|
+
];
|
|
452
|
+
_fee_priority = await
|
|
453
|
+
_price_gas_transaction_get.apply(
|
|
454
|
+
null,
|
|
455
|
+
_price_gas_transaction_get_args);
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
if ( _price_feasible_retries_max < _price_feasible_retries ) {
|
|
459
|
+
_msg =
|
|
460
|
+
`Setting price to max price ` +
|
|
461
|
+
`'${_price_gas_max}'`;
|
|
462
|
+
_msg_info(
|
|
463
|
+
_msg);
|
|
464
|
+
_price_gas =
|
|
465
|
+
_price_gas_max;
|
|
466
|
+
}
|
|
467
|
+
_price_feasible_retries =
|
|
468
|
+
_price_feasible_retries + 1;
|
|
469
|
+
_price_gas_max =
|
|
470
|
+
Math.max(
|
|
471
|
+
_price_gas_max,
|
|
472
|
+
// _gas_limit,
|
|
473
|
+
_gas_fee,
|
|
474
|
+
_fee_priority,
|
|
475
|
+
_price_gas,
|
|
476
|
+
);
|
|
477
|
+
// _tx[
|
|
478
|
+
// "gasLimit"] =
|
|
479
|
+
// _gas_limit;
|
|
480
|
+
_tx[
|
|
481
|
+
"maxFeePerGas"] =
|
|
482
|
+
_gas_fee;
|
|
483
|
+
_tx[
|
|
484
|
+
"maxPriorityFeePerGas"] =
|
|
485
|
+
_fee_priority;
|
|
486
|
+
}
|
|
487
|
+
if ( _msg_value > 0 ) {
|
|
488
|
+
if ( _measure_unit == "ether" ) {
|
|
489
|
+
_amount =
|
|
490
|
+
_ethers_to_wei(
|
|
491
|
+
_msg_value);
|
|
492
|
+
}
|
|
493
|
+
else if ( _measure_unit == "wei" ) {
|
|
494
|
+
_amount =
|
|
495
|
+
_msg_value;
|
|
496
|
+
}
|
|
497
|
+
else if ( _measure_unit == "" ) {
|
|
498
|
+
_amount =
|
|
499
|
+
_msg_value;
|
|
500
|
+
}
|
|
501
|
+
else {
|
|
502
|
+
_msg =
|
|
503
|
+
`Unknown measure unit '${_measure_unit}'.`;
|
|
504
|
+
_msg_error(
|
|
505
|
+
_msg,
|
|
506
|
+
1);
|
|
507
|
+
}
|
|
508
|
+
_tx[
|
|
509
|
+
"value"] =
|
|
510
|
+
_amount;
|
|
511
|
+
// _method_args.push(
|
|
512
|
+
// _send_opts);
|
|
513
|
+
}
|
|
514
|
+
_tx = await
|
|
515
|
+
_contract.runner.sendTransaction(
|
|
516
|
+
_tx);
|
|
517
|
+
// _tx =
|
|
518
|
+
// await _method.send.apply(
|
|
519
|
+
// null,
|
|
520
|
+
// _method_args)
|
|
521
|
+
}
|
|
522
|
+
else {
|
|
523
|
+
_msg =
|
|
524
|
+
"Setting no gas price.";
|
|
525
|
+
_msg_info(
|
|
526
|
+
_msg);
|
|
527
|
+
if ( _msg_value > 0 ) {
|
|
528
|
+
if ( _measure_unit == "ether" ) {
|
|
529
|
+
_amount =
|
|
530
|
+
_ethers_to_wei(
|
|
531
|
+
_msg_value);
|
|
532
|
+
}
|
|
533
|
+
else if ( _measure_unit == "wei" ) {
|
|
534
|
+
_amount =
|
|
535
|
+
_msg_value;
|
|
536
|
+
}
|
|
537
|
+
else if ( _measure_unit == "" ) {
|
|
538
|
+
_amount =
|
|
539
|
+
_msg_value;
|
|
540
|
+
}
|
|
541
|
+
else {
|
|
542
|
+
_msg =
|
|
543
|
+
`Unknown measure unit '${_measure_unit}'.`;
|
|
544
|
+
_msg_error(
|
|
545
|
+
_msg,
|
|
546
|
+
1);
|
|
547
|
+
}
|
|
548
|
+
_send_opts[
|
|
549
|
+
"value"] =
|
|
550
|
+
_amount;
|
|
551
|
+
_method_args.push(
|
|
552
|
+
_send_opts);
|
|
553
|
+
}
|
|
554
|
+
_tx =
|
|
555
|
+
await _method.send.apply(
|
|
556
|
+
null,
|
|
557
|
+
_method_args)
|
|
558
|
+
}
|
|
559
|
+
if ( _tx == undefined ) {
|
|
560
|
+
_msg = {
|
|
561
|
+
"code":
|
|
562
|
+
444444,
|
|
563
|
+
"message":
|
|
564
|
+
"Transaction response undefined." };
|
|
565
|
+
throw _msg;
|
|
566
|
+
}
|
|
567
|
+
if ( quiet == "n" ) {
|
|
568
|
+
console.log(
|
|
569
|
+
_tx);
|
|
570
|
+
}
|
|
571
|
+
_receipt =
|
|
572
|
+
await _tx.wait(
|
|
573
|
+
1,
|
|
574
|
+
_call_timeout);
|
|
575
|
+
} catch (
|
|
576
|
+
_error) {
|
|
577
|
+
if ( "code" in _error ) {
|
|
578
|
+
if ( _error["code"] == -32010 ) {
|
|
579
|
+
_msg_info(
|
|
580
|
+
_error[
|
|
581
|
+
"message"]);
|
|
582
|
+
}
|
|
583
|
+
else {
|
|
584
|
+
_msg =
|
|
585
|
+
"Unknown error."
|
|
586
|
+
_msg_error(
|
|
587
|
+
_msg,
|
|
588
|
+
0);
|
|
589
|
+
_error_display(
|
|
590
|
+
_error)
|
|
591
|
+
}
|
|
592
|
+
}
|
|
593
|
+
_msg_info(
|
|
594
|
+
_error[
|
|
595
|
+
"code"]);
|
|
596
|
+
_msg =
|
|
597
|
+
"Dynamic contract call crashed.";
|
|
598
|
+
_msg_info(
|
|
599
|
+
_msg);
|
|
600
|
+
throw _error;
|
|
601
|
+
};
|
|
602
|
+
return _receipt;
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
async function
|
|
606
|
+
_contract_run(
|
|
607
|
+
_retries_max,
|
|
608
|
+
_call_timeout,
|
|
609
|
+
_wallet_seed,
|
|
610
|
+
_wallet_password,
|
|
611
|
+
_api_key_path,
|
|
612
|
+
_price_gas,
|
|
613
|
+
_msg_value,
|
|
614
|
+
_measure_unit,
|
|
615
|
+
_target_network,
|
|
616
|
+
_contract_address,
|
|
617
|
+
_contract_abi_path,
|
|
618
|
+
_contract_bytecode_path,
|
|
619
|
+
_contract_compiler_output_path,
|
|
620
|
+
_contract_method,
|
|
621
|
+
_method_args,
|
|
622
|
+
_output_file) {
|
|
623
|
+
let
|
|
624
|
+
_msg,
|
|
625
|
+
_tx,
|
|
626
|
+
_contract_call_dynamic_opts,
|
|
627
|
+
_wallet_path_list,
|
|
628
|
+
_wallet_path;
|
|
629
|
+
if ( typeof(
|
|
630
|
+
_price_gas) === "undefined" ||
|
|
631
|
+
_price_gas == "" ) {
|
|
632
|
+
_msg =
|
|
633
|
+
"Setting no gas price.";
|
|
634
|
+
_msg_info(
|
|
635
|
+
_msg);
|
|
636
|
+
_price_gas =
|
|
637
|
+
"";
|
|
638
|
+
}
|
|
639
|
+
if ( typeof(
|
|
640
|
+
_retries_max) === "undefined" ||
|
|
641
|
+
_retries_max == "" ) {
|
|
642
|
+
_msg =
|
|
643
|
+
"Setting maximum call retries to '100'.";
|
|
644
|
+
_msg_info(
|
|
645
|
+
_msg);
|
|
646
|
+
_retries_max =
|
|
647
|
+
100;
|
|
648
|
+
}
|
|
649
|
+
_retries_max =
|
|
650
|
+
Number(
|
|
651
|
+
_retries_max);
|
|
652
|
+
if ( typeof(
|
|
653
|
+
_call_timeout) === "undefined" ||
|
|
654
|
+
_call_timeout == "" ) {
|
|
655
|
+
_msg =
|
|
656
|
+
"Setting timeout to '300' seconds.";
|
|
657
|
+
_msg_info(
|
|
658
|
+
_msg);
|
|
659
|
+
_call_timeout =
|
|
660
|
+
300000;
|
|
661
|
+
}
|
|
662
|
+
_call_timeout =
|
|
663
|
+
Number(
|
|
664
|
+
_call_timeout);
|
|
665
|
+
if ( typeof(
|
|
666
|
+
_msg_value) === "undefined" ||
|
|
667
|
+
_msg_value == "" ) {
|
|
668
|
+
_msg =
|
|
669
|
+
"Setting transaction value '0'.";
|
|
670
|
+
_msg_info(
|
|
671
|
+
_msg);
|
|
672
|
+
_msg_value =
|
|
673
|
+
0;
|
|
674
|
+
}
|
|
675
|
+
_msg_value =
|
|
676
|
+
Number(
|
|
677
|
+
_msg_value);
|
|
678
|
+
if ( typeof(
|
|
679
|
+
_measure_unit) === undefined ||
|
|
680
|
+
_measure_unit == "" ) {
|
|
681
|
+
_msg =
|
|
682
|
+
"Setting measure unit to 'wei'.";
|
|
683
|
+
_msg_info(
|
|
684
|
+
_msg);
|
|
685
|
+
_measure_unit =
|
|
686
|
+
"wei";
|
|
687
|
+
}
|
|
688
|
+
if ( typeof(
|
|
689
|
+
_wallet_password) === "undefined" ||
|
|
690
|
+
_wallet_password == "" ) {
|
|
691
|
+
_msg =
|
|
692
|
+
"Wallet without password.";
|
|
693
|
+
_msg_info(
|
|
694
|
+
_msg);
|
|
695
|
+
}
|
|
696
|
+
_wallet_path =
|
|
697
|
+
"";
|
|
698
|
+
if ( typeof(
|
|
699
|
+
_wallet_path) === "undefined" ||
|
|
700
|
+
_wallet_path == "" ) {
|
|
701
|
+
_wallet_path_list = [
|
|
702
|
+
_dirname(
|
|
703
|
+
_wallet_seed),
|
|
704
|
+
"wallet.dat"];
|
|
705
|
+
_wallet_path =
|
|
706
|
+
_path_join(
|
|
707
|
+
_wallet_path_list);
|
|
708
|
+
_msg_info_wallet_selected(
|
|
709
|
+
_wallet_path);
|
|
710
|
+
}
|
|
711
|
+
_contract_call_dynamic_opts = [
|
|
712
|
+
_call_timeout,
|
|
713
|
+
_wallet_seed,
|
|
714
|
+
_wallet_password,
|
|
715
|
+
_api_key_path,
|
|
716
|
+
_price_gas,
|
|
717
|
+
_msg_value,
|
|
718
|
+
_measure_unit,
|
|
719
|
+
_target_network,
|
|
720
|
+
_contract_address,
|
|
721
|
+
_contract_abi_path,
|
|
722
|
+
_contract_bytecode_path,
|
|
723
|
+
_contract_compiler_output_path,
|
|
724
|
+
_contract_method,
|
|
725
|
+
_method_args
|
|
726
|
+
];
|
|
727
|
+
_attempt =
|
|
728
|
+
1;
|
|
729
|
+
while ( _attempt <= _retries_max ) {
|
|
730
|
+
try {
|
|
731
|
+
_tx =
|
|
732
|
+
await _contract_call_dynamic.apply(
|
|
733
|
+
null,
|
|
734
|
+
_contract_call_dynamic_opts);
|
|
735
|
+
if ( _tx == undefined ) {
|
|
736
|
+
_msg_error_transaction_undefined(
|
|
737
|
+
_attempt);
|
|
738
|
+
throw "Transaction undefined."
|
|
739
|
+
}
|
|
740
|
+
else if ( _tx != undefined ) {
|
|
741
|
+
if ( quiet == "n" ) {
|
|
742
|
+
console.log(
|
|
743
|
+
_tx);
|
|
744
|
+
}
|
|
745
|
+
if ( _tx.hash != undefined ) {
|
|
746
|
+
_msg =
|
|
747
|
+
"Transaction sent.";
|
|
748
|
+
_msg_info(
|
|
749
|
+
_msg);
|
|
750
|
+
break;
|
|
751
|
+
}
|
|
752
|
+
else if ( _tx.hash == undefined ) {
|
|
753
|
+
_msg_error_transaction_failed(
|
|
754
|
+
_attempt);
|
|
755
|
+
throw "Transaction hash undefined."
|
|
756
|
+
}
|
|
757
|
+
else {
|
|
758
|
+
_msg_error_transaction_failed(
|
|
759
|
+
_attempt);
|
|
760
|
+
throw "Unknown transaction error."
|
|
761
|
+
}
|
|
762
|
+
}
|
|
763
|
+
} catch (
|
|
764
|
+
_error) {
|
|
765
|
+
_error_display(
|
|
766
|
+
_error);
|
|
767
|
+
_msg =
|
|
768
|
+
"Waiting 3 seconds before retrying.";
|
|
769
|
+
_msg_info(
|
|
770
|
+
_msg);
|
|
771
|
+
await _sleep(
|
|
772
|
+
3000);
|
|
773
|
+
_attempt =
|
|
774
|
+
_attempt + 1;
|
|
775
|
+
}
|
|
776
|
+
}
|
|
777
|
+
if ( _attempt > _retries_max ) {
|
|
778
|
+
throw "Maximum number of retries reached.";
|
|
779
|
+
}
|
|
780
|
+
return _tx;
|
|
781
|
+
}
|
|
782
|
+
|
|
783
|
+
function
|
|
784
|
+
_overrides_set() {
|
|
785
|
+
if ( retries_max == "" ) {
|
|
786
|
+
retries_max =
|
|
787
|
+
100;
|
|
788
|
+
}
|
|
789
|
+
if ( call_timeout == "" ) {
|
|
790
|
+
call_timeout =
|
|
791
|
+
300000;
|
|
792
|
+
}
|
|
793
|
+
if ( msg_value == "" ) {
|
|
794
|
+
msg_value =
|
|
795
|
+
0;
|
|
796
|
+
}
|
|
797
|
+
if ( measure_unit == "" ) {
|
|
798
|
+
measure_unit =
|
|
799
|
+
"wei";
|
|
800
|
+
}
|
|
801
|
+
}
|
|
802
|
+
|
|
803
|
+
function
|
|
804
|
+
_usage(
|
|
805
|
+
_exit_code) {
|
|
806
|
+
let
|
|
807
|
+
_text;
|
|
808
|
+
_text = [
|
|
809
|
+
"Execute a dynamic call to an EVM network's contract method.",
|
|
810
|
+
"",
|
|
811
|
+
"Usage:",
|
|
812
|
+
" evm-contract-call-dynamic",
|
|
813
|
+
" <quiet>",
|
|
814
|
+
" <retries-max>",
|
|
815
|
+
" <call-timeout>",
|
|
816
|
+
" <wallet-seed>",
|
|
817
|
+
" <wallet-password>",
|
|
818
|
+
" <api-key-path>",
|
|
819
|
+
" <price-gas>",
|
|
820
|
+
" <msg-value>",
|
|
821
|
+
" <measure-unit>",
|
|
822
|
+
" <target-network>",
|
|
823
|
+
" <contract-address>",
|
|
824
|
+
" <contract-abi_path>",
|
|
825
|
+
" <contract-bytecode_path>",
|
|
826
|
+
" <contract-compiler-output_path>",
|
|
827
|
+
" <contract-method>",
|
|
828
|
+
" [method-args]",
|
|
829
|
+
"",
|
|
830
|
+
"Args:",
|
|
831
|
+
" <quiet> Can be 'y' or 'n'",
|
|
832
|
+
" Default: y",
|
|
833
|
+
" <retries-max> Maximum number of retries before",
|
|
834
|
+
" failing.",
|
|
835
|
+
" <call-timeout> How many milliseconds to wait for a return",
|
|
836
|
+
" before declaring the call failed.",
|
|
837
|
+
" <wallet-seed> Path of the file containing",
|
|
838
|
+
" the seed phrase.",
|
|
839
|
+
" <wallet-password> Password of the wallet.",
|
|
840
|
+
" <api-key-path> Path of the API key for the",
|
|
841
|
+
" contract ABI provider service.",
|
|
842
|
+
" <target-network> Network on which the contract",
|
|
843
|
+
" resides.",
|
|
844
|
+
" <price-gas> Gas price for the transaction.",
|
|
845
|
+
" <msg-value> How much <measure-unit> attach",
|
|
846
|
+
" to the transaction.",
|
|
847
|
+
" Default: 0",
|
|
848
|
+
" <measure-unit> Measure unit for the transaction",
|
|
849
|
+
" value. It can be 'wei' or 'ether'",
|
|
850
|
+
` Default: ${measure_unit}`,
|
|
851
|
+
" <contract-address> Address of the contract.",
|
|
852
|
+
" <contract-abi_path> Contract ABI path.",
|
|
853
|
+
" <contract-bytecode-path> Path for the contract bytecode.",
|
|
854
|
+
" <contract-compiler-output-path> Path for the contract compiler",
|
|
855
|
+
" output path (the hardhat artifact).",
|
|
856
|
+
" <contract-method> Contract method to execute.",
|
|
857
|
+
" [method-args] Arguments to pass to the method.",
|
|
858
|
+
"",
|
|
859
|
+
" Options:",
|
|
860
|
+
" -h (--help) This help."
|
|
861
|
+
]
|
|
862
|
+
for ( let
|
|
863
|
+
_line =
|
|
864
|
+
0;
|
|
865
|
+
_line < _text.length;
|
|
866
|
+
_line++ ) {
|
|
867
|
+
_msg_info(
|
|
868
|
+
_msgs[
|
|
869
|
+
_line]);
|
|
870
|
+
}
|
|
871
|
+
process.exit(
|
|
872
|
+
_exit_code);
|
|
873
|
+
}
|
|
874
|
+
|
|
875
|
+
function
|
|
876
|
+
_config_show() {
|
|
877
|
+
let
|
|
878
|
+
_chars_max,
|
|
879
|
+
_line,
|
|
880
|
+
_method_args,
|
|
881
|
+
_text;
|
|
882
|
+
_chars_max =
|
|
883
|
+
300;
|
|
884
|
+
_method_args =
|
|
885
|
+
method_args.join(
|
|
886
|
+
" ");
|
|
887
|
+
if ( _chars_max < _method_args.length ) {
|
|
888
|
+
_method_args =
|
|
889
|
+
_method_args.substring(
|
|
890
|
+
0,
|
|
891
|
+
_chars_max);
|
|
892
|
+
}
|
|
893
|
+
_text = [
|
|
894
|
+
"Dynamic call configuration:",
|
|
895
|
+
` Measure unit: ${measure_unit}`,
|
|
896
|
+
` Max retries: ${retries_max}`,
|
|
897
|
+
` Network settings:`,
|
|
898
|
+
` Target network: ${target_network}`,
|
|
899
|
+
` API Key path: ${api_key_path}`,
|
|
900
|
+
` Call timeout: ${call_timeout}`,
|
|
901
|
+
` Gas price: ${price_gas}`,
|
|
902
|
+
` Credentials settings:`,
|
|
903
|
+
` Wallet seed: ${wallet_seed}`,
|
|
904
|
+
` Wallet password: ${wallet_password}`,
|
|
905
|
+
` Contract settings:`,
|
|
906
|
+
` Contract address: ${contract_address}`,
|
|
907
|
+
` Contract ABI: ${contract_abi_path}`,
|
|
908
|
+
` Contract Bytecode: ${contract_bytecode_path}`,
|
|
909
|
+
`Contract compiler output: ${contract_compiler_output_path}`,
|
|
910
|
+
` Call settings:`,
|
|
911
|
+
` Transaction value: ${msg_value}`,
|
|
912
|
+
` Contract method: ${contract_method}`,
|
|
913
|
+
` Method args: ${_method_args}`,
|
|
914
|
+
];
|
|
915
|
+
for (_line of _text) {
|
|
916
|
+
_msg_info(
|
|
917
|
+
_line);
|
|
918
|
+
}
|
|
919
|
+
}
|
|
920
|
+
|
|
921
|
+
function
|
|
922
|
+
_cmdline_parse() {
|
|
923
|
+
let
|
|
924
|
+
_msg;
|
|
925
|
+
quiet =
|
|
926
|
+
"y";
|
|
927
|
+
process.argv.forEach(
|
|
928
|
+
function (
|
|
929
|
+
_value,
|
|
930
|
+
_index,
|
|
931
|
+
_array) {
|
|
932
|
+
if ( _index == 2 ) {
|
|
933
|
+
quiet =
|
|
934
|
+
_value;
|
|
935
|
+
}
|
|
936
|
+
if ( _index == 3 ) {
|
|
937
|
+
retries_max =
|
|
938
|
+
_value;
|
|
939
|
+
}
|
|
940
|
+
if ( _index == 4 ) {
|
|
941
|
+
call_timeout =
|
|
942
|
+
_value;
|
|
943
|
+
}
|
|
944
|
+
if ( _index == 5 ) {
|
|
945
|
+
wallet_seed =
|
|
946
|
+
_value;
|
|
947
|
+
}
|
|
948
|
+
if ( _index == 6 ) {
|
|
949
|
+
wallet_password =
|
|
950
|
+
_value;
|
|
951
|
+
}
|
|
952
|
+
if ( _index == 7 ) {
|
|
953
|
+
api_key_path =
|
|
954
|
+
_value;
|
|
955
|
+
}
|
|
956
|
+
if ( _index == 8 ) {
|
|
957
|
+
price_gas =
|
|
958
|
+
_value;
|
|
959
|
+
}
|
|
960
|
+
if ( _index == 9 ) {
|
|
961
|
+
msg_value =
|
|
962
|
+
_value;
|
|
963
|
+
}
|
|
964
|
+
if ( _index == 10 ) {
|
|
965
|
+
measure_unit =
|
|
966
|
+
_value;
|
|
967
|
+
}
|
|
968
|
+
if ( _index == 11 ) {
|
|
969
|
+
target_network =
|
|
970
|
+
_value;
|
|
971
|
+
}
|
|
972
|
+
if ( _index == 12 ) {
|
|
973
|
+
contract_address =
|
|
974
|
+
_value;
|
|
975
|
+
}
|
|
976
|
+
if ( _index == 13 ) {
|
|
977
|
+
contract_abi_path =
|
|
978
|
+
_value;
|
|
979
|
+
}
|
|
980
|
+
if ( _index == 14 ) {
|
|
981
|
+
contract_bytecode_path =
|
|
982
|
+
_value;
|
|
983
|
+
}
|
|
984
|
+
if ( _index == 15 ) {
|
|
985
|
+
contract_compiler_output_path =
|
|
986
|
+
_value;
|
|
987
|
+
}
|
|
988
|
+
if ( _index == 16 ) {
|
|
989
|
+
contract_method =
|
|
990
|
+
_value;
|
|
991
|
+
}
|
|
992
|
+
if ( 16 < _index ) {
|
|
993
|
+
method_args.push(
|
|
994
|
+
_value);
|
|
995
|
+
}
|
|
996
|
+
if ( _value == "-h" ||
|
|
997
|
+
_value == "--help" ) {
|
|
998
|
+
quiet =
|
|
999
|
+
"n";
|
|
1000
|
+
_usage(
|
|
1001
|
+
0);
|
|
1002
|
+
}
|
|
1003
|
+
});
|
|
1004
|
+
if ( contract_address == "" ) {
|
|
1005
|
+
_msg =
|
|
1006
|
+
"No contract address specified.";
|
|
1007
|
+
_msg_error(
|
|
1008
|
+
_msg,
|
|
1009
|
+
0);
|
|
1010
|
+
quiet =
|
|
1011
|
+
"n";
|
|
1012
|
+
_usage(
|
|
1013
|
+
1);
|
|
1014
|
+
}
|
|
1015
|
+
}
|
|
1016
|
+
|
|
1017
|
+
if ( _cmdline_check(
|
|
1018
|
+
"evm-contract-call-dynamic") ) {
|
|
1019
|
+
_global_variables();
|
|
1020
|
+
_cmdline_parse();
|
|
1021
|
+
_config_show();
|
|
1022
|
+
_overrides_set();
|
|
1023
|
+
app_opts = [
|
|
1024
|
+
retries_max,
|
|
1025
|
+
call_timeout,
|
|
1026
|
+
wallet_seed,
|
|
1027
|
+
wallet_password,
|
|
1028
|
+
api_key_path,
|
|
1029
|
+
price_gas,
|
|
1030
|
+
msg_value,
|
|
1031
|
+
measure_unit,
|
|
1032
|
+
target_network,
|
|
1033
|
+
contract_address,
|
|
1034
|
+
contract_abi_path,
|
|
1035
|
+
contract_bytecode_path,
|
|
1036
|
+
contract_compiler_output_path,
|
|
1037
|
+
contract_method,
|
|
1038
|
+
method_args
|
|
1039
|
+
];
|
|
1040
|
+
_contract_run.apply(
|
|
1041
|
+
null,
|
|
1042
|
+
app_opts);
|
|
1043
|
+
}
|
|
1044
|
+
|
|
1045
|
+
module.exports = {
|
|
1046
|
+
_contract_call_dynamic:
|
|
1047
|
+
_contract_call_dynamic,
|
|
1048
|
+
_contract_run:
|
|
1049
|
+
_contract_run
|
|
1050
|
+
};
|