@ethereumjs/vm
Version:
An Ethereum VM implementation
75 lines • 3.29 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.createVM = createVM;
const common_1 = require("@ethereumjs/common");
const evm_1 = require("@ethereumjs/evm");
const statemanager_1 = require("@ethereumjs/statemanager");
const util_1 = require("@ethereumjs/util");
const vm_ts_1 = require("./vm.js");
/**
* VM async constructor. Creates engine instance and initializes it.
*
* @param opts VM engine constructor options
*/
async function createVM(opts = {}) {
// Save if a `StateManager` was passed (for activatePrecompiles)
const didPassStateManager = opts.stateManager !== undefined;
// Add common, SM, blockchain, EVM here
if (opts.common === undefined) {
opts.common = new common_1.Common({ chain: common_1.Mainnet });
}
if (opts.stateManager === undefined) {
opts.stateManager = new statemanager_1.MerkleStateManager({
common: opts.common,
});
}
if (opts.blockchain === undefined) {
opts.blockchain = new evm_1.EVMMockBlockchain();
}
if (opts.profilerOpts !== undefined) {
const profilerOpts = opts.profilerOpts;
if (profilerOpts.reportAfterBlock === true && profilerOpts.reportAfterTx === true) {
throw (0, util_1.EthereumJSErrorWithoutCode)('Cannot have `reportProfilerAfterBlock` and `reportProfilerAfterTx` set to `true` at the same time');
}
}
if (opts.evm !== undefined && opts.evmOpts !== undefined) {
throw (0, util_1.EthereumJSErrorWithoutCode)('the evm and evmOpts options cannot be used in conjunction');
}
if (opts.evm === undefined) {
let enableProfiler = false;
if (opts.profilerOpts?.reportAfterBlock === true || opts.profilerOpts?.reportAfterTx === true) {
enableProfiler = true;
}
const evmOpts = opts.evmOpts ?? {};
opts.evm = await (0, evm_1.createEVM)({
common: opts.common,
stateManager: opts.stateManager,
blockchain: opts.blockchain,
profiler: {
enabled: enableProfiler,
},
...evmOpts,
});
}
if (opts.activatePrecompiles === true && !didPassStateManager) {
await opts.evm.journal.checkpoint();
// put 1 wei in each of the precompiles in order to make the accounts non-empty and thus not have them deduct `callNewAccount` gas.
for (const [addressStr] of (0, evm_1.getActivePrecompiles)(opts.common)) {
const address = new util_1.Address((0, util_1.unprefixedHexToBytes)(addressStr));
let account = await opts.evm.stateManager.getAccount(address);
// Only do this if it is not overridden in genesis
// Note: in the case that custom genesis has storage fields, this is preserved
if (account === undefined) {
account = new util_1.Account();
const newAccount = (0, util_1.createAccount)({
balance: 1,
storageRoot: account.storageRoot,
});
await opts.evm.stateManager.putAccount(address, newAccount);
}
}
await opts.evm.journal.commit();
}
return new vm_ts_1.VM(opts);
}
//# sourceMappingURL=constructors.js.map