-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathindex.js
136 lines (121 loc) · 2.91 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
"use-strict";
const revm = require("./index.node");
const chalk = require("chalk");
const ZERO_ADDR = "0x0000000000000000000000000000000000000000";
const SPEC_ID = [
"FRONTIER",
"FRONTIER_THAWING",
"HOMESTEAD",
"DAO_FORK",
"TANGERINE",
"SPURIOUS_DRAGON",
"BYZANTIUM",
"CONSTANTINOPLE",
"PETERSBURG",
"INSTANBUL",
"MUIR_GLACIER",
"BERLIN",
"LONDON",
"ARROW_GLACIER",
"GRAY_GLACIER",
"MERGE",
"SHANGHAI",
];
function sanitizeTxOpts(txOpts) {
if (txOpts.from == undefined) {
console.warn(
chalk.yellow("WARNING !!!: ") +
chalk.magenta("The from field was not set. Default will be address(0)")
);
txOpts.from = ZERO_ADDR;
}
if (txOpts.to == undefined || txOpts.to == "0x") {
// contract creation.
txOpts.to = "";
}
if (txOpts.txData == undefined) {
console.warn(
chalk.yellow("WARNING !!!: ") +
chalk.magenta(
"The data field was not set. Default will be empty string"
)
);
txOpts.txData = "";
}
if (txOpts.gasLimit == undefined) {
console.warn(
chalk.yellow("WARNING !!!: ") +
chalk.magenta(
"The gasLimit field was not set. Default will be 30_000_000"
)
);
txOpts.gasLimit = 30_000_000;
}
if (txOpts.gasPrice == undefined) {
console.warn(
chalk.yellow("WARNING !!!: ") +
chalk.magenta("The gasPrice field was not set. Default will be 0")
);
txOpts.gasPrice = 0;
}
}
/**
* REVM.
*
* JS Wrapper around Rust EVM implementation (REVM).
*/
class Revm {
constructor(config = {}) {
if (config.specId == undefined) {
// default config.
config.specId = "SHANGHAI";
}
config.specId = config.specId.toUpperCase();
if (!SPEC_ID.includes(config.specId)) {
throw new Error(
`Invalid EVM version. Valid versions are: ${SPEC_ID.join(", ")}`
);
}
this.config = config;
this.db = revm.new();
this.revm = revm;
}
// Updates the state. Sets 'amount = WEI'to 'address'.
setBalance(address, amount) {
this.revm.set_balance(this.db, address, amount);
}
// Returns the balance of 'address'.
getBalance(address) {
const balance = this.revm.get_balance(this.db, address);
return balance;
}
// Executes the transaction, commits it to the DB and returns the result.
callCommit(txOpts) {
sanitizeTxOpts(txOpts);
return this.revm.call_commit(
this.db,
txOpts.from,
txOpts.to,
txOpts.value,
txOpts.txData,
txOpts.gasLimit,
txOpts.gasPrice,
this.config.specId
);
}
// Executes the transaction without committing to the DB, returns result.
callNoCommit(txOpts) {
sanitizeTxOpts(txOpts);
return this.revm.call_no_commit(
this.db,
txOpts.from,
txOpts.to,
txOpts.value,
txOpts.txData,
txOpts.gasLimit,
txOpts.gasPrice,
this.config.specId
);
}
}
module.exports = Revm;