Socket
Socket
Sign inDemoInstall

@nomicfoundation/ethereumjs-evm

Package Overview
Dependencies
Maintainers
2
Versions
12
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@nomicfoundation/ethereumjs-evm - npm Package Compare versions

Comparing version 1.0.0-rc.2 to 1.0.0-rc.3

75

dist/evm.js

@@ -7,2 +7,3 @@ "use strict";

const AsyncEventEmitter = require("async-eventemitter");
const debug_1 = require("debug");
const util_1 = require("util");

@@ -16,2 +17,4 @@ const eof_1 = require("./eof");

const transientStorage_1 = require("./transientStorage");
const debug = (0, debug_1.debug)('evm');
const debugGas = (0, debug_1.debug)('evm:gas');
// very ugly way to detect if we are running in a browser

@@ -184,5 +187,11 @@ const isBrowser = new Function('try {return this===window;}catch(e){ return false;}');

exit = true;
if (this.DEBUG) {
debug(`Exit early on no code`);
}
}
if ((0, ethereumjs_util_1.isTruthy)(errorMessage)) {
exit = true;
if (this.DEBUG) {
debug(`Exit early on value transfer overflowed`);
}
}

@@ -201,2 +210,5 @@ if (exit) {

if (message.isCompiled) {
if (this.DEBUG) {
debug(`Run precompile`);
}
result = await this.runPrecompile(message.code, message.data, message.gasLimit);

@@ -206,2 +218,5 @@ result.gasRefund = message.gasRefund;

else {
if (this.DEBUG) {
debug(`Start bytecode processing...`);
}
result = await this.runInterpreter(message);

@@ -235,2 +250,5 @@ }

message.to = await this._generateAddress(message);
if (this.DEBUG) {
debug(`Generated CREATE contract address ${message.to}`);
}
let toAccount = await this.eei.getAccount(message.to);

@@ -240,2 +258,5 @@ // Check for collision

!toAccount.codeHash.equals(ethereumjs_util_1.KECCAK256_NULL)) {
if (this.DEBUG) {
debug(`Returning on address collision`);
}
return {

@@ -272,5 +293,11 @@ createdAddress: message.to,

exit = true;
if (this.DEBUG) {
debug(`Exit early on no code`);
}
}
if ((0, ethereumjs_util_1.isTruthy)(errorMessage)) {
exit = true;
if (this.DEBUG) {
debug(`Exit early on value transfer overflowed`);
}
}

@@ -288,2 +315,5 @@ if (exit) {

}
if (this.DEBUG) {
debug(`Start bytecode processing...`);
}
let result = await this.runInterpreter(message);

@@ -297,2 +327,5 @@ // fee for size of the return value

totalGas = totalGas + returnFee;
if (this.DEBUG) {
debugGas(`Add return value size fee (${returnFee} to gas used (-> ${totalGas}))`);
}
}

@@ -345,2 +378,5 @@ // Check for SpuriousDragon EIP-170 code size limit

if (this._common.gteHardfork(ethereumjs_common_1.Hardfork.Homestead)) {
if (this.DEBUG) {
debug(`Not enough gas or code size not allowed (>= Homestead)`);
}
result = { ...result, ...OOGResult(message.gasLimit) };

@@ -350,2 +386,5 @@ }

// we are in Frontier
if (this.DEBUG) {
debug(`Not enough gas or code size not allowed (Frontier)`);
}
if (totalGas - returnFee <= message.gasLimit) {

@@ -366,2 +405,5 @@ // we cannot pay the code deposit fee (but the deposit code actually did run)

await this.eei.putContractCode(message.to, result.returnValue);
if (this.DEBUG) {
debug(`Code saved on new contract creation`);
}
}

@@ -483,9 +525,27 @@ else if (CodestoreOOG) {

this._transientStorage.checkpoint();
if (this.DEBUG) {
debug('-'.repeat(100));
debug(`message checkpoint`);
}
let result;
if (this.DEBUG) {
const { caller, gasLimit, to, value, delegatecall } = message;
debug(`New message caller=${caller} gasLimit=${gasLimit} to=${to?.toString() ?? 'none'} value=${value} delegatecall=${delegatecall ? 'yes' : 'no'}`);
}
if (message.to) {
if (this.DEBUG) {
debug(`Message CALL execution (to: ${message.to})`);
}
result = await this._executeCall(message);
}
else {
if (this.DEBUG) {
debug(`Message CREATE execution (to undefined)`);
}
result = await this._executeCreate(message);
}
if (this.DEBUG) {
const { executionGasUsed, exceptionError, returnValue } = result.execResult;
debug(`Received message execResult: [ gasUsed=${executionGasUsed} exceptionError=${exceptionError ? `'${exceptionError.error}'` : 'none'} returnValue=0x${(0, ethereumjs_util_1.short)(returnValue)} gasRefund=${result.execResult.gasRefund ?? 0} ]`);
}
const err = result.execResult.exceptionError;

@@ -504,2 +564,5 @@ // This clause captures any error which happened during execution

this._transientStorage.revert();
if (this.DEBUG) {
debug(`message checkpoint reverted`);
}
}

@@ -511,2 +574,5 @@ else {

this._transientStorage.commit();
if (this.DEBUG) {
debug(`message checkpoint committed`);
}
}

@@ -517,2 +583,5 @@ }

this._transientStorage.commit();
if (this.DEBUG) {
debug(`message checkpoint committed`);
}
}

@@ -601,2 +670,5 @@ await this._emit('afterMessage', result);

const result = this.eei.putAccount(message.authcallOrigin ?? message.caller, account);
if (this.DEBUG) {
debug(`Reduced sender (${message.caller}) balance (-> ${account.balance})`);
}
return result;

@@ -612,2 +684,5 @@ }

const result = this.eei.putAccount(message.to, toAccount);
if (this.DEBUG) {
debug(`Added toAccount (${message.to}) balance (-> ${toAccount.balance})`);
}
return result;

@@ -614,0 +689,0 @@ }

6

dist/interpreter.d.ts

@@ -124,3 +124,3 @@ /// <reference types="node" />

*/
useGas(amount: bigint, _context?: string): void;
useGas(amount: bigint, context?: string): void;
/**

@@ -131,3 +131,3 @@ * Adds a positive amount to the gas counter.

*/
refundGas(amount: bigint, _context?: string): void;
refundGas(amount: bigint, context?: string): void;
/**

@@ -138,3 +138,3 @@ * Reduces amount of gas to be refunded by a positive value.

*/
subRefund(amount: bigint, _context?: string): void;
subRefund(amount: bigint, context?: string): void;
/**

@@ -141,0 +141,0 @@ * Increments the internal gasLeft counter. Used for adding callStipend.

@@ -6,2 +6,3 @@ "use strict";

const ethereumjs_util_1 = require("@nomicfoundation/ethereumjs-util");
const debug_1 = require("debug");
const eof_1 = require("./eof");

@@ -13,2 +14,3 @@ const exceptions_1 = require("./exceptions");

const stack_1 = require("./stack");
const debugGas = (0, debug_1.debug)('evm:eei:gas');
/**

@@ -200,2 +202,22 @@ * Parses and executes EVM bytecode.

};
if (this._evm.DEBUG) {
// Create opTrace for debug functionality
let hexStack = [];
hexStack = eventObj.stack.map((item) => {
return (0, ethereumjs_util_1.bigIntToHex)(BigInt(item));
});
const name = eventObj.opcode.name;
const opTrace = {
pc: eventObj.pc,
op: name,
gas: (0, ethereumjs_util_1.bigIntToHex)(eventObj.gasLeft),
gasCost: (0, ethereumjs_util_1.intToHex)(eventObj.opcode.fee),
stack: hexStack,
depth: eventObj.depth,
};
if (!(name in this.opDebuggers)) {
this.opDebuggers[name] = (0, debug_1.debug)(`evm:ops:${name}`);
}
this.opDebuggers[name](JSON.stringify(opTrace));
}
/**

@@ -257,4 +279,7 @@ * The `step` event for trace output

*/
useGas(amount, _context) {
useGas(amount, context) {
this._runState.gasLeft -= amount;
if (this._evm.DEBUG) {
debugGas(`${typeof context === 'string' ? context + ': ' : ''}used ${amount} gas (-> ${this._runState.gasLeft})`);
}
if (this._runState.gasLeft < BigInt(0)) {

@@ -270,3 +295,6 @@ this._runState.gasLeft = BigInt(0);

*/
refundGas(amount, _context) {
refundGas(amount, context) {
if (this._evm.DEBUG) {
debugGas(`${typeof context === 'string' ? context + ': ' : ''}refund ${amount} gas (-> ${this._runState.gasRefund})`);
}
this._runState.gasRefund += amount;

@@ -279,3 +307,6 @@ }

*/
subRefund(amount, _context) {
subRefund(amount, context) {
if (this._evm.DEBUG) {
debugGas(`${typeof context === 'string' ? context + ': ' : ''}sub gas refund ${amount} (-> ${this._runState.gasRefund})`);
}
this._runState.gasRefund -= amount;

@@ -292,2 +323,5 @@ if (this._runState.gasRefund < BigInt(0)) {

addStipend(amount) {
if (this._evm.DEBUG) {
debugGas(`add stipend ${amount} (-> ${this._runState.gasLeft})`);
}
this._runState.gasLeft += amount;

@@ -294,0 +328,0 @@ }

{
"name": "@nomicfoundation/ethereumjs-evm",
"version": "1.0.0-rc.2",
"version": "1.0.0-rc.3",
"description": "JavaScript Ethereum Virtual Machine (EVM) implementation",

@@ -48,4 +48,4 @@ "keywords": [

"dependencies": {
"@nomicfoundation/ethereumjs-common": "3.0.0-rc.2",
"@nomicfoundation/ethereumjs-util": "8.0.0-rc.2",
"@nomicfoundation/ethereumjs-common": "3.0.0-rc.3",
"@nomicfoundation/ethereumjs-util": "8.0.0-rc.3",
"@types/async-eventemitter": "^0.2.1",

@@ -59,3 +59,3 @@ "async-eventemitter": "^0.2.4",

"devDependencies": {
"@nomicfoundation/ethereumjs-statemanager": "1.0.0-rc.2",
"@nomicfoundation/ethereumjs-statemanager": "1.0.0-rc.3",
"@ethersproject/abi": "^5.0.12",

@@ -62,0 +62,0 @@ "@types/benchmark": "^1.0.33",

@@ -11,5 +11,7 @@ import { Chain, Common, Hardfork } from '@nomicfoundation/ethereumjs-common'

isTruthy,
short,
zeros,
} from '@nomicfoundation/ethereumjs-util'
import AsyncEventEmitter = require('async-eventemitter')
import { debug as createDebugLogger } from 'debug'
import { promisify } from 'util'

@@ -44,2 +46,5 @@

const debug = createDebugLogger('evm')
const debugGas = createDebugLogger('evm:gas')
// very ugly way to detect if we are running in a browser

@@ -368,5 +373,11 @@ const isBrowser = new Function('try {return this===window;}catch(e){ return false;}')

exit = true
if (this.DEBUG) {
debug(`Exit early on no code`)
}
}
if (isTruthy(errorMessage)) {
exit = true
if (this.DEBUG) {
debug(`Exit early on value transfer overflowed`)
}
}

@@ -386,2 +397,5 @@ if (exit) {

if (message.isCompiled) {
if (this.DEBUG) {
debug(`Run precompile`)
}
result = await this.runPrecompile(

@@ -394,2 +408,5 @@ message.code as PrecompileFunc,

} else {
if (this.DEBUG) {
debug(`Start bytecode processing...`)
}
result = await this.runInterpreter(message)

@@ -428,2 +445,5 @@ }

message.to = await this._generateAddress(message)
if (this.DEBUG) {
debug(`Generated CREATE contract address ${message.to}`)
}
let toAccount = await this.eei.getAccount(message.to)

@@ -436,2 +456,5 @@

) {
if (this.DEBUG) {
debug(`Returning on address collision`)
}
return {

@@ -473,5 +496,11 @@ createdAddress: message.to,

exit = true
if (this.DEBUG) {
debug(`Exit early on no code`)
}
}
if (isTruthy(errorMessage)) {
exit = true
if (this.DEBUG) {
debug(`Exit early on value transfer overflowed`)
}
}

@@ -490,2 +519,6 @@ if (exit) {

if (this.DEBUG) {
debug(`Start bytecode processing...`)
}
let result = await this.runInterpreter(message)

@@ -499,2 +532,5 @@ // fee for size of the return value

totalGas = totalGas + returnFee
if (this.DEBUG) {
debugGas(`Add return value size fee (${returnFee} to gas used (-> ${totalGas}))`)
}
}

@@ -551,5 +587,11 @@

if (this._common.gteHardfork(Hardfork.Homestead)) {
if (this.DEBUG) {
debug(`Not enough gas or code size not allowed (>= Homestead)`)
}
result = { ...result, ...OOGResult(message.gasLimit) }
} else {
// we are in Frontier
if (this.DEBUG) {
debug(`Not enough gas or code size not allowed (Frontier)`)
}
if (totalGas - returnFee <= message.gasLimit) {

@@ -572,2 +614,5 @@ // we cannot pay the code deposit fee (but the deposit code actually did run)

await this.eei.putContractCode(message.to, result.returnValue)
if (this.DEBUG) {
debug(`Code saved on new contract creation`)
}
} else if (CodestoreOOG) {

@@ -707,9 +752,35 @@ // This only happens at Frontier. But, let's do a sanity check;

this._transientStorage.checkpoint()
if (this.DEBUG) {
debug('-'.repeat(100))
debug(`message checkpoint`)
}
let result
if (this.DEBUG) {
const { caller, gasLimit, to, value, delegatecall } = message
debug(
`New message caller=${caller} gasLimit=${gasLimit} to=${
to?.toString() ?? 'none'
} value=${value} delegatecall=${delegatecall ? 'yes' : 'no'}`
)
}
if (message.to) {
if (this.DEBUG) {
debug(`Message CALL execution (to: ${message.to})`)
}
result = await this._executeCall(message as MessageWithTo)
} else {
if (this.DEBUG) {
debug(`Message CREATE execution (to undefined)`)
}
result = await this._executeCreate(message)
}
if (this.DEBUG) {
const { executionGasUsed, exceptionError, returnValue } = result.execResult
debug(
`Received message execResult: [ gasUsed=${executionGasUsed} exceptionError=${
exceptionError ? `'${exceptionError.error}'` : 'none'
} returnValue=0x${short(returnValue)} gasRefund=${result.execResult.gasRefund ?? 0} ]`
)
}
const err = result.execResult.exceptionError

@@ -730,2 +801,5 @@ // This clause captures any error which happened during execution

this._transientStorage.revert()
if (this.DEBUG) {
debug(`message checkpoint reverted`)
}
} else {

@@ -736,2 +810,5 @@ // we are in chainstart and the error was the code deposit error

this._transientStorage.commit()
if (this.DEBUG) {
debug(`message checkpoint committed`)
}
}

@@ -741,2 +818,5 @@ } else {

this._transientStorage.commit()
if (this.DEBUG) {
debug(`message checkpoint committed`)
}
}

@@ -839,2 +919,5 @@ await this._emit('afterMessage', result)

const result = this.eei.putAccount(message.authcallOrigin ?? message.caller, account)
if (this.DEBUG) {
debug(`Reduced sender (${message.caller}) balance (-> ${account.balance})`)
}
return result

@@ -851,2 +934,5 @@ }

const result = this.eei.putAccount(message.to, toAccount)
if (this.DEBUG) {
debug(`Added toAccount (${message.to}) balance (-> ${toAccount.balance})`)
}
return result

@@ -853,0 +939,0 @@ }

import { ConsensusAlgorithm } from '@nomicfoundation/ethereumjs-common'
import { MAX_UINT64, bufferToBigInt, isFalsy, isTruthy } from '@nomicfoundation/ethereumjs-util'
import {
MAX_UINT64,
bigIntToHex,
bufferToBigInt,
intToHex,
isFalsy,
isTruthy,
} from '@nomicfoundation/ethereumjs-util'
import { debug as createDebugLogger } from 'debug'

@@ -17,2 +25,4 @@ import { EOF } from './eof'

const debugGas = createDebugLogger('evm:eei:gas')
export interface InterpreterOpts {

@@ -310,2 +320,26 @@ pc?: number

if (this._evm.DEBUG) {
// Create opTrace for debug functionality
let hexStack = []
hexStack = eventObj.stack.map((item: any) => {
return bigIntToHex(BigInt(item))
})
const name = eventObj.opcode.name
const opTrace = {
pc: eventObj.pc,
op: name,
gas: bigIntToHex(eventObj.gasLeft),
gasCost: intToHex(eventObj.opcode.fee),
stack: hexStack,
depth: eventObj.depth,
}
if (!(name in this.opDebuggers)) {
this.opDebuggers[name] = createDebugLogger(`evm:ops:${name}`)
}
this.opDebuggers[name](JSON.stringify(opTrace))
}
/**

@@ -369,4 +403,11 @@ * The `step` event for trace output

*/
useGas(amount: bigint, _context?: string): void {
useGas(amount: bigint, context?: string): void {
this._runState.gasLeft -= amount
if (this._evm.DEBUG) {
debugGas(
`${typeof context === 'string' ? context + ': ' : ''}used ${amount} gas (-> ${
this._runState.gasLeft
})`
)
}
if (this._runState.gasLeft < BigInt(0)) {

@@ -383,3 +424,10 @@ this._runState.gasLeft = BigInt(0)

*/
refundGas(amount: bigint, _context?: string): void {
refundGas(amount: bigint, context?: string): void {
if (this._evm.DEBUG) {
debugGas(
`${typeof context === 'string' ? context + ': ' : ''}refund ${amount} gas (-> ${
this._runState.gasRefund
})`
)
}
this._runState.gasRefund += amount

@@ -393,3 +441,10 @@ }

*/
subRefund(amount: bigint, _context?: string): void {
subRefund(amount: bigint, context?: string): void {
if (this._evm.DEBUG) {
debugGas(
`${typeof context === 'string' ? context + ': ' : ''}sub gas refund ${amount} (-> ${
this._runState.gasRefund
})`
)
}
this._runState.gasRefund -= amount

@@ -407,2 +462,5 @@ if (this._runState.gasRefund < BigInt(0)) {

addStipend(amount: bigint): void {
if (this._evm.DEBUG) {
debugGas(`add stipend ${amount} (-> ${this._runState.gasLeft})`)
}
this._runState.gasLeft += amount

@@ -409,0 +467,0 @@ }

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc