Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@ethereumjs/evm

Package Overview
Dependencies
Maintainers
4
Versions
24
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@ethereumjs/evm - npm Package Compare versions

Comparing version 3.0.0 to 3.1.0

dist/cjs/precompiles/0b-bls12-g1add.d.ts

3

dist/cjs/evm.d.ts

@@ -13,3 +13,3 @@ import { Common, Hardfork } from '@ethereumjs/common';

import type { CustomPrecompile, PrecompileFunc } from './precompiles/index.js';
import type { Block, Blockchain, CustomOpcode, EVMEvents, EVMInterface, EVMOpts, EVMResult, EVMRunCallOpts, EVMRunCodeOpts, ExecResult, bn128 } from './types.js';
import type { Block, Blockchain, CustomOpcode, EVMBLSInterface, EVMEvents, EVMInterface, EVMOpts, EVMResult, EVMRunCallOpts, EVMRunCodeOpts, ExecResult, bn128 } from './types.js';
import type { EVMStateManagerInterface } from '@ethereumjs/common';

@@ -48,2 +48,3 @@ /**

get opcodes(): OpcodeList;
protected readonly _bls?: EVMBLSInterface;
/**

@@ -50,0 +51,0 @@ * EVM is run in DEBUG mode (default: false)

@@ -19,6 +19,5 @@ "use strict";

const types_js_1 = require("./types.js");
const { debug: createDebugLogger } = debug_1.default;
const debug = createDebugLogger('evm:evm');
const debugGas = createDebugLogger('evm:gas');
const debugPrecompiles = createDebugLogger('evm:precompiles');
const debug = (0, debug_1.default)('evm:evm');
const debugGas = (0, debug_1.default)('evm:gas');
const debugPrecompiles = (0, debug_1.default)('evm:precompiles');
let initializedRustBN = undefined;

@@ -61,4 +60,5 @@ /**

const supportedEIPs = [
1153, 1559, 2315, 2565, 2718, 2929, 2930, 2935, 3074, 3198, 3529, 3540, 3541, 3607, 3651,
3670, 3855, 3860, 4399, 4895, 4788, 4844, 5133, 5656, 6780, 6800, 7516,
1153, 1559, 2537, 2565, 2718, 2929, 2930, 2935, 3074, 3198, 3529, 3540, 3541, 3607, 3651,
3670, 3855, 3860, 4399, 4895, 4788, 4844, 5133, 5656, 6110, 6780, 6800, 7002, 7251, 7516,
7685, 7702, 7709,
];

@@ -86,2 +86,6 @@ for (const eip of this.common.eips()) {

this._precompiles = (0, index_js_2.getActivePrecompiles)(this.common, this._customPrecompiles);
if (this.common.isActivatedEIP(2537)) {
this._bls = opts.bls ?? new index_js_2.NobleBLS();
this._bls.init?.();
}
this._emit = async (topic, data) => {

@@ -138,20 +142,31 @@ return new Promise((resolve) => this.events.emit(topic, data, resolve));

let gasLimit = message.gasLimit;
const fromAddress = message.authcallOrigin ?? message.caller;
if (this.common.isActivatedEIP(6800)) {
const sendsValue = message.value !== util_1.BIGINT_0;
if (message.depth === 0) {
const originAccessGas = message.accessWitness.touchTxOriginAndComputeGas(message.authcallOrigin ?? message.caller);
gasLimit -= originAccessGas;
if (gasLimit < util_1.BIGINT_0) {
if (this.DEBUG) {
debugGas(`Origin access charged(${originAccessGas}) caused OOG (-> ${gasLimit})`);
}
return { execResult: OOGResult(message.gasLimit) };
const originAccessGas = message.accessWitness.touchTxOriginAndComputeGas(fromAddress);
debugGas(`originAccessGas=${originAccessGas} waived off for origin at depth=0`);
const destAccessGas = message.accessWitness.touchTxTargetAndComputeGas(message.to, {
sendsValue,
});
debugGas(`destAccessGas=${destAccessGas} waived off for target at depth=0`);
}
let callAccessGas = message.accessWitness.touchAndChargeMessageCall(message.to);
if (sendsValue) {
callAccessGas += message.accessWitness.touchAndChargeValueTransfer(fromAddress, message.to);
}
gasLimit -= callAccessGas;
if (gasLimit < util_1.BIGINT_0) {
if (this.DEBUG) {
debugGas(`callAccessGas charged(${callAccessGas}) caused OOG (-> ${gasLimit})`);
}
else {
if (this.DEBUG) {
debugGas(`Origin access used (${originAccessGas} gas (-> ${gasLimit}))`);
}
return { execResult: OOGResult(message.gasLimit) };
}
else {
if (this.DEBUG) {
debugGas(`callAccessGas used (${callAccessGas} gas (-> ${gasLimit}))`);
}
}
}
let account = await this.stateManager.getAccount(message.authcallOrigin ?? message.caller);
let account = await this.stateManager.getAccount(fromAddress);
if (!account) {

@@ -170,22 +185,2 @@ account = new util_1.Account();

}
if (this.common.isActivatedEIP(6800)) {
if (message.depth === 0) {
const sendsValue = message.value !== util_1.BIGINT_0;
const destAccessGas = message.accessWitness.touchTxExistingAndComputeGas(message.to, {
sendsValue,
});
gasLimit -= destAccessGas;
if (gasLimit < util_1.BIGINT_0) {
if (this.DEBUG) {
debugGas(`Destination access charged(${destAccessGas}) caused OOG (-> ${gasLimit})`);
}
return { execResult: OOGResult(message.gasLimit) };
}
else {
if (this.DEBUG) {
debugGas(`Destination access used (${destAccessGas} gas (-> ${gasLimit}))`);
}
}
}
}
// Load `to` account

@@ -284,16 +279,8 @@ let toAccount = await this.stateManager.getAccount(message.to);

let gasLimit = message.gasLimit;
const fromAddress = message.authcallOrigin ?? message.caller;
if (this.common.isActivatedEIP(6800)) {
const originAccessGas = message.accessWitness.touchTxOriginAndComputeGas(message.caller);
gasLimit -= originAccessGas;
if (gasLimit < util_1.BIGINT_0) {
if (this.DEBUG) {
debugGas(`Origin access charged(${originAccessGas}) caused OOG (-> ${gasLimit})`);
}
return { execResult: OOGResult(message.gasLimit) };
if (message.depth === 0) {
const originAccessGas = message.accessWitness.touchTxOriginAndComputeGas(fromAddress);
debugGas(`originAccessGas=${originAccessGas} waived off for origin at depth=0`);
}
else {
if (this.DEBUG) {
debugGas(`Origin access used (${originAccessGas} gas (-> ${gasLimit}))`);
}
}
}

@@ -333,8 +320,7 @@ let account = await this.stateManager.getAccount(message.caller);

if (this.common.isActivatedEIP(6800)) {
const sendsValue = message.value !== util_1.BIGINT_0;
const contractCreateAccessGas = message.accessWitness.touchAndChargeContractCreateInit(message.to, { sendsValue });
const contractCreateAccessGas = message.accessWitness.touchAndChargeContractCreateInit(message.to);
gasLimit -= contractCreateAccessGas;
if (gasLimit < util_1.BIGINT_0) {
if (this.DEBUG) {
debugGas(`Contract create (sendsValue=${sendsValue}) charge(${contractCreateAccessGas}) caused OOG (-> ${gasLimit})`);
debugGas(`ContractCreateInit charge(${contractCreateAccessGas}) caused OOG (-> ${gasLimit})`);
}

@@ -345,3 +331,3 @@ return { execResult: OOGResult(message.gasLimit) };

if (this.DEBUG) {
debugGas(`Contract create (sendsValue=${sendsValue}) charged (${contractCreateAccessGas} gas (-> ${gasLimit}))`);
debugGas(`ContractCreateInit charged (${contractCreateAccessGas} gas (-> ${gasLimit}))`);
}

@@ -352,3 +338,5 @@ }

if ((toAccount.nonce && toAccount.nonce > util_1.BIGINT_0) ||
!((0, util_1.equalsBytes)(toAccount.codeHash, util_1.KECCAK256_NULL) === true)) {
!((0, util_1.equalsBytes)(toAccount.codeHash, util_1.KECCAK256_NULL) === true) ||
// See EIP 7610 and the discussion `https://ethereum-magicians.org/t/eip-7610-revert-creation-in-case-of-non-empty-storage`
!((0, util_1.equalsBytes)(toAccount.storageRoot, util_1.KECCAK256_RLP) === true)) {
if (this.DEBUG) {

@@ -404,2 +392,15 @@ debug(`Returning on address collision`);

if (exit) {
if (this.common.isActivatedEIP(6800)) {
const createCompleteAccessGas = message.accessWitness.touchAndChargeContractCreateCompleted(message.to);
gasLimit -= createCompleteAccessGas;
if (gasLimit < util_1.BIGINT_0) {
if (this.DEBUG) {
debug(`ContractCreateComplete access gas (${createCompleteAccessGas}) caused OOG (-> ${gasLimit})`);
}
return { execResult: OOGResult(message.gasLimit) };
}
else {
debug(`ContractCreateComplete access used (${createCompleteAccessGas}) gas (-> ${gasLimit})`);
}
}
return {

@@ -424,3 +425,3 @@ createdAddress: message.to,

let returnFee = util_1.BIGINT_0;
if (!result.exceptionError) {
if (!result.exceptionError && !this.common.isActivatedEIP(6800)) {
returnFee =

@@ -532,3 +533,3 @@ BigInt(result.returnValue.length) * BigInt(this.common.param('gasPrices', 'createData'));

if (this.common.isActivatedEIP(6800)) {
const byteCodeWriteAccessfee = message.accessWitness.touchCodeChunksRangeOnWriteAndChargeGas(message.to, 0, message.code.length - 1);
const byteCodeWriteAccessfee = message.accessWitness.touchCodeChunksRangeOnWriteAndChargeGas(message.to, 0, result.returnValue.length - 1);
gasLimit -= byteCodeWriteAccessfee;

@@ -542,3 +543,3 @@ if (gasLimit < util_1.BIGINT_0) {

else {
debug(`ContractCreateComplete access used (${byteCodeWriteAccessfee}) gas (-> ${gasLimit})`);
debug(`byteCodeWrite access used (${byteCodeWriteAccessfee}) gas (-> ${gasLimit})`);
result.executionGasUsed += byteCodeWriteAccessfee;

@@ -697,3 +698,3 @@ }

await this._emit('beforeMessage', message);
if (!message.to && this.common.isActivatedEIP(2929) === true) {
if (!message.to && this.common.isActivatedEIP(2929)) {
message.code = message.data;

@@ -927,2 +928,3 @@ this.journal.addWarmedAddress((await this._generateAddress(message)).bytes);

common_1.Hardfork.Prague,
common_1.Hardfork.Osaka,
];

@@ -929,0 +931,0 @@ function OOGResult(gasLimit) {

@@ -26,4 +26,2 @@ export declare enum ERROR {

AUTHCALL_UNSET = "attempting to AUTHCALL without AUTH set",
AUTHCALL_NONZERO_VALUEEXT = "attempting to execute AUTHCALL with nonzero external value",
AUTH_INVALID_S = "invalid Signature: s-values greater than secp256k1n/2 are considered invalid",
BLS_12_381_INVALID_INPUT_LENGTH = "invalid input length",

@@ -30,0 +28,0 @@ BLS_12_381_POINT_NOT_ON_CURVE = "point not on curve",

@@ -30,4 +30,2 @@ "use strict";

ERROR["AUTHCALL_UNSET"] = "attempting to AUTHCALL without AUTH set";
ERROR["AUTHCALL_NONZERO_VALUEEXT"] = "attempting to execute AUTHCALL with nonzero external value";
ERROR["AUTH_INVALID_S"] = "invalid Signature: s-values greater than secp256k1n/2 are considered invalid";
// BLS errors

@@ -34,0 +32,0 @@ ERROR["BLS_12_381_INVALID_INPUT_LENGTH"] = "invalid input length";

import { EOF } from './eof.js';
import { EVM } from './evm.js';
import { ERROR as EVMErrorMessage, EvmError } from './exceptions.js';
import { InterpreterStep } from './interpreter.js';
import { Message } from './message.js';
import { getOpcodesForHF } from './opcodes/index.js';
import { PrecompileInput, getActivePrecompiles } from './precompiles/index.js';
import { EVMInterface, EVMResult, EVMRunCallOpts, EVMRunCodeOpts, ExecResult, Log, bn128 } from './types.js';
export { bn128, EOF, EVM, EvmError, EVMErrorMessage, EVMInterface, EVMResult, EVMRunCallOpts, EVMRunCodeOpts, ExecResult, getActivePrecompiles, getOpcodesForHF, InterpreterStep, Log, Message, PrecompileInput, };
import { MCLBLS, NobleBLS, type PrecompileInput, getActivePrecompiles } from './precompiles/index.js';
import type { InterpreterStep } from './interpreter.js';
import type { EVMInterface, EVMOpts, EVMResult, EVMRunCallOpts, EVMRunCodeOpts, ExecResult, Log, bn128 } from './types.js';
export * from './logger.js';
export type { bn128, EVMInterface, EVMOpts, EVMResult, EVMRunCallOpts, EVMRunCodeOpts, ExecResult, InterpreterStep, Log, PrecompileInput, };
export { EOF, EVM, EvmError, EVMErrorMessage, getActivePrecompiles, getOpcodesForHF, MCLBLS, Message, NobleBLS, };
//# sourceMappingURL=index.d.ts.map
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Message = exports.getOpcodesForHF = exports.getActivePrecompiles = exports.EVMErrorMessage = exports.EvmError = exports.EVM = exports.EOF = void 0;
exports.NobleBLS = exports.Message = exports.MCLBLS = exports.getOpcodesForHF = exports.getActivePrecompiles = exports.EVMErrorMessage = exports.EvmError = exports.EVM = exports.EOF = void 0;
const eof_js_1 = require("./eof.js");

@@ -16,3 +30,6 @@ Object.defineProperty(exports, "EOF", { enumerable: true, get: function () { return eof_js_1.EOF; } });

const index_js_2 = require("./precompiles/index.js");
Object.defineProperty(exports, "MCLBLS", { enumerable: true, get: function () { return index_js_2.MCLBLS; } });
Object.defineProperty(exports, "NobleBLS", { enumerable: true, get: function () { return index_js_2.NobleBLS; } });
Object.defineProperty(exports, "getActivePrecompiles", { enumerable: true, get: function () { return index_js_2.getActivePrecompiles; } });
__exportStar(require("./logger.js"), exports);
//# sourceMappingURL=index.js.map

@@ -11,5 +11,4 @@ import { Account } from '@ethereumjs/util';

import type { Block, Blockchain, EVMProfilerOpts, Log } from './types.js';
import type { Common, EVMStateManagerInterface } from '@ethereumjs/common';
import type { AccessWitness } from '@ethereumjs/statemanager';
import type { Address } from '@ethereumjs/util';
import type { AccessWitnessInterface, Common, EVMStateManagerInterface } from '@ethereumjs/common';
import type { Address, PrefixedHexString } from '@ethereumjs/util';
export interface InterpreterOpts {

@@ -27,7 +26,7 @@ pc?: number;

*/
selfdestruct: Set<string>;
selfdestruct: Set<PrefixedHexString>;
/**
* A map which tracks which addresses were created (used in EIP 6780)
*/
createdAddresses?: Set<string>;
createdAddresses?: Set<PrefixedHexString>;
}

@@ -51,3 +50,3 @@ export interface Env {

createdAddresses?: Set<string>;
accessWitness?: AccessWitness;
accessWitness?: AccessWitnessInterface;
chargeCodeAccesses?: boolean;

@@ -62,3 +61,2 @@ }

stack: Stack;
returnStack: Stack;
code: Uint8Array;

@@ -89,3 +87,2 @@ shouldDoJumpAnalysis: boolean;

stack: bigint[];
returnStack: bigint[];
pc: number;

@@ -92,0 +89,0 @@ depth: number;

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

const common_1 = require("@ethereumjs/common");
const statemanager_1 = require("@ethereumjs/statemanager");
const util_1 = require("@ethereumjs/util");

@@ -15,4 +14,3 @@ const debug_1 = require("debug");

const stack_js_1 = require("./stack.js");
const { debug: createDebugLogger } = debug_1.default;
const debugGas = createDebugLogger('evm:gas');
const debugGas = (0, debug_1.default)('evm:gas');
/**

@@ -36,3 +34,2 @@ * Parses and executes EVM bytecode.

stack: new stack_js_1.Stack(),
returnStack: new stack_js_1.Stack(1023),
code: new Uint8Array(0),

@@ -138,5 +135,6 @@ validJumps: Uint8Array.from([]),

this.common.isActivatedEIP(6800) &&
this._runState.stateManager instanceof statemanager_1.StatelessVerkleStateManager) {
// is this a code loaded from state using witnesses
this._runState.env.chargeCodeAccesses === true) {
const contract = this._runState.interpreter.getAddress();
if (!this._runState.stateManager.checkChunkWitnessPresent(contract, programCounter)) {
if (!(await this._runState.stateManager.checkChunkWitnessPresent(contract, programCounter))) {
throw Error(`Invalid witness with missing codeChunk for pc=${programCounter}`);

@@ -251,3 +249,2 @@ }

stack: this._runState.stack.getStack(),
returnStack: this._runState.returnStack.getStack(),
depth: this._env.depth,

@@ -277,3 +274,3 @@ address: this._env.address,

if (!(name in this.opDebuggers)) {
this.opDebuggers[name] = createDebugLogger(`evm:ops:${name}`);
this.opDebuggers[name] = (0, debug_1.default)(`evm:ops:${name}`);
}

@@ -327,6 +324,2 @@ this.opDebuggers[name](JSON.stringify(opTrace));

}
else if (opcode === 0x5c) {
// Define a BEGINSUB as a 2 in the valid jumps array
jumps[i] = 2;
}
}

@@ -647,2 +640,3 @@ }

blobVersionedHashes: this._env.blobVersionedHashes,
accessWitness: this._env.accessWitness,
});

@@ -665,2 +659,3 @@ return this._baseCall(msg);

blobVersionedHashes: this._env.blobVersionedHashes,
accessWitness: this._env.accessWitness,
});

@@ -683,2 +678,3 @@ return this._baseCall(msg);

blobVersionedHashes: this._env.blobVersionedHashes,
accessWitness: this._env.accessWitness,
});

@@ -702,2 +698,3 @@ return this._baseCall(msg);

blobVersionedHashes: this._env.blobVersionedHashes,
accessWitness: this._env.accessWitness,
});

@@ -722,2 +719,3 @@ return this._baseCall(msg);

blobVersionedHashes: this._env.blobVersionedHashes,
accessWitness: this._env.accessWitness,
});

@@ -812,2 +810,3 @@ return this._baseCall(msg);

blobVersionedHashes: this._env.blobVersionedHashes,
accessWitness: this._env.accessWitness,
});

@@ -814,0 +813,0 @@ let createdAddresses;

import { Address } from '@ethereumjs/util';
import type { Common, EVMStateManagerInterface } from '@ethereumjs/common';
import type { Account } from '@ethereumjs/util';
import type { Account, PrefixedHexString } from '@ethereumjs/util';
declare type AddressString = string;
declare type HashString = string;
declare type SlotString = string;

@@ -18,3 +17,3 @@ export declare class Journal {

accessList?: Map<AddressString, Set<SlotString>>;
preimages?: Map<HashString, Uint8Array>;
preimages?: Map<PrefixedHexString, Uint8Array>;
constructor(stateManager: EVMStateManagerInterface, common: Common);

@@ -21,0 +20,0 @@ /**

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

const debug_1 = require("debug");
const { debug: createDebugLogger } = debug_1.default;
const utils_1 = require("ethereum-cryptography/utils");
class Journal {

@@ -15,3 +15,3 @@ constructor(stateManager, common) {

typeof window === 'undefined' ? process?.env?.DEBUG?.includes('ethjs') ?? false : false;
this._debug = createDebugLogger('statemanager:statemanager');
this._debug = (0, debug_1.default)('statemanager:statemanager');
// TODO maybe call into this.clearJournal

@@ -132,14 +132,7 @@ this.cleanJournal();

async cleanup() {
if (this.common.gteHardfork(common_1.Hardfork.SpuriousDragon) === true) {
if (this.common.gteHardfork(common_1.Hardfork.SpuriousDragon)) {
for (const addressHex of this.touched) {
const address = new util_1.Address((0, util_1.toBytes)('0x' + addressHex));
const address = new util_1.Address((0, utils_1.hexToBytes)(`0x${addressHex}`));
const account = await this.stateManager.getAccount(address);
if (account === undefined || account.isEmpty()) {
if (this.common.isActivatedEIP(2935)) {
// The history storage address is exempt of state clearing by EIP-158 if the EIP is activated
const addr = (0, util_1.bigIntToHex)(this.common.param('vm', 'historyStorageAddress')).slice(2);
if (addressHex === addr) {
continue;
}
}
await this.deleteAccount(address);

@@ -146,0 +139,0 @@ if (this.DEBUG) {

import { Address } from '@ethereumjs/util';
import type { PrecompileFunc } from './precompiles/index.js';
import type { AccessWitness } from '@ethereumjs/statemanager';
import type { AccessWitnessInterface } from '@ethereumjs/common';
import type { PrefixedHexString } from '@ethereumjs/util';
interface MessageOpts {

@@ -19,7 +20,7 @@ to?: Address;

*/
selfdestruct?: Set<string>;
selfdestruct?: Set<PrefixedHexString>;
/**
* Map of addresses which were created (used in EIP 6780)
*/
createdAddresses?: Set<string>;
createdAddresses?: Set<PrefixedHexString>;
delegatecall?: boolean;

@@ -29,3 +30,3 @@ authcallOrigin?: Address;

blobVersionedHashes?: Uint8Array[];
accessWitness?: AccessWitness;
accessWitness?: AccessWitnessInterface;
}

@@ -49,7 +50,7 @@ export declare class Message {

*/
selfdestruct?: Set<string>;
selfdestruct?: Set<PrefixedHexString>;
/**
* Map of addresses which were created (used in EIP 6780)
*/
createdAddresses?: Set<string>;
createdAddresses?: Set<PrefixedHexString>;
delegatecall: boolean;

@@ -66,3 +67,3 @@ /**

blobVersionedHashes?: Uint8Array[];
accessWitness?: AccessWitness;
accessWitness?: AccessWitnessInterface;
constructor(opts: MessageOpts);

@@ -69,0 +70,0 @@ /**

@@ -233,10 +233,2 @@ "use strict";

{
eip: 2315,
opcodes: {
0x5c: { name: 'BEGINSUB', isAsync: false, dynamicGas: false },
0x5d: { name: 'RETURNSUB', isAsync: false, dynamicGas: false },
0x5e: { name: 'JUMPSUB', isAsync: false, dynamicGas: false },
},
},
{
eip: 3198,

@@ -243,0 +235,0 @@ opcodes: {

@@ -22,3 +22,3 @@ import type { RunState } from '../interpreter.js';

*/
export declare function accessStorageEIP2929(runState: RunState, key: Uint8Array, isSstore: boolean, common: Common): bigint;
export declare function accessStorageEIP2929(runState: RunState, key: Uint8Array, isSstore: boolean, common: Common, chargeGas?: boolean): bigint;
/**

@@ -25,0 +25,0 @@ * Adjusts cost of SSTORE_RESET_GAS or SLOAD (aka sstorenoop) (EIP-2200) downward when storage

@@ -16,3 +16,3 @@ "use strict";

function accessAddressEIP2929(runState, address, common, chargeGas = true, isSelfdestructOrAuthcall = false) {
if (common.isActivatedEIP(2929) === false)
if (!common.isActivatedEIP(2929))
return util_1.BIGINT_0;

@@ -24,3 +24,4 @@ // Cold

// selfdestruct beneficiary address reads are charged an *additional* cold access
if (chargeGas) {
// if verkle not activated
if (chargeGas && !common.isActivatedEIP(6800)) {
return common.param('gasPrices', 'coldaccountaccess');

@@ -44,4 +45,4 @@ }

*/
function accessStorageEIP2929(runState, key, isSstore, common) {
if (common.isActivatedEIP(2929) === false)
function accessStorageEIP2929(runState, key, isSstore, common, chargeGas = true) {
if (!common.isActivatedEIP(2929))
return util_1.BIGINT_0;

@@ -53,5 +54,7 @@ const address = runState.interpreter.getAddress().bytes;

runState.interpreter.journal.addWarmedStorage(address, key);
return common.param('gasPrices', 'coldsload');
if (chargeGas && !common.isActivatedEIP(6800)) {
return common.param('gasPrices', 'coldsload');
}
}
else if (!isSstore) {
else if (chargeGas && (!isSstore || common.isActivatedEIP(6800))) {
return common.param('gasPrices', 'warmstorageread');

@@ -73,3 +76,3 @@ }

function adjustSstoreGasEIP2929(runState, key, defaultCost, costName, common) {
if (common.isActivatedEIP(2929) === false)
if (!common.isActivatedEIP(2929))
return defaultCost;

@@ -76,0 +79,0 @@ const address = runState.interpreter.getAddress().bytes;

@@ -8,3 +8,3 @@ "use strict";

const util_js_1 = require("./util.js");
const EIP3074MAGIC = (0, util_1.hexToBytes)('0x03');
const EIP3074MAGIC = (0, util_1.hexToBytes)('0x04');
// the opcode functions

@@ -464,4 +464,10 @@ exports.handlers = new Map([

const addressBigInt = runState.stack.pop();
const size = BigInt((await runState.stateManager.getContractCode(new util_1.Address((0, util_js_1.addresstoBytes)(addressBigInt))))
.length);
let size;
if (typeof runState.stateManager.getContractCodeSize === 'function') {
size = BigInt(await runState.stateManager.getContractCodeSize(new util_1.Address((0, util_js_1.addresstoBytes)(addressBigInt))));
}
else {
size = BigInt((await runState.stateManager.getContractCode(new util_1.Address((0, util_js_1.addresstoBytes)(addressBigInt))))
.length);
}
runState.stack.push(size);

@@ -531,3 +537,3 @@ },

const number = runState.stack.pop();
if (common.isActivatedEIP(2935)) {
if (common.isActivatedEIP(7709)) {
if (number >= runState.interpreter.getBlockNumber()) {

@@ -538,10 +544,17 @@ runState.stack.push(util_1.BIGINT_0);

const diff = runState.interpreter.getBlockNumber() - number;
const historyServeWindow = common.param('vm', 'historyServeWindow');
// block lookups must be within the `historyServeWindow`
if (diff > historyServeWindow || diff <= util_1.BIGINT_0) {
// block lookups must be within the original window even if historyStorageAddress's
// historyServeWindow is much greater than 256
if (diff > util_1.BIGINT_256 || diff <= util_1.BIGINT_0) {
runState.stack.push(util_1.BIGINT_0);
return;
}
const historyAddress = util_1.Address.fromString((0, util_1.bigIntToHex)(common.param('vm', 'historyStorageAddress')));
const historyAddress = new util_1.Address((0, util_1.bigIntToAddressBytes)(common.param('vm', 'historyStorageAddress')));
const historyServeWindow = common.param('vm', 'historyServeWindow');
const key = (0, util_1.setLengthLeft)((0, util_1.bigIntToBytes)(number % historyServeWindow), 32);
if (common.isActivatedEIP(6800)) {
const { treeIndex, subIndex } = (0, util_1.getVerkleTreeIndexesForStorageSlot)(number);
// create witnesses and charge gas
const statelessGas = runState.env.accessWitness.touchAddressOnReadAndComputeGas(historyAddress, treeIndex, subIndex);
runState.interpreter.useGas(statelessGas, `BLOCKHASH`);
}
const storage = await runState.stateManager.getContractStorage(historyAddress, key);

@@ -763,74 +776,41 @@ runState.stack.push((0, util_1.bytesToBigInt)(storage));

[0x5b, function () { }],
// 0x5c: BEGINSUB (EIP 2315) / TLOAD (EIP 1153)
// 0x5c: TLOAD (EIP 1153)
[
0x5c,
function (runState, common) {
if (common.isActivatedEIP(2315)) {
// BEGINSUB
(0, util_js_1.trap)(exceptions_js_1.ERROR.INVALID_BEGINSUB + ' at ' + (0, util_js_1.describeLocation)(runState));
}
else if (common.isActivatedEIP(1153)) {
// TLOAD
const key = runState.stack.pop();
const keyBuf = (0, util_1.setLengthLeft)((0, util_1.bigIntToBytes)(key), 32);
const value = runState.interpreter.transientStorageLoad(keyBuf);
const valueBN = value.length ? (0, util_1.bytesToBigInt)(value) : util_1.BIGINT_0;
runState.stack.push(valueBN);
}
function (runState) {
const key = runState.stack.pop();
const keyBuf = (0, util_1.setLengthLeft)((0, util_1.bigIntToBytes)(key), 32);
const value = runState.interpreter.transientStorageLoad(keyBuf);
const valueBN = value.length ? (0, util_1.bytesToBigInt)(value) : util_1.BIGINT_0;
runState.stack.push(valueBN);
},
],
// 0x5d: RETURNSUB (EIP 2315) / TSTORE (EIP 1153)
// 0x5d: TSTORE (EIP 1153)
[
0x5d,
function (runState, common) {
if (common.isActivatedEIP(2315)) {
// RETURNSUB
if (runState.returnStack.length < 1) {
(0, util_js_1.trap)(exceptions_js_1.ERROR.INVALID_RETURNSUB);
}
const dest = runState.returnStack.pop();
runState.programCounter = Number(dest);
function (runState) {
// TSTORE
if (runState.interpreter.isStatic()) {
(0, util_js_1.trap)(exceptions_js_1.ERROR.STATIC_STATE_CHANGE);
}
else if (common.isActivatedEIP(1153)) {
// TSTORE
if (runState.interpreter.isStatic()) {
(0, util_js_1.trap)(exceptions_js_1.ERROR.STATIC_STATE_CHANGE);
}
const [key, val] = runState.stack.popN(2);
const keyBuf = (0, util_1.setLengthLeft)((0, util_1.bigIntToBytes)(key), 32);
// NOTE: this should be the shortest representation
let value;
if (val === util_1.BIGINT_0) {
value = Uint8Array.from([]);
}
else {
value = (0, util_1.bigIntToBytes)(val);
}
runState.interpreter.transientStorageStore(keyBuf, value);
const [key, val] = runState.stack.popN(2);
const keyBuf = (0, util_1.setLengthLeft)((0, util_1.bigIntToBytes)(key), 32);
// NOTE: this should be the shortest representation
let value;
if (val === util_1.BIGINT_0) {
value = Uint8Array.from([]);
}
else {
value = (0, util_1.bigIntToBytes)(val);
}
runState.interpreter.transientStorageStore(keyBuf, value);
},
],
// 0x5e: JUMPSUB (2315) / MCOPY (5656)
// 0x5e: MCOPY (5656)
[
0x5e,
function (runState, common) {
if (common.isActivatedEIP(2315)) {
// JUMPSUB
const dest = runState.stack.pop();
if (dest > runState.interpreter.getCodeSize()) {
(0, util_js_1.trap)(exceptions_js_1.ERROR.INVALID_JUMPSUB + ' at ' + (0, util_js_1.describeLocation)(runState));
}
const destNum = Number(dest);
if (!(0, util_js_1.jumpSubIsValid)(runState, destNum)) {
(0, util_js_1.trap)(exceptions_js_1.ERROR.INVALID_JUMPSUB + ' at ' + (0, util_js_1.describeLocation)(runState));
}
runState.returnStack.push(BigInt(runState.programCounter));
runState.programCounter = destNum + 1;
}
else if (common.isActivatedEIP(5656)) {
// MCOPY
const [dst, src, length] = runState.stack.popN(3);
const data = runState.memory.read(Number(src), Number(length), true);
runState.memory.write(Number(dst), Number(length), data);
}
function (runState) {
const [dst, src, length] = runState.stack.popN(3);
const data = runState.memory.read(Number(src), Number(length), true);
runState.memory.write(Number(dst), Number(length), data);
},

@@ -1020,19 +1000,37 @@ ],

let [authority, memOffset, memLength] = runState.stack.popN(3);
if (memLength > util_1.BIGINT_128) {
memLength = util_1.BIGINT_128;
if (memLength > BigInt(97)) {
memLength = BigInt(97);
}
let mem = runState.memory.read(Number(memOffset), Number(memLength));
if (mem.length < 128) {
mem = (0, util_1.setLengthRight)(mem, 128);
if (mem.length < 97) {
mem = (0, util_1.setLengthRight)(mem, 97);
}
const yParity = BigInt(mem[31]);
const r = mem.subarray(32, 64);
const s = mem.subarray(64, 96);
const commit = mem.subarray(96, 128);
const yParity = BigInt(mem[0]);
const r = mem.subarray(1, 33);
const s = mem.subarray(33, 65);
const commit = mem.subarray(65, 97);
if ((0, util_1.bytesToBigInt)(s) > util_1.SECP256K1_ORDER_DIV_2) {
(0, util_js_1.trap)(exceptions_js_1.ERROR.AUTH_INVALID_S);
runState.stack.push(util_1.BIGINT_0);
runState.auth = undefined;
return;
}
const paddedInvokerAddress = (0, util_1.setLengthLeft)(runState.interpreter._env.address.bytes, 32);
if (yParity > util_1.BIGINT_1) {
runState.stack.push(util_1.BIGINT_0);
runState.auth = undefined;
return;
}
// we don't want strick check here on authority being in address range just last 20 bytes
const expectedAddress = new util_1.Address((0, util_1.bigIntToAddressBytes)(authority, false));
const account = (await runState.stateManager.getAccount(expectedAddress)) ?? new util_1.Account();
if (account.isContract()) {
// EXTCODESIZE > 0
runState.stack.push(util_1.BIGINT_0);
runState.auth = undefined;
return;
}
const accountNonce = account.nonce;
const invokedAddress = (0, util_1.setLengthLeft)(runState.interpreter._env.address.bytes, 32);
const chainId = (0, util_1.setLengthLeft)((0, util_1.bigIntToBytes)(runState.interpreter.getChainId()), 32);
const message = (0, util_1.concatBytes)(EIP3074MAGIC, chainId, paddedInvokerAddress, commit);
const nonce = (0, util_1.setLengthLeft)((0, util_1.bigIntToBytes)(accountNonce), 32);
const message = (0, util_1.concatBytes)(EIP3074MAGIC, chainId, nonce, invokedAddress, commit);
const keccakFunction = runState.interpreter._evm.common.customCrypto.keccak256 ?? keccak_js_1.keccak256;

@@ -1054,3 +1052,2 @@ const msgHash = keccakFunction(message);

runState.auth = address;
const expectedAddress = new util_1.Address((0, util_1.setLengthLeft)((0, util_1.bigIntToBytes)(authority), 20));
if (!expectedAddress.equals(address)) {

@@ -1070,3 +1067,3 @@ // expected address does not equal the recovered address, clear auth variable

async function (runState) {
const [_currentGasLimit, addr, value, _valueExt, argsOffset, argsLength, retOffset, retLength,] = runState.stack.popN(8);
const [_currentGasLimit, addr, value, argsOffset, argsLength, retOffset, retLength] = runState.stack.popN(7);
const toAddress = new util_1.Address((0, util_js_1.addresstoBytes)(addr));

@@ -1073,0 +1070,0 @@ const gasLimit = runState.messageGasLimit;

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

const common_1 = require("@ethereumjs/common");
const statemanager_1 = require("@ethereumjs/statemanager");
const util_1 = require("@ethereumjs/util");

@@ -48,6 +47,13 @@ const exceptions_js_1 = require("../exceptions.js");

async function (runState, gas, common) {
if (common.isActivatedEIP(2929) === true) {
const address = runState.stack.peek()[0];
gas += (0, EIP2929_js_1.accessAddressEIP2929)(runState, (0, util_js_1.addresstoBytes)(address), common);
const address = (0, util_js_1.addresstoBytes)(runState.stack.peek()[0]);
let charge2929Gas = true;
if (common.isActivatedEIP(6800)) {
const balanceAddress = new util_1.Address(address);
const coldAccessGas = runState.env.accessWitness.touchAddressOnReadAndComputeGas(balanceAddress, 0, util_1.VERKLE_BALANCE_LEAF_KEY);
gas += coldAccessGas;
charge2929Gas = coldAccessGas === util_1.BIGINT_0;
}
if (common.isActivatedEIP(2929)) {
gas += (0, EIP2929_js_1.accessAddressEIP2929)(runState, address, common, charge2929Gas);
}
return gas;

@@ -76,3 +82,3 @@ },

gas += common.param('gasPrices', 'copy') * (0, util_js_1.divCeil)(dataLength, util_1.BIGINT_32);
if (common.isActivatedEIP(6800)) {
if (common.isActivatedEIP(6800) && runState.env.chargeCodeAccesses === true) {
const contract = runState.interpreter.getAddress();

@@ -94,9 +100,16 @@ let codeEnd = _codeOffset + dataLength;

async function (runState, gas, common) {
if (common.isActivatedEIP(2929) === true) {
const address = runState.stack.peek()[0];
gas += (0, EIP2929_js_1.accessAddressEIP2929)(runState, (0, util_js_1.addresstoBytes)(address), common);
const addressBytes = (0, util_js_1.addresstoBytes)(runState.stack.peek()[0]);
const address = new util_1.Address(addressBytes);
let charge2929Gas = true;
if (common.isActivatedEIP(6800) &&
runState.interpreter._evm.getPrecompile(address) === undefined) {
let coldAccessGas = util_1.BIGINT_0;
coldAccessGas += runState.env.accessWitness.touchAddressOnReadAndComputeGas(address, 0, util_1.VERKLE_VERSION_LEAF_KEY);
coldAccessGas += runState.env.accessWitness.touchAddressOnReadAndComputeGas(address, 0, util_1.VERKLE_CODE_SIZE_LEAF_KEY);
gas += coldAccessGas;
// if cold access gas has been charged 2929 gas shouldn't be charged
charge2929Gas = coldAccessGas === util_1.BIGINT_0;
}
if (common.isActivatedEIP(6800) === true) {
const address = new util_1.Address((0, util_js_1.addresstoBytes)(runState.stack.peek()[0]));
gas += runState.env.accessWitness.touchAddressOnReadAndComputeGas(address, 0, statemanager_1.CODE_SIZE_LEAF_KEY);
if (common.isActivatedEIP(2929)) {
gas += (0, EIP2929_js_1.accessAddressEIP2929)(runState, addressBytes, common, charge2929Gas);
}

@@ -110,17 +123,28 @@ return gas;

async function (runState, gas, common) {
const [address, memOffset, _codeOffset, dataLength] = runState.stack.peek(4);
const [addressBigInt, memOffset, _codeOffset, dataLength] = runState.stack.peek(4);
const addressBytes = (0, util_js_1.addresstoBytes)(addressBigInt);
const address = new util_1.Address(addressBytes);
gas += (0, util_js_1.subMemUsage)(runState, memOffset, dataLength, common);
if (common.isActivatedEIP(2929) === true) {
gas += (0, EIP2929_js_1.accessAddressEIP2929)(runState, (0, util_js_1.addresstoBytes)(address), common);
let charge2929Gas = true;
if (common.isActivatedEIP(6800) &&
runState.interpreter._evm.getPrecompile(address) === undefined) {
let coldAccessGas = util_1.BIGINT_0;
coldAccessGas += runState.env.accessWitness.touchAddressOnReadAndComputeGas(address, 0, util_1.VERKLE_VERSION_LEAF_KEY);
coldAccessGas += runState.env.accessWitness.touchAddressOnReadAndComputeGas(address, 0, util_1.VERKLE_CODE_SIZE_LEAF_KEY);
gas += coldAccessGas;
// if cold access gas has been charged 2929 gas shouldn't be charged
charge2929Gas = coldAccessGas === util_1.BIGINT_0;
}
if (common.isActivatedEIP(2929)) {
gas += (0, EIP2929_js_1.accessAddressEIP2929)(runState, addressBytes, common, charge2929Gas);
}
if (dataLength !== util_1.BIGINT_0) {
gas += common.param('gasPrices', 'copy') * (0, util_js_1.divCeil)(dataLength, util_1.BIGINT_32);
if (common.isActivatedEIP(6800)) {
const contract = new util_1.Address((0, util_js_1.addresstoBytes)(address));
let codeEnd = _codeOffset + dataLength;
const codeSize = BigInt((await runState.stateManager.getContractCode(contract)).length);
const codeSize = BigInt((await runState.stateManager.getContractCode(address)).length);
if (codeEnd > codeSize) {
codeEnd = codeSize;
}
gas += runState.env.accessWitness.touchCodeChunksRangeOnReadAndChargeGas(contract, Number(_codeOffset), Number(codeEnd));
gas += runState.env.accessWitness.touchCodeChunksRangeOnReadAndChargeGas(address, Number(_codeOffset), Number(codeEnd));
}

@@ -150,6 +174,14 @@ }

async function (runState, gas, common) {
if (common.isActivatedEIP(2929) === true) {
const address = runState.stack.peek()[0];
gas += (0, EIP2929_js_1.accessAddressEIP2929)(runState, (0, util_js_1.addresstoBytes)(address), common);
const address = (0, util_js_1.addresstoBytes)(runState.stack.peek()[0]);
let charge2929Gas = true;
if (common.isActivatedEIP(6800)) {
const codeAddress = new util_1.Address(address);
let coldAccessGas = util_1.BIGINT_0;
coldAccessGas += runState.env.accessWitness.touchAddressOnReadAndComputeGas(codeAddress, 0, util_1.VERKLE_CODE_HASH_LEAF_KEY);
gas += coldAccessGas;
charge2929Gas = coldAccessGas === util_1.BIGINT_0;
}
if (common.isActivatedEIP(2929)) {
gas += (0, EIP2929_js_1.accessAddressEIP2929)(runState, address, common, charge2929Gas);
}
return gas;

@@ -191,10 +223,13 @@ },

const keyBuf = (0, util_1.setLengthLeft)((0, util_1.bigIntToBytes)(key), 32);
if (common.isActivatedEIP(2929) === true) {
gas += (0, EIP2929_js_1.accessStorageEIP2929)(runState, keyBuf, false, common);
}
if (common.isActivatedEIP(6800) === true) {
let charge2929Gas = true;
if (common.isActivatedEIP(6800)) {
const address = runState.interpreter.getAddress();
const { treeIndex, subIndex } = (0, statemanager_1.getTreeIndexesForStorageSlot)(key);
gas += runState.env.accessWitness.touchAddressOnReadAndComputeGas(address, treeIndex, subIndex);
const { treeIndex, subIndex } = (0, util_1.getVerkleTreeIndexesForStorageSlot)(key);
const coldAccessGas = runState.env.accessWitness.touchAddressOnReadAndComputeGas(address, treeIndex, subIndex);
gas += coldAccessGas;
charge2929Gas = coldAccessGas === util_1.BIGINT_0;
}
if (common.isActivatedEIP(2929)) {
gas += (0, EIP2929_js_1.accessStorageEIP2929)(runState, keyBuf, false, common, charge2929Gas);
}
return gas;

@@ -226,3 +261,5 @@ },

else if (common.gteHardfork(common_1.Hardfork.Istanbul)) {
gas += (0, EIP2200_js_1.updateSstoreGasEIP2200)(runState, currentStorage, originalStorage, (0, util_js_1.setLengthLeftStorage)(value), keyBytes, common);
if (!common.isActivatedEIP(6800)) {
gas += (0, EIP2200_js_1.updateSstoreGasEIP2200)(runState, currentStorage, originalStorage, (0, util_js_1.setLengthLeftStorage)(value), keyBytes, common);
}
}

@@ -232,13 +269,16 @@ else {

}
if (common.isActivatedEIP(2929) === true) {
let charge2929Gas = true;
if (common.isActivatedEIP(6800)) {
const contract = runState.interpreter.getAddress();
const { treeIndex, subIndex } = (0, util_1.getVerkleTreeIndexesForStorageSlot)(key);
const coldAccessGas = runState.env.accessWitness.touchAddressOnWriteAndComputeGas(contract, treeIndex, subIndex);
gas += coldAccessGas;
charge2929Gas = coldAccessGas === util_1.BIGINT_0;
}
if (common.isActivatedEIP(2929)) {
// We have to do this after the Istanbul (EIP2200) checks.
// Otherwise, we might run out of gas, due to "sentry check" of 2300 gas,
// if we deduct extra gas first.
gas += (0, EIP2929_js_1.accessStorageEIP2929)(runState, keyBytes, true, common);
gas += (0, EIP2929_js_1.accessStorageEIP2929)(runState, keyBytes, true, common, charge2929Gas);
}
if (common.isActivatedEIP(6800) === true) {
const contract = runState.interpreter.getAddress();
const { treeIndex, subIndex } = (0, statemanager_1.getTreeIndexesForStorageSlot)(key);
gas += runState.env.accessWitness.touchAddressOnWriteAndComputeGas(contract, treeIndex, subIndex);
}
return gas;

@@ -286,6 +326,6 @@ },

const [_value, offset, length] = runState.stack.peek(3);
if (common.isActivatedEIP(2929) === true) {
if (common.isActivatedEIP(2929)) {
gas += (0, EIP2929_js_1.accessAddressEIP2929)(runState, runState.interpreter.getAddress().bytes, common, false);
}
if (common.isActivatedEIP(3860) === true) {
if (common.isActivatedEIP(3860)) {
gas += ((length + util_1.BIGINT_31) / util_1.BIGINT_32) * common.param('gasPrices', 'initCodeWordCost');

@@ -311,6 +351,18 @@ }

gas += (0, util_js_1.subMemUsage)(runState, outOffset, outLength, common);
if (common.isActivatedEIP(2929) === true) {
gas += (0, EIP2929_js_1.accessAddressEIP2929)(runState, toAddress.bytes, common);
let charge2929Gas = true;
if (common.isActivatedEIP(6800) &&
runState.interpreter._evm.getPrecompile(toAddress) === undefined) {
// TODO: add check if toAddress is not a precompile
const coldAccessGas = runState.env.accessWitness.touchAndChargeMessageCall(toAddress);
if (value !== util_1.BIGINT_0) {
const contractAddress = runState.interpreter.getAddress();
gas += runState.env.accessWitness.touchAndChargeValueTransfer(contractAddress, toAddress);
}
gas += coldAccessGas;
charge2929Gas = coldAccessGas === util_1.BIGINT_0;
}
if (value !== util_1.BIGINT_0) {
if (common.isActivatedEIP(2929)) {
gas += (0, EIP2929_js_1.accessAddressEIP2929)(runState, toAddress.bytes, common, charge2929Gas);
}
if (value !== util_1.BIGINT_0 && !common.isActivatedEIP(6800)) {
gas += common.param('gasPrices', 'callValueTransfer');

@@ -335,10 +387,2 @@ }

}
if (common.isActivatedEIP(6800)) {
// TODO: add check if toAddress is not a precompile
gas += runState.env.accessWitness.touchAndChargeMessageCall(toAddress);
if (value !== util_1.BIGINT_0) {
const contractAddress = runState.interpreter.getAddress();
gas += runState.env.accessWitness.touchAndChargeValueTransfer(contractAddress, toAddress);
}
}
const gasLimit = (0, util_js_1.maxCallGas)(currentGasLimit, runState.interpreter.getGasLeft() - gas, runState, common);

@@ -362,15 +406,18 @@ // note that TangerineWhistle or later this cannot happen

const [currentGasLimit, toAddr, value, inOffset, inLength, outOffset, outLength] = runState.stack.peek(7);
const toAddress = new util_1.Address((0, util_js_1.addresstoBytes)(toAddr));
gas += (0, util_js_1.subMemUsage)(runState, inOffset, inLength, common);
gas += (0, util_js_1.subMemUsage)(runState, outOffset, outLength, common);
if (common.isActivatedEIP(2929) === true) {
gas += (0, EIP2929_js_1.accessAddressEIP2929)(runState, (0, util_js_1.addresstoBytes)(toAddr), common);
let charge2929Gas = true;
if (common.isActivatedEIP(6800) &&
runState.interpreter._evm.getPrecompile(toAddress) === undefined) {
const coldAccessGas = runState.env.accessWitness.touchAndChargeMessageCall(toAddress);
gas += coldAccessGas;
charge2929Gas = coldAccessGas === util_1.BIGINT_0;
}
if (common.isActivatedEIP(2929)) {
gas += (0, EIP2929_js_1.accessAddressEIP2929)(runState, (0, util_js_1.addresstoBytes)(toAddr), common, charge2929Gas);
}
if (value !== util_1.BIGINT_0) {
gas += common.param('gasPrices', 'callValueTransfer');
}
if (common.isActivatedEIP(6800)) {
const toAddress = new util_1.Address((0, util_js_1.addresstoBytes)(toAddr));
// TODO: add check if toAddress is not a precompile
gas += runState.env.accessWitness.touchAndChargeMessageCall(toAddress);
}
const gasLimit = (0, util_js_1.maxCallGas)(currentGasLimit, runState.interpreter.getGasLeft() - gas, runState, common);

@@ -400,12 +447,16 @@ // note that TangerineWhistle or later this cannot happen

const [currentGasLimit, toAddr, inOffset, inLength, outOffset, outLength] = runState.stack.peek(6);
const toAddress = new util_1.Address((0, util_js_1.addresstoBytes)(toAddr));
gas += (0, util_js_1.subMemUsage)(runState, inOffset, inLength, common);
gas += (0, util_js_1.subMemUsage)(runState, outOffset, outLength, common);
if (common.isActivatedEIP(2929) === true) {
gas += (0, EIP2929_js_1.accessAddressEIP2929)(runState, (0, util_js_1.addresstoBytes)(toAddr), common);
}
if (common.isActivatedEIP(6800)) {
const toAddress = new util_1.Address((0, util_js_1.addresstoBytes)(toAddr));
let charge2929Gas = true;
if (common.isActivatedEIP(6800) &&
runState.interpreter._evm.getPrecompile(toAddress) === undefined) {
// TODO: add check if toAddress is not a precompile
gas += runState.env.accessWitness.touchAndChargeMessageCall(toAddress);
const coldAccessGas = runState.env.accessWitness.touchAndChargeMessageCall(toAddress);
gas += coldAccessGas;
charge2929Gas = coldAccessGas === util_1.BIGINT_0;
}
if (common.isActivatedEIP(2929)) {
gas += (0, EIP2929_js_1.accessAddressEIP2929)(runState, (0, util_js_1.addresstoBytes)(toAddr), common, charge2929Gas);
}
const gasLimit = (0, util_js_1.maxCallGas)(currentGasLimit, runState.interpreter.getGasLeft() - gas, runState, common);

@@ -430,6 +481,6 @@ // note that TangerineWhistle or later this cannot happen

gas += (0, util_js_1.subMemUsage)(runState, offset, length, common);
if (common.isActivatedEIP(2929) === true) {
if (common.isActivatedEIP(2929)) {
gas += (0, EIP2929_js_1.accessAddressEIP2929)(runState, runState.interpreter.getAddress().bytes, common, false);
}
if (common.isActivatedEIP(3860) === true) {
if (common.isActivatedEIP(3860)) {
gas += ((length + util_1.BIGINT_31) / util_1.BIGINT_32) * common.param('gasPrices', 'initCodeWordCost');

@@ -448,3 +499,6 @@ }

async function (runState, gas, common) {
const [_address, memOffset, memLength] = runState.stack.peek(3);
const [address, memOffset, memLength] = runState.stack.peek(3);
// Note: 2929 is always active if AUTH can be reached,
// since it needs London as minimum hardfork
gas += (0, EIP2929_js_1.accessAddressEIP2929)(runState, (0, util_1.bigIntToBytes)(address), common);
gas += (0, util_js_1.subMemUsage)(runState, memOffset, memLength, common);

@@ -461,6 +515,3 @@ return gas;

}
const [currentGasLimit, addr, value, valueExt, argsOffset, argsLength, retOffset, retLength,] = runState.stack.peek(8);
if (valueExt !== util_1.BIGINT_0) {
(0, util_js_1.trap)(exceptions_js_1.ERROR.AUTHCALL_NONZERO_VALUEEXT);
}
const [currentGasLimit, addr, value, argsOffset, argsLength, retOffset, retLength] = runState.stack.peek(7);
const toAddress = new util_1.Address((0, util_js_1.addresstoBytes)(addr));

@@ -486,2 +537,13 @@ gas += common.param('gasPrices', 'warmstorageread');

runState.messageGasLimit = gasLimit;
if (value > util_1.BIGINT_0) {
const account = (await runState.stateManager.getAccount(runState.auth)) ?? new util_1.Account();
if (account.balance < value) {
(0, util_js_1.trap)(exceptions_js_1.ERROR.OUT_OF_GAS);
}
account.balance -= value;
const toAddr = new util_1.Address((0, util_js_1.addresstoBytes)(addr));
const target = (await runState.stateManager.getAccount(toAddr)) ?? new util_1.Account();
target.balance += value;
await runState.stateManager.putAccount(toAddr, target);
}
return gas;

@@ -497,10 +559,13 @@ },

gas += (0, util_js_1.subMemUsage)(runState, outOffset, outLength, common);
if (common.isActivatedEIP(2929) === true) {
gas += (0, EIP2929_js_1.accessAddressEIP2929)(runState, (0, util_js_1.addresstoBytes)(toAddr), common);
}
let charge2929Gas = true;
if (common.isActivatedEIP(6800)) {
const toAddress = new util_1.Address((0, util_js_1.addresstoBytes)(toAddr));
// TODO: add check if toAddress is not a precompile
gas += runState.env.accessWitness.touchAndChargeMessageCall(toAddress);
const coldAccessGas = runState.env.accessWitness.touchAndChargeMessageCall(toAddress);
gas += coldAccessGas;
charge2929Gas = coldAccessGas === util_1.BIGINT_0;
}
if (common.isActivatedEIP(2929)) {
gas += (0, EIP2929_js_1.accessAddressEIP2929)(runState, (0, util_js_1.addresstoBytes)(toAddr), common, charge2929Gas);
}
const gasLimit = (0, util_js_1.maxCallGas)(currentGasLimit, runState.interpreter.getGasLeft() - gas, runState, common); // we set TangerineWhistle or later to true here, as STATICCALL was available from Byzantium (which is after TangerineWhistle)

@@ -529,6 +594,7 @@ runState.messageGasLimit = gasLimit;

const selfdestructToAddress = new util_1.Address((0, util_js_1.addresstoBytes)(selfdestructToaddressBigInt));
const contractAddress = runState.interpreter.getAddress();
let deductGas = false;
const balance = await runState.interpreter.getExternalBalance(contractAddress);
if (common.gteHardfork(common_1.Hardfork.SpuriousDragon)) {
// EIP-161: State Trie Clearing
const balance = await runState.interpreter.getExternalBalance(runState.interpreter.getAddress());
if (balance > util_1.BIGINT_0) {

@@ -552,5 +618,24 @@ // This technically checks if account is empty or non-existent

}
if (common.isActivatedEIP(2929) === true) {
gas += (0, EIP2929_js_1.accessAddressEIP2929)(runState, selfdestructToAddress.bytes, common, true, true);
let selfDestructToCharge2929Gas = true;
if (common.isActivatedEIP(6800)) {
// read accesses for version and code size
if (runState.interpreter._evm.getPrecompile(contractAddress) === undefined) {
gas += runState.env.accessWitness.touchAddressOnReadAndComputeGas(contractAddress, 0, util_1.VERKLE_VERSION_LEAF_KEY);
gas += runState.env.accessWitness.touchAddressOnReadAndComputeGas(contractAddress, 0, util_1.VERKLE_CODE_SIZE_LEAF_KEY);
}
gas += runState.env.accessWitness.touchAddressOnReadAndComputeGas(contractAddress, 0, util_1.VERKLE_BALANCE_LEAF_KEY);
if (balance > util_1.BIGINT_0) {
gas += runState.env.accessWitness.touchAddressOnWriteAndComputeGas(contractAddress, 0, util_1.VERKLE_BALANCE_LEAF_KEY);
}
let selfDestructToColdAccessGas = runState.env.accessWitness.touchAddressOnReadAndComputeGas(selfdestructToAddress, 0, util_1.VERKLE_BALANCE_LEAF_KEY);
if (balance > util_1.BIGINT_0) {
selfDestructToColdAccessGas +=
runState.env.accessWitness.touchAddressOnWriteAndComputeGas(selfdestructToAddress, 0, util_1.VERKLE_BALANCE_LEAF_KEY);
}
gas += selfDestructToColdAccessGas;
selfDestructToCharge2929Gas = selfDestructToColdAccessGas === util_1.BIGINT_0;
}
if (common.isActivatedEIP(2929)) {
gas += (0, EIP2929_js_1.accessAddressEIP2929)(runState, selfdestructToAddress.bytes, common, selfDestructToCharge2929Gas, true);
}
return gas;

@@ -557,0 +642,0 @@ },

@@ -47,6 +47,2 @@ import type { RunState } from '../interpreter.js';

/**
* Checks if a jumpsub is valid given a destination (defined as a 2 in the validJumps array)
*/
export declare function jumpSubIsValid(runState: RunState, dest: number): boolean;
/**
* Returns an overflow-safe slice of an array. It right-pads

@@ -53,0 +49,0 @@ * the data with zeros to `length`.

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.exponentiation = exports.abs = exports.toTwos = exports.fromTwos = exports.mod = exports.updateSstoreGas = exports.writeCallOutput = exports.subMemUsage = exports.maxCallGas = exports.jumpSubIsValid = exports.jumpIsValid = exports.getFullname = exports.getDataSlice = exports.divCeil = exports.describeLocation = exports.addresstoBytes = exports.trap = exports.setLengthLeftStorage = void 0;
exports.exponentiation = exports.abs = exports.toTwos = exports.fromTwos = exports.mod = exports.updateSstoreGas = exports.writeCallOutput = exports.subMemUsage = exports.maxCallGas = exports.jumpIsValid = exports.getFullname = exports.getDataSlice = exports.divCeil = exports.describeLocation = exports.addresstoBytes = exports.trap = exports.setLengthLeftStorage = void 0;
const common_1 = require("@ethereumjs/common");

@@ -121,9 +121,2 @@ const util_1 = require("@ethereumjs/util");

/**
* Checks if a jumpsub is valid given a destination (defined as a 2 in the validJumps array)
*/
function jumpSubIsValid(runState, dest) {
return runState.validJumps[dest] === 2;
}
exports.jumpSubIsValid = jumpSubIsValid;
/**
* Returns an overflow-safe slice of an array. It right-pads

@@ -130,0 +123,0 @@ * the data with zeros to `length`.

import { type Address } from '@ethereumjs/util';
import { MCLBLS, NobleBLS } from './bls12_381/index.js';
import type { PrecompileFunc, PrecompileInput } from './types.js';

@@ -39,4 +40,4 @@ import type { Common } from '@ethereumjs/common';

declare function getPrecompileName(addressUnprefixedStr: string): string | undefined;
export { getActivePrecompiles, getPrecompileName, precompileEntries, precompiles, ripemdPrecompileAddress, };
export { getActivePrecompiles, getPrecompileName, MCLBLS, NobleBLS, precompileEntries, precompiles, ripemdPrecompileAddress, };
export type { AddPrecompile, CustomPrecompile, DeletePrecompile, PrecompileFunc, PrecompileInput };
//# sourceMappingURL=index.d.ts.map
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ripemdPrecompileAddress = exports.precompiles = exports.precompileEntries = exports.getPrecompileName = exports.getActivePrecompiles = void 0;
exports.ripemdPrecompileAddress = exports.precompiles = exports.precompileEntries = exports.NobleBLS = exports.MCLBLS = exports.getPrecompileName = exports.getActivePrecompiles = void 0;
const common_1 = require("@ethereumjs/common");

@@ -16,2 +16,14 @@ const util_1 = require("@ethereumjs/util");

const _0a_kzg_point_evaluation_js_1 = require("./0a-kzg-point-evaluation.js");
const _0b_bls12_g1add_js_1 = require("./0b-bls12-g1add.js");
const _0c_bls12_g1mul_js_1 = require("./0c-bls12-g1mul.js");
const _0d_bls12_g1msm_js_1 = require("./0d-bls12-g1msm.js");
const _0e_bls12_g2add_js_1 = require("./0e-bls12-g2add.js");
const _0f_bls12_g2mul_js_1 = require("./0f-bls12-g2mul.js");
const _10_bls12_g2msm_js_1 = require("./10-bls12-g2msm.js");
const _11_bls12_pairing_js_1 = require("./11-bls12-pairing.js");
const _12_bls12_map_fp_to_g1_js_1 = require("./12-bls12-map-fp-to-g1.js");
const _13_bls12_map_fp2_to_g2_js_1 = require("./13-bls12-map-fp2-to-g2.js");
const index_js_1 = require("./bls12_381/index.js");
Object.defineProperty(exports, "MCLBLS", { enumerable: true, get: function () { return index_js_1.MCLBLS; } });
Object.defineProperty(exports, "NobleBLS", { enumerable: true, get: function () { return index_js_1.NobleBLS; } });
var PrecompileAvailabilityCheck;

@@ -115,2 +127,83 @@ (function (PrecompileAvailabilityCheck) {

},
{
address: '000000000000000000000000000000000000000b',
check: {
type: PrecompileAvailabilityCheck.EIP,
param: 2537,
},
precompile: _0b_bls12_g1add_js_1.precompile0b,
name: 'BLS12_G1ADD',
},
{
address: '000000000000000000000000000000000000000c',
check: {
type: PrecompileAvailabilityCheck.EIP,
param: 2537,
},
precompile: _0c_bls12_g1mul_js_1.precompile0c,
name: 'BLS12_G1MUL',
},
{
address: '000000000000000000000000000000000000000d',
check: {
type: PrecompileAvailabilityCheck.EIP,
param: 2537,
},
precompile: _0d_bls12_g1msm_js_1.precompile0d,
name: 'BLS12_G1MSM',
},
{
address: '000000000000000000000000000000000000000e',
check: {
type: PrecompileAvailabilityCheck.EIP,
param: 2537,
},
precompile: _0e_bls12_g2add_js_1.precompile0e,
name: 'BLS12_G2ADD',
},
{
address: '000000000000000000000000000000000000000f',
check: {
type: PrecompileAvailabilityCheck.EIP,
param: 2537,
},
precompile: _0f_bls12_g2mul_js_1.precompile0f,
name: 'BLS12_G2MUL',
},
{
address: '0000000000000000000000000000000000000010',
check: {
type: PrecompileAvailabilityCheck.EIP,
param: 2537,
},
precompile: _10_bls12_g2msm_js_1.precompile10,
name: 'BLS12_G2MSM',
},
{
address: '0000000000000000000000000000000000000011',
check: {
type: PrecompileAvailabilityCheck.EIP,
param: 2537,
},
precompile: _11_bls12_pairing_js_1.precompile11,
name: 'BLS12_PAIRING',
},
{
address: '0000000000000000000000000000000000000012',
check: {
type: PrecompileAvailabilityCheck.EIP,
param: 2537,
},
precompile: _12_bls12_map_fp_to_g1_js_1.precompile12,
name: 'BLS12_MAP_FP_TO_G1',
},
{
address: '0000000000000000000000000000000000000013',
check: {
type: PrecompileAvailabilityCheck.EIP,
param: 2537,
},
precompile: _13_bls12_map_fp2_to_g2_js_1.precompile13,
name: 'BLS12_MAP_FP2_TO_G2',
},
];

@@ -129,2 +222,11 @@ exports.precompileEntries = precompileEntries;

'000000000000000000000000000000000000000a': _0a_kzg_point_evaluation_js_1.precompile0a,
'000000000000000000000000000000000000000b': _0b_bls12_g1add_js_1.precompile0b,
'000000000000000000000000000000000000000c': _0c_bls12_g1mul_js_1.precompile0c,
'000000000000000000000000000000000000000d': _0d_bls12_g1msm_js_1.precompile0d,
'000000000000000000000000000000000000000e': _0e_bls12_g2add_js_1.precompile0e,
'000000000000000000000000000000000000000f': _0f_bls12_g2mul_js_1.precompile0f,
'0000000000000000000000000000000000000010': _10_bls12_g2msm_js_1.precompile10,
'0000000000000000000000000000000000000011': _11_bls12_pairing_js_1.precompile11,
'0000000000000000000000000000000000000012': _12_bls12_map_fp_to_g1_js_1.precompile12,
'0000000000000000000000000000000000000013': _13_bls12_map_fp2_to_g2_js_1.precompile13,
};

@@ -131,0 +233,0 @@ exports.precompiles = precompiles;

@@ -8,5 +8,4 @@ import type { EvmError } from './exceptions.js';

import type { PrecompileFunc } from './precompiles/types.js';
import type { Common, EVMStateManagerInterface } from '@ethereumjs/common';
import type { AccessWitness } from '@ethereumjs/statemanager';
import type { Account, Address, AsyncEventEmitter } from '@ethereumjs/util';
import type { AccessWitnessInterface, Common, EVMStateManagerInterface } from '@ethereumjs/common';
import type { Account, Address, AsyncEventEmitter, PrefixedHexString } from '@ethereumjs/util';
export declare type DeleteOpcode = {

@@ -70,3 +69,3 @@ opcode: number;

*/
selfdestruct?: Set<string>;
selfdestruct?: Set<PrefixedHexString>;
/**

@@ -99,3 +98,3 @@ * The address of the account that is executing this code (`address(this)`). Defaults to the zero address.

*/
createdAddresses?: Set<string>;
createdAddresses?: Set<PrefixedHexString>;
/**

@@ -118,3 +117,3 @@ * Skip balance checks if true. If caller balance is less than message value,

message?: Message;
accessWitness?: AccessWitness;
accessWitness?: AccessWitnessInterface;
}

@@ -141,3 +140,3 @@ interface NewContractEvent {

accessList?: Map<string, Set<string>>;
preimages?: Map<string, Uint8Array>;
preimages?: Map<PrefixedHexString, Uint8Array>;
addAlwaysWarmAddress(address: string, addToAccessList?: boolean): void;

@@ -168,7 +167,6 @@ addAlwaysWarmSlot(address: string, slot: string, addToAccessList?: boolean): void;

* - [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559) - Fee market change for ETH 1.0 chain
* - [EIP-2315](https://eips.ethereum.org/EIPS/eip-2315) - Simple subroutines for the EVM (`outdated`)
* - [EIP-2537](https://eips.ethereum.org/EIPS/eip-2537) - BLS precompiles (removed in v4.0.0, see latest v3 release)
* - [EIP-2565](https://eips.ethereum.org/EIPS/eip-2565) - ModExp gas cost
* - [EIP-2718](https://eips.ethereum.org/EIPS/eip-2565) - Transaction Types
* - [EIP-2935](https://eips.ethereum.org/EIPS/eip-2935) - Save historical block hashes in state (`experimental`)
* - [EIP-2935](https://eips.ethereum.org/EIPS/eip-2935) - Serve historical block hashes from state (Prague)
* - [EIP-2929](https://eips.ethereum.org/EIPS/eip-2929) - gas cost increases for state access opcodes

@@ -192,7 +190,13 @@ * - [EIP-2930](https://eips.ethereum.org/EIPS/eip-2930) - Optional access list tx type

* - [EIP-4844](https://eips.ethereum.org/EIPS/eip-4844) - Shard Blob Transactions (Cancun)
* - [EIP-7702](https://eips.ethereum.org/EIPS/eip-7702) - EOA code transactions (Prague) (`outdated`)
* - [EIP-7709](https://eips.ethereum.org/EIPS/eip-7709) - Read BLOCKHASH from storage and update cost (Osaka)
* - [EIP-4895](https://eips.ethereum.org/EIPS/eip-4895) - Beacon chain push withdrawals as operations (Shanghai)
* - [EIP-5133](https://eips.ethereum.org/EIPS/eip-5133) - Delaying Difficulty Bomb to mid-September 2022 (Gray Glacier)
* - [EIP-5656](https://eips.ethereum.org/EIPS/eip-5656) - MCOPY - Memory copying instruction (Cancun)
* - [EIP-6110](https://eips.ethereum.org/EIPS/eip-6110) - Supply validator deposits on chain (Prague)
* - [EIP-6780](https://eips.ethereum.org/EIPS/eip-6780) - SELFDESTRUCT only in same transaction (Cancun)
* - [EIP-7002](https://eips.ethereum.org/EIPS/eip-7002) - Execution layer triggerable withdrawals (Prague)
* - [EIP-7251](https://eips.ethereum.org/EIPS/eip-7251) - Execution layer triggerable validator consolidations (Prague)
* - [EIP-7516](https://eips.ethereum.org/EIPS/eip-7516) - BLOBBASEFEE opcode (Cancun)
* - [EIP-7685](https://eips.ethereum.org/EIPS/eip-7685) - General purpose execution layer requests (Prague)
*

@@ -238,2 +242,23 @@ * *Annotations:*

customPrecompiles?: CustomPrecompile[];
/**
* For the EIP-2537 BLS Precompiles, the native JS `@noble/curves`
* https://github.com/paulmillr/noble-curves BLS12-381 curve implementation
* is used (see `noble.ts` file in the `precompiles` folder).
*
* To use an alternative implementation this option can be used by passing
* in a wrapper implementation integrating the desired library and adhering
* to the `EVMBLSInterface` specification.
*
* An interface for the MCL WASM implementation https://github.com/herumi/mcl-wasm
* is shipped with this library which can be used as follows (with `mcl-wasm` being
* explicitly added to the set of dependencies):
*
* ```ts
* import * as mcl from 'mcl-wasm'
*
* await mcl.init(mcl.BLS12_381)
* const evm = await EVM.create({ bls: new MCLBLS(mcl) })
* ```
*/
bls?: EVMBLSInterface;
stateManager?: EVMStateManagerInterface;

@@ -290,7 +315,7 @@ /**

*/
selfdestruct?: Set<string>;
selfdestruct?: Set<PrefixedHexString>;
/**
* Map of addresses which were created (used in EIP 6780)
*/
createdAddresses?: Set<string>;
createdAddresses?: Set<PrefixedHexString>;
/**

@@ -305,2 +330,14 @@ * The gas refund counter

}
export declare type EVMBLSInterface = {
init?(): void;
addG1(input: Uint8Array): Uint8Array;
mulG1(input: Uint8Array): Uint8Array;
addG2(input: Uint8Array): Uint8Array;
mulG2(input: Uint8Array): Uint8Array;
mapFPtoG1(input: Uint8Array): Uint8Array;
mapFP2toG2(input: Uint8Array): Uint8Array;
msmG1(input: Uint8Array): Uint8Array;
msmG2(input: Uint8Array): Uint8Array;
pairingCheck(input: Uint8Array): Uint8Array;
};
/**

@@ -353,7 +390,7 @@ * Log that the contract emits.

export interface bn128 {
ec_pairing: (input_str: string) => string;
ec_add: (input_str: string) => string;
ec_mul: (input_hex: string) => string;
ec_pairing: (input_str: string) => PrefixedHexString;
ec_add: (input_str: string) => PrefixedHexString;
ec_mul: (input_hex: string) => PrefixedHexString;
}
export {};
//# sourceMappingURL=types.d.ts.map

@@ -13,3 +13,3 @@ import { Common, Hardfork } from '@ethereumjs/common';

import type { CustomPrecompile, PrecompileFunc } from './precompiles/index.js';
import type { Block, Blockchain, CustomOpcode, EVMEvents, EVMInterface, EVMOpts, EVMResult, EVMRunCallOpts, EVMRunCodeOpts, ExecResult, bn128 } from './types.js';
import type { Block, Blockchain, CustomOpcode, EVMBLSInterface, EVMEvents, EVMInterface, EVMOpts, EVMResult, EVMRunCallOpts, EVMRunCodeOpts, ExecResult, bn128 } from './types.js';
import type { EVMStateManagerInterface } from '@ethereumjs/common';

@@ -48,2 +48,3 @@ /**

get opcodes(): OpcodeList;
protected readonly _bls?: EVMBLSInterface;
/**

@@ -50,0 +51,0 @@ * EVM is run in DEBUG mode (default: false)

import { Chain, Common, Hardfork } from '@ethereumjs/common';
import { DefaultStateManager } from '@ethereumjs/statemanager';
import { Account, Address, AsyncEventEmitter, BIGINT_0, BIGINT_1, KECCAK256_NULL, MAX_INTEGER, bigIntToBytes, bytesToUnprefixedHex, equalsBytes, generateAddress, generateAddress2, short, zeros, } from '@ethereumjs/util';
import { Account, Address, AsyncEventEmitter, BIGINT_0, BIGINT_1, KECCAK256_NULL, KECCAK256_RLP, MAX_INTEGER, bigIntToBytes, bytesToUnprefixedHex, equalsBytes, generateAddress, generateAddress2, short, zeros, } from '@ethereumjs/util';
import debugDefault from 'debug';

@@ -13,9 +13,8 @@ import { initRustBN } from 'rustbn-wasm';

import { getOpcodesForHF } from './opcodes/index.js';
import { getActivePrecompiles, getPrecompileName } from './precompiles/index.js';
import { NobleBLS, getActivePrecompiles, getPrecompileName } from './precompiles/index.js';
import { TransientStorage } from './transientStorage.js';
import { DefaultBlockchain } from './types.js';
const { debug: createDebugLogger } = debugDefault;
const debug = createDebugLogger('evm:evm');
const debugGas = createDebugLogger('evm:gas');
const debugPrecompiles = createDebugLogger('evm:precompiles');
const debug = debugDefault('evm:evm');
const debugGas = debugDefault('evm:gas');
const debugPrecompiles = debugDefault('evm:precompiles');
let initializedRustBN = undefined;

@@ -58,4 +57,5 @@ /**

const supportedEIPs = [
1153, 1559, 2315, 2565, 2718, 2929, 2930, 2935, 3074, 3198, 3529, 3540, 3541, 3607, 3651,
3670, 3855, 3860, 4399, 4895, 4788, 4844, 5133, 5656, 6780, 6800, 7516,
1153, 1559, 2537, 2565, 2718, 2929, 2930, 2935, 3074, 3198, 3529, 3540, 3541, 3607, 3651,
3670, 3855, 3860, 4399, 4895, 4788, 4844, 5133, 5656, 6110, 6780, 6800, 7002, 7251, 7516,
7685, 7702, 7709,
];

@@ -83,2 +83,6 @@ for (const eip of this.common.eips()) {

this._precompiles = getActivePrecompiles(this.common, this._customPrecompiles);
if (this.common.isActivatedEIP(2537)) {
this._bls = opts.bls ?? new NobleBLS();
this._bls.init?.();
}
this._emit = async (topic, data) => {

@@ -135,20 +139,31 @@ return new Promise((resolve) => this.events.emit(topic, data, resolve));

let gasLimit = message.gasLimit;
const fromAddress = message.authcallOrigin ?? message.caller;
if (this.common.isActivatedEIP(6800)) {
const sendsValue = message.value !== BIGINT_0;
if (message.depth === 0) {
const originAccessGas = message.accessWitness.touchTxOriginAndComputeGas(message.authcallOrigin ?? message.caller);
gasLimit -= originAccessGas;
if (gasLimit < BIGINT_0) {
if (this.DEBUG) {
debugGas(`Origin access charged(${originAccessGas}) caused OOG (-> ${gasLimit})`);
}
return { execResult: OOGResult(message.gasLimit) };
const originAccessGas = message.accessWitness.touchTxOriginAndComputeGas(fromAddress);
debugGas(`originAccessGas=${originAccessGas} waived off for origin at depth=0`);
const destAccessGas = message.accessWitness.touchTxTargetAndComputeGas(message.to, {
sendsValue,
});
debugGas(`destAccessGas=${destAccessGas} waived off for target at depth=0`);
}
let callAccessGas = message.accessWitness.touchAndChargeMessageCall(message.to);
if (sendsValue) {
callAccessGas += message.accessWitness.touchAndChargeValueTransfer(fromAddress, message.to);
}
gasLimit -= callAccessGas;
if (gasLimit < BIGINT_0) {
if (this.DEBUG) {
debugGas(`callAccessGas charged(${callAccessGas}) caused OOG (-> ${gasLimit})`);
}
else {
if (this.DEBUG) {
debugGas(`Origin access used (${originAccessGas} gas (-> ${gasLimit}))`);
}
return { execResult: OOGResult(message.gasLimit) };
}
else {
if (this.DEBUG) {
debugGas(`callAccessGas used (${callAccessGas} gas (-> ${gasLimit}))`);
}
}
}
let account = await this.stateManager.getAccount(message.authcallOrigin ?? message.caller);
let account = await this.stateManager.getAccount(fromAddress);
if (!account) {

@@ -167,22 +182,2 @@ account = new Account();

}
if (this.common.isActivatedEIP(6800)) {
if (message.depth === 0) {
const sendsValue = message.value !== BIGINT_0;
const destAccessGas = message.accessWitness.touchTxExistingAndComputeGas(message.to, {
sendsValue,
});
gasLimit -= destAccessGas;
if (gasLimit < BIGINT_0) {
if (this.DEBUG) {
debugGas(`Destination access charged(${destAccessGas}) caused OOG (-> ${gasLimit})`);
}
return { execResult: OOGResult(message.gasLimit) };
}
else {
if (this.DEBUG) {
debugGas(`Destination access used (${destAccessGas} gas (-> ${gasLimit}))`);
}
}
}
}
// Load `to` account

@@ -281,16 +276,8 @@ let toAccount = await this.stateManager.getAccount(message.to);

let gasLimit = message.gasLimit;
const fromAddress = message.authcallOrigin ?? message.caller;
if (this.common.isActivatedEIP(6800)) {
const originAccessGas = message.accessWitness.touchTxOriginAndComputeGas(message.caller);
gasLimit -= originAccessGas;
if (gasLimit < BIGINT_0) {
if (this.DEBUG) {
debugGas(`Origin access charged(${originAccessGas}) caused OOG (-> ${gasLimit})`);
}
return { execResult: OOGResult(message.gasLimit) };
if (message.depth === 0) {
const originAccessGas = message.accessWitness.touchTxOriginAndComputeGas(fromAddress);
debugGas(`originAccessGas=${originAccessGas} waived off for origin at depth=0`);
}
else {
if (this.DEBUG) {
debugGas(`Origin access used (${originAccessGas} gas (-> ${gasLimit}))`);
}
}
}

@@ -330,8 +317,7 @@ let account = await this.stateManager.getAccount(message.caller);

if (this.common.isActivatedEIP(6800)) {
const sendsValue = message.value !== BIGINT_0;
const contractCreateAccessGas = message.accessWitness.touchAndChargeContractCreateInit(message.to, { sendsValue });
const contractCreateAccessGas = message.accessWitness.touchAndChargeContractCreateInit(message.to);
gasLimit -= contractCreateAccessGas;
if (gasLimit < BIGINT_0) {
if (this.DEBUG) {
debugGas(`Contract create (sendsValue=${sendsValue}) charge(${contractCreateAccessGas}) caused OOG (-> ${gasLimit})`);
debugGas(`ContractCreateInit charge(${contractCreateAccessGas}) caused OOG (-> ${gasLimit})`);
}

@@ -342,3 +328,3 @@ return { execResult: OOGResult(message.gasLimit) };

if (this.DEBUG) {
debugGas(`Contract create (sendsValue=${sendsValue}) charged (${contractCreateAccessGas} gas (-> ${gasLimit}))`);
debugGas(`ContractCreateInit charged (${contractCreateAccessGas} gas (-> ${gasLimit}))`);
}

@@ -349,3 +335,5 @@ }

if ((toAccount.nonce && toAccount.nonce > BIGINT_0) ||
!(equalsBytes(toAccount.codeHash, KECCAK256_NULL) === true)) {
!(equalsBytes(toAccount.codeHash, KECCAK256_NULL) === true) ||
// See EIP 7610 and the discussion `https://ethereum-magicians.org/t/eip-7610-revert-creation-in-case-of-non-empty-storage`
!(equalsBytes(toAccount.storageRoot, KECCAK256_RLP) === true)) {
if (this.DEBUG) {

@@ -401,2 +389,15 @@ debug(`Returning on address collision`);

if (exit) {
if (this.common.isActivatedEIP(6800)) {
const createCompleteAccessGas = message.accessWitness.touchAndChargeContractCreateCompleted(message.to);
gasLimit -= createCompleteAccessGas;
if (gasLimit < BIGINT_0) {
if (this.DEBUG) {
debug(`ContractCreateComplete access gas (${createCompleteAccessGas}) caused OOG (-> ${gasLimit})`);
}
return { execResult: OOGResult(message.gasLimit) };
}
else {
debug(`ContractCreateComplete access used (${createCompleteAccessGas}) gas (-> ${gasLimit})`);
}
}
return {

@@ -421,3 +422,3 @@ createdAddress: message.to,

let returnFee = BIGINT_0;
if (!result.exceptionError) {
if (!result.exceptionError && !this.common.isActivatedEIP(6800)) {
returnFee =

@@ -529,3 +530,3 @@ BigInt(result.returnValue.length) * BigInt(this.common.param('gasPrices', 'createData'));

if (this.common.isActivatedEIP(6800)) {
const byteCodeWriteAccessfee = message.accessWitness.touchCodeChunksRangeOnWriteAndChargeGas(message.to, 0, message.code.length - 1);
const byteCodeWriteAccessfee = message.accessWitness.touchCodeChunksRangeOnWriteAndChargeGas(message.to, 0, result.returnValue.length - 1);
gasLimit -= byteCodeWriteAccessfee;

@@ -539,3 +540,3 @@ if (gasLimit < BIGINT_0) {

else {
debug(`ContractCreateComplete access used (${byteCodeWriteAccessfee}) gas (-> ${gasLimit})`);
debug(`byteCodeWrite access used (${byteCodeWriteAccessfee}) gas (-> ${gasLimit})`);
result.executionGasUsed += byteCodeWriteAccessfee;

@@ -694,3 +695,3 @@ }

await this._emit('beforeMessage', message);
if (!message.to && this.common.isActivatedEIP(2929) === true) {
if (!message.to && this.common.isActivatedEIP(2929)) {
message.code = message.data;

@@ -923,2 +924,3 @@ this.journal.addWarmedAddress((await this._generateAddress(message)).bytes);

Hardfork.Prague,
Hardfork.Osaka,
];

@@ -925,0 +927,0 @@ export function OOGResult(gasLimit) {

@@ -26,4 +26,2 @@ export declare enum ERROR {

AUTHCALL_UNSET = "attempting to AUTHCALL without AUTH set",
AUTHCALL_NONZERO_VALUEEXT = "attempting to execute AUTHCALL with nonzero external value",
AUTH_INVALID_S = "invalid Signature: s-values greater than secp256k1n/2 are considered invalid",
BLS_12_381_INVALID_INPUT_LENGTH = "invalid input length",

@@ -30,0 +28,0 @@ BLS_12_381_POINT_NOT_ON_CURVE = "point not on curve",

@@ -27,4 +27,2 @@ export var ERROR;

ERROR["AUTHCALL_UNSET"] = "attempting to AUTHCALL without AUTH set";
ERROR["AUTHCALL_NONZERO_VALUEEXT"] = "attempting to execute AUTHCALL with nonzero external value";
ERROR["AUTH_INVALID_S"] = "invalid Signature: s-values greater than secp256k1n/2 are considered invalid";
// BLS errors

@@ -31,0 +29,0 @@ ERROR["BLS_12_381_INVALID_INPUT_LENGTH"] = "invalid input length";

import { EOF } from './eof.js';
import { EVM } from './evm.js';
import { ERROR as EVMErrorMessage, EvmError } from './exceptions.js';
import { InterpreterStep } from './interpreter.js';
import { Message } from './message.js';
import { getOpcodesForHF } from './opcodes/index.js';
import { PrecompileInput, getActivePrecompiles } from './precompiles/index.js';
import { EVMInterface, EVMResult, EVMRunCallOpts, EVMRunCodeOpts, ExecResult, Log, bn128 } from './types.js';
export { bn128, EOF, EVM, EvmError, EVMErrorMessage, EVMInterface, EVMResult, EVMRunCallOpts, EVMRunCodeOpts, ExecResult, getActivePrecompiles, getOpcodesForHF, InterpreterStep, Log, Message, PrecompileInput, };
import { MCLBLS, NobleBLS, type PrecompileInput, getActivePrecompiles } from './precompiles/index.js';
import type { InterpreterStep } from './interpreter.js';
import type { EVMInterface, EVMOpts, EVMResult, EVMRunCallOpts, EVMRunCodeOpts, ExecResult, Log, bn128 } from './types.js';
export * from './logger.js';
export type { bn128, EVMInterface, EVMOpts, EVMResult, EVMRunCallOpts, EVMRunCodeOpts, ExecResult, InterpreterStep, Log, PrecompileInput, };
export { EOF, EVM, EvmError, EVMErrorMessage, getActivePrecompiles, getOpcodesForHF, MCLBLS, Message, NobleBLS, };
//# sourceMappingURL=index.d.ts.map

@@ -6,4 +6,5 @@ import { EOF } from './eof.js';

import { getOpcodesForHF } from './opcodes/index.js';
import { getActivePrecompiles } from './precompiles/index.js';
export { EOF, EVM, EvmError, EVMErrorMessage, getActivePrecompiles, getOpcodesForHF, Message, };
import { MCLBLS, NobleBLS, getActivePrecompiles, } from './precompiles/index.js';
export * from './logger.js';
export { EOF, EVM, EvmError, EVMErrorMessage, getActivePrecompiles, getOpcodesForHF, MCLBLS, Message, NobleBLS, };
//# sourceMappingURL=index.js.map

@@ -11,5 +11,4 @@ import { Account } from '@ethereumjs/util';

import type { Block, Blockchain, EVMProfilerOpts, Log } from './types.js';
import type { Common, EVMStateManagerInterface } from '@ethereumjs/common';
import type { AccessWitness } from '@ethereumjs/statemanager';
import type { Address } from '@ethereumjs/util';
import type { AccessWitnessInterface, Common, EVMStateManagerInterface } from '@ethereumjs/common';
import type { Address, PrefixedHexString } from '@ethereumjs/util';
export interface InterpreterOpts {

@@ -27,7 +26,7 @@ pc?: number;

*/
selfdestruct: Set<string>;
selfdestruct: Set<PrefixedHexString>;
/**
* A map which tracks which addresses were created (used in EIP 6780)
*/
createdAddresses?: Set<string>;
createdAddresses?: Set<PrefixedHexString>;
}

@@ -51,3 +50,3 @@ export interface Env {

createdAddresses?: Set<string>;
accessWitness?: AccessWitness;
accessWitness?: AccessWitnessInterface;
chargeCodeAccesses?: boolean;

@@ -62,3 +61,2 @@ }

stack: Stack;
returnStack: Stack;
code: Uint8Array;

@@ -89,3 +87,2 @@ shouldDoJumpAnalysis: boolean;

stack: bigint[];
returnStack: bigint[];
pc: number;

@@ -92,0 +89,0 @@ depth: number;

import { ConsensusAlgorithm } from '@ethereumjs/common';
import { StatelessVerkleStateManager } from '@ethereumjs/statemanager';
import { Account, BIGINT_0, BIGINT_1, MAX_UINT64, bigIntToHex, bytesToBigInt, bytesToHex, equalsBytes, } from '@ethereumjs/util';

@@ -11,4 +10,3 @@ import debugDefault from 'debug';

import { Stack } from './stack.js';
const { debug: createDebugLogger } = debugDefault;
const debugGas = createDebugLogger('evm:gas');
const debugGas = debugDefault('evm:gas');
/**

@@ -32,3 +30,2 @@ * Parses and executes EVM bytecode.

stack: new Stack(),
returnStack: new Stack(1023),
code: new Uint8Array(0),

@@ -134,5 +131,6 @@ validJumps: Uint8Array.from([]),

this.common.isActivatedEIP(6800) &&
this._runState.stateManager instanceof StatelessVerkleStateManager) {
// is this a code loaded from state using witnesses
this._runState.env.chargeCodeAccesses === true) {
const contract = this._runState.interpreter.getAddress();
if (!this._runState.stateManager.checkChunkWitnessPresent(contract, programCounter)) {
if (!(await this._runState.stateManager.checkChunkWitnessPresent(contract, programCounter))) {
throw Error(`Invalid witness with missing codeChunk for pc=${programCounter}`);

@@ -247,3 +245,2 @@ }

stack: this._runState.stack.getStack(),
returnStack: this._runState.returnStack.getStack(),
depth: this._env.depth,

@@ -273,3 +270,3 @@ address: this._env.address,

if (!(name in this.opDebuggers)) {
this.opDebuggers[name] = createDebugLogger(`evm:ops:${name}`);
this.opDebuggers[name] = debugDefault(`evm:ops:${name}`);
}

@@ -323,6 +320,2 @@ this.opDebuggers[name](JSON.stringify(opTrace));

}
else if (opcode === 0x5c) {
// Define a BEGINSUB as a 2 in the valid jumps array
jumps[i] = 2;
}
}

@@ -643,2 +636,3 @@ }

blobVersionedHashes: this._env.blobVersionedHashes,
accessWitness: this._env.accessWitness,
});

@@ -661,2 +655,3 @@ return this._baseCall(msg);

blobVersionedHashes: this._env.blobVersionedHashes,
accessWitness: this._env.accessWitness,
});

@@ -679,2 +674,3 @@ return this._baseCall(msg);

blobVersionedHashes: this._env.blobVersionedHashes,
accessWitness: this._env.accessWitness,
});

@@ -698,2 +694,3 @@ return this._baseCall(msg);

blobVersionedHashes: this._env.blobVersionedHashes,
accessWitness: this._env.accessWitness,
});

@@ -718,2 +715,3 @@ return this._baseCall(msg);

blobVersionedHashes: this._env.blobVersionedHashes,
accessWitness: this._env.accessWitness,
});

@@ -808,2 +806,3 @@ return this._baseCall(msg);

blobVersionedHashes: this._env.blobVersionedHashes,
accessWitness: this._env.accessWitness,
});

@@ -810,0 +809,0 @@ let createdAddresses;

import { Address } from '@ethereumjs/util';
import type { Common, EVMStateManagerInterface } from '@ethereumjs/common';
import type { Account } from '@ethereumjs/util';
import type { Account, PrefixedHexString } from '@ethereumjs/util';
declare type AddressString = string;
declare type HashString = string;
declare type SlotString = string;

@@ -18,3 +17,3 @@ export declare class Journal {

accessList?: Map<AddressString, Set<SlotString>>;
preimages?: Map<HashString, Uint8Array>;
preimages?: Map<PrefixedHexString, Uint8Array>;
constructor(stateManager: EVMStateManagerInterface, common: Common);

@@ -21,0 +20,0 @@ /**

import { Hardfork } from '@ethereumjs/common';
import { Address, RIPEMD160_ADDRESS_STRING, bigIntToHex, bytesToHex, bytesToUnprefixedHex, stripHexPrefix, toBytes, unprefixedHexToBytes, } from '@ethereumjs/util';
import { Address, RIPEMD160_ADDRESS_STRING, bytesToHex, bytesToUnprefixedHex, stripHexPrefix, unprefixedHexToBytes, } from '@ethereumjs/util';
import debugDefault from 'debug';
const { debug: createDebugLogger } = debugDefault;
import { hexToBytes } from 'ethereum-cryptography/utils';
export class Journal {

@@ -11,3 +11,3 @@ constructor(stateManager, common) {

typeof window === 'undefined' ? process?.env?.DEBUG?.includes('ethjs') ?? false : false;
this._debug = createDebugLogger('statemanager:statemanager');
this._debug = debugDefault('statemanager:statemanager');
// TODO maybe call into this.clearJournal

@@ -128,14 +128,7 @@ this.cleanJournal();

async cleanup() {
if (this.common.gteHardfork(Hardfork.SpuriousDragon) === true) {
if (this.common.gteHardfork(Hardfork.SpuriousDragon)) {
for (const addressHex of this.touched) {
const address = new Address(toBytes('0x' + addressHex));
const address = new Address(hexToBytes(`0x${addressHex}`));
const account = await this.stateManager.getAccount(address);
if (account === undefined || account.isEmpty()) {
if (this.common.isActivatedEIP(2935)) {
// The history storage address is exempt of state clearing by EIP-158 if the EIP is activated
const addr = bigIntToHex(this.common.param('vm', 'historyStorageAddress')).slice(2);
if (addressHex === addr) {
continue;
}
}
await this.deleteAccount(address);

@@ -142,0 +135,0 @@ if (this.DEBUG) {

import { Address } from '@ethereumjs/util';
import type { PrecompileFunc } from './precompiles/index.js';
import type { AccessWitness } from '@ethereumjs/statemanager';
import type { AccessWitnessInterface } from '@ethereumjs/common';
import type { PrefixedHexString } from '@ethereumjs/util';
interface MessageOpts {

@@ -19,7 +20,7 @@ to?: Address;

*/
selfdestruct?: Set<string>;
selfdestruct?: Set<PrefixedHexString>;
/**
* Map of addresses which were created (used in EIP 6780)
*/
createdAddresses?: Set<string>;
createdAddresses?: Set<PrefixedHexString>;
delegatecall?: boolean;

@@ -29,3 +30,3 @@ authcallOrigin?: Address;

blobVersionedHashes?: Uint8Array[];
accessWitness?: AccessWitness;
accessWitness?: AccessWitnessInterface;
}

@@ -49,7 +50,7 @@ export declare class Message {

*/
selfdestruct?: Set<string>;
selfdestruct?: Set<PrefixedHexString>;
/**
* Map of addresses which were created (used in EIP 6780)
*/
createdAddresses?: Set<string>;
createdAddresses?: Set<PrefixedHexString>;
delegatecall: boolean;

@@ -66,3 +67,3 @@ /**

blobVersionedHashes?: Uint8Array[];
accessWitness?: AccessWitness;
accessWitness?: AccessWitnessInterface;
constructor(opts: MessageOpts);

@@ -69,0 +70,0 @@ /**

@@ -229,10 +229,2 @@ import { Hardfork } from '@ethereumjs/common';

{
eip: 2315,
opcodes: {
0x5c: { name: 'BEGINSUB', isAsync: false, dynamicGas: false },
0x5d: { name: 'RETURNSUB', isAsync: false, dynamicGas: false },
0x5e: { name: 'JUMPSUB', isAsync: false, dynamicGas: false },
},
},
{
eip: 3198,

@@ -239,0 +231,0 @@ opcodes: {

@@ -22,3 +22,3 @@ import type { RunState } from '../interpreter.js';

*/
export declare function accessStorageEIP2929(runState: RunState, key: Uint8Array, isSstore: boolean, common: Common): bigint;
export declare function accessStorageEIP2929(runState: RunState, key: Uint8Array, isSstore: boolean, common: Common, chargeGas?: boolean): bigint;
/**

@@ -25,0 +25,0 @@ * Adjusts cost of SSTORE_RESET_GAS or SLOAD (aka sstorenoop) (EIP-2200) downward when storage

@@ -13,3 +13,3 @@ import { BIGINT_0 } from '@ethereumjs/util';

export function accessAddressEIP2929(runState, address, common, chargeGas = true, isSelfdestructOrAuthcall = false) {
if (common.isActivatedEIP(2929) === false)
if (!common.isActivatedEIP(2929))
return BIGINT_0;

@@ -21,3 +21,4 @@ // Cold

// selfdestruct beneficiary address reads are charged an *additional* cold access
if (chargeGas) {
// if verkle not activated
if (chargeGas && !common.isActivatedEIP(6800)) {
return common.param('gasPrices', 'coldaccountaccess');

@@ -40,4 +41,4 @@ }

*/
export function accessStorageEIP2929(runState, key, isSstore, common) {
if (common.isActivatedEIP(2929) === false)
export function accessStorageEIP2929(runState, key, isSstore, common, chargeGas = true) {
if (!common.isActivatedEIP(2929))
return BIGINT_0;

@@ -49,5 +50,7 @@ const address = runState.interpreter.getAddress().bytes;

runState.interpreter.journal.addWarmedStorage(address, key);
return common.param('gasPrices', 'coldsload');
if (chargeGas && !common.isActivatedEIP(6800)) {
return common.param('gasPrices', 'coldsload');
}
}
else if (!isSstore) {
else if (chargeGas && (!isSstore || common.isActivatedEIP(6800))) {
return common.param('gasPrices', 'warmstorageread');

@@ -68,3 +71,3 @@ }

export function adjustSstoreGasEIP2929(runState, key, defaultCost, costName, common) {
if (common.isActivatedEIP(2929) === false)
if (!common.isActivatedEIP(2929))
return defaultCost;

@@ -71,0 +74,0 @@ const address = runState.interpreter.getAddress().bytes;

@@ -1,6 +0,6 @@

import { Address, BIGINT_0, BIGINT_1, BIGINT_128, BIGINT_160, BIGINT_2, BIGINT_224, BIGINT_255, BIGINT_256, BIGINT_27, BIGINT_2EXP160, BIGINT_2EXP224, BIGINT_2EXP96, BIGINT_31, BIGINT_32, BIGINT_7, BIGINT_8, BIGINT_96, MAX_INTEGER_BIGINT, SECP256K1_ORDER_DIV_2, TWO_POW256, bigIntToBytes, bigIntToHex, bytesToBigInt, bytesToHex, concatBytes, ecrecover, hexToBytes, publicToAddress, setLengthLeft, setLengthRight, } from '@ethereumjs/util';
import { Account, Address, BIGINT_0, BIGINT_1, BIGINT_160, BIGINT_2, BIGINT_224, BIGINT_255, BIGINT_256, BIGINT_27, BIGINT_2EXP160, BIGINT_2EXP224, BIGINT_2EXP96, BIGINT_31, BIGINT_32, BIGINT_7, BIGINT_8, BIGINT_96, MAX_INTEGER_BIGINT, SECP256K1_ORDER_DIV_2, TWO_POW256, bigIntToAddressBytes, bigIntToBytes, bytesToBigInt, bytesToHex, concatBytes, ecrecover, getVerkleTreeIndexesForStorageSlot, hexToBytes, publicToAddress, setLengthLeft, setLengthRight, } from '@ethereumjs/util';
import { keccak256 } from 'ethereum-cryptography/keccak.js';
import { ERROR } from '../exceptions.js';
import { addresstoBytes, describeLocation, exponentiation, fromTwos, getDataSlice, jumpIsValid, jumpSubIsValid, mod, toTwos, trap, writeCallOutput, } from './util.js';
const EIP3074MAGIC = hexToBytes('0x03');
import { addresstoBytes, describeLocation, exponentiation, fromTwos, getDataSlice, jumpIsValid, mod, toTwos, trap, writeCallOutput, } from './util.js';
const EIP3074MAGIC = hexToBytes('0x04');
// the opcode functions

@@ -460,4 +460,10 @@ export const handlers = new Map([

const addressBigInt = runState.stack.pop();
const size = BigInt((await runState.stateManager.getContractCode(new Address(addresstoBytes(addressBigInt))))
.length);
let size;
if (typeof runState.stateManager.getContractCodeSize === 'function') {
size = BigInt(await runState.stateManager.getContractCodeSize(new Address(addresstoBytes(addressBigInt))));
}
else {
size = BigInt((await runState.stateManager.getContractCode(new Address(addresstoBytes(addressBigInt))))
.length);
}
runState.stack.push(size);

@@ -527,3 +533,3 @@ },

const number = runState.stack.pop();
if (common.isActivatedEIP(2935)) {
if (common.isActivatedEIP(7709)) {
if (number >= runState.interpreter.getBlockNumber()) {

@@ -534,10 +540,17 @@ runState.stack.push(BIGINT_0);

const diff = runState.interpreter.getBlockNumber() - number;
const historyServeWindow = common.param('vm', 'historyServeWindow');
// block lookups must be within the `historyServeWindow`
if (diff > historyServeWindow || diff <= BIGINT_0) {
// block lookups must be within the original window even if historyStorageAddress's
// historyServeWindow is much greater than 256
if (diff > BIGINT_256 || diff <= BIGINT_0) {
runState.stack.push(BIGINT_0);
return;
}
const historyAddress = Address.fromString(bigIntToHex(common.param('vm', 'historyStorageAddress')));
const historyAddress = new Address(bigIntToAddressBytes(common.param('vm', 'historyStorageAddress')));
const historyServeWindow = common.param('vm', 'historyServeWindow');
const key = setLengthLeft(bigIntToBytes(number % historyServeWindow), 32);
if (common.isActivatedEIP(6800)) {
const { treeIndex, subIndex } = getVerkleTreeIndexesForStorageSlot(number);
// create witnesses and charge gas
const statelessGas = runState.env.accessWitness.touchAddressOnReadAndComputeGas(historyAddress, treeIndex, subIndex);
runState.interpreter.useGas(statelessGas, `BLOCKHASH`);
}
const storage = await runState.stateManager.getContractStorage(historyAddress, key);

@@ -759,74 +772,41 @@ runState.stack.push(bytesToBigInt(storage));

[0x5b, function () { }],
// 0x5c: BEGINSUB (EIP 2315) / TLOAD (EIP 1153)
// 0x5c: TLOAD (EIP 1153)
[
0x5c,
function (runState, common) {
if (common.isActivatedEIP(2315)) {
// BEGINSUB
trap(ERROR.INVALID_BEGINSUB + ' at ' + describeLocation(runState));
}
else if (common.isActivatedEIP(1153)) {
// TLOAD
const key = runState.stack.pop();
const keyBuf = setLengthLeft(bigIntToBytes(key), 32);
const value = runState.interpreter.transientStorageLoad(keyBuf);
const valueBN = value.length ? bytesToBigInt(value) : BIGINT_0;
runState.stack.push(valueBN);
}
function (runState) {
const key = runState.stack.pop();
const keyBuf = setLengthLeft(bigIntToBytes(key), 32);
const value = runState.interpreter.transientStorageLoad(keyBuf);
const valueBN = value.length ? bytesToBigInt(value) : BIGINT_0;
runState.stack.push(valueBN);
},
],
// 0x5d: RETURNSUB (EIP 2315) / TSTORE (EIP 1153)
// 0x5d: TSTORE (EIP 1153)
[
0x5d,
function (runState, common) {
if (common.isActivatedEIP(2315)) {
// RETURNSUB
if (runState.returnStack.length < 1) {
trap(ERROR.INVALID_RETURNSUB);
}
const dest = runState.returnStack.pop();
runState.programCounter = Number(dest);
function (runState) {
// TSTORE
if (runState.interpreter.isStatic()) {
trap(ERROR.STATIC_STATE_CHANGE);
}
else if (common.isActivatedEIP(1153)) {
// TSTORE
if (runState.interpreter.isStatic()) {
trap(ERROR.STATIC_STATE_CHANGE);
}
const [key, val] = runState.stack.popN(2);
const keyBuf = setLengthLeft(bigIntToBytes(key), 32);
// NOTE: this should be the shortest representation
let value;
if (val === BIGINT_0) {
value = Uint8Array.from([]);
}
else {
value = bigIntToBytes(val);
}
runState.interpreter.transientStorageStore(keyBuf, value);
const [key, val] = runState.stack.popN(2);
const keyBuf = setLengthLeft(bigIntToBytes(key), 32);
// NOTE: this should be the shortest representation
let value;
if (val === BIGINT_0) {
value = Uint8Array.from([]);
}
else {
value = bigIntToBytes(val);
}
runState.interpreter.transientStorageStore(keyBuf, value);
},
],
// 0x5e: JUMPSUB (2315) / MCOPY (5656)
// 0x5e: MCOPY (5656)
[
0x5e,
function (runState, common) {
if (common.isActivatedEIP(2315)) {
// JUMPSUB
const dest = runState.stack.pop();
if (dest > runState.interpreter.getCodeSize()) {
trap(ERROR.INVALID_JUMPSUB + ' at ' + describeLocation(runState));
}
const destNum = Number(dest);
if (!jumpSubIsValid(runState, destNum)) {
trap(ERROR.INVALID_JUMPSUB + ' at ' + describeLocation(runState));
}
runState.returnStack.push(BigInt(runState.programCounter));
runState.programCounter = destNum + 1;
}
else if (common.isActivatedEIP(5656)) {
// MCOPY
const [dst, src, length] = runState.stack.popN(3);
const data = runState.memory.read(Number(src), Number(length), true);
runState.memory.write(Number(dst), Number(length), data);
}
function (runState) {
const [dst, src, length] = runState.stack.popN(3);
const data = runState.memory.read(Number(src), Number(length), true);
runState.memory.write(Number(dst), Number(length), data);
},

@@ -1016,19 +996,37 @@ ],

let [authority, memOffset, memLength] = runState.stack.popN(3);
if (memLength > BIGINT_128) {
memLength = BIGINT_128;
if (memLength > BigInt(97)) {
memLength = BigInt(97);
}
let mem = runState.memory.read(Number(memOffset), Number(memLength));
if (mem.length < 128) {
mem = setLengthRight(mem, 128);
if (mem.length < 97) {
mem = setLengthRight(mem, 97);
}
const yParity = BigInt(mem[31]);
const r = mem.subarray(32, 64);
const s = mem.subarray(64, 96);
const commit = mem.subarray(96, 128);
const yParity = BigInt(mem[0]);
const r = mem.subarray(1, 33);
const s = mem.subarray(33, 65);
const commit = mem.subarray(65, 97);
if (bytesToBigInt(s) > SECP256K1_ORDER_DIV_2) {
trap(ERROR.AUTH_INVALID_S);
runState.stack.push(BIGINT_0);
runState.auth = undefined;
return;
}
const paddedInvokerAddress = setLengthLeft(runState.interpreter._env.address.bytes, 32);
if (yParity > BIGINT_1) {
runState.stack.push(BIGINT_0);
runState.auth = undefined;
return;
}
// we don't want strick check here on authority being in address range just last 20 bytes
const expectedAddress = new Address(bigIntToAddressBytes(authority, false));
const account = (await runState.stateManager.getAccount(expectedAddress)) ?? new Account();
if (account.isContract()) {
// EXTCODESIZE > 0
runState.stack.push(BIGINT_0);
runState.auth = undefined;
return;
}
const accountNonce = account.nonce;
const invokedAddress = setLengthLeft(runState.interpreter._env.address.bytes, 32);
const chainId = setLengthLeft(bigIntToBytes(runState.interpreter.getChainId()), 32);
const message = concatBytes(EIP3074MAGIC, chainId, paddedInvokerAddress, commit);
const nonce = setLengthLeft(bigIntToBytes(accountNonce), 32);
const message = concatBytes(EIP3074MAGIC, chainId, nonce, invokedAddress, commit);
const keccakFunction = runState.interpreter._evm.common.customCrypto.keccak256 ?? keccak256;

@@ -1050,3 +1048,2 @@ const msgHash = keccakFunction(message);

runState.auth = address;
const expectedAddress = new Address(setLengthLeft(bigIntToBytes(authority), 20));
if (!expectedAddress.equals(address)) {

@@ -1066,3 +1063,3 @@ // expected address does not equal the recovered address, clear auth variable

async function (runState) {
const [_currentGasLimit, addr, value, _valueExt, argsOffset, argsLength, retOffset, retLength,] = runState.stack.popN(8);
const [_currentGasLimit, addr, value, argsOffset, argsLength, retOffset, retLength] = runState.stack.popN(7);
const toAddress = new Address(addresstoBytes(addr));

@@ -1069,0 +1066,0 @@ const gasLimit = runState.messageGasLimit;

import { Hardfork } from '@ethereumjs/common';
import { CODE_SIZE_LEAF_KEY, getTreeIndexesForStorageSlot } from '@ethereumjs/statemanager';
import { Address, BIGINT_0, BIGINT_1, BIGINT_3, BIGINT_31, BIGINT_32, bigIntToBytes, setLengthLeft, } from '@ethereumjs/util';
import { Account, Address, BIGINT_0, BIGINT_1, BIGINT_3, BIGINT_31, BIGINT_32, VERKLE_BALANCE_LEAF_KEY, VERKLE_CODE_HASH_LEAF_KEY, VERKLE_CODE_SIZE_LEAF_KEY, VERKLE_VERSION_LEAF_KEY, bigIntToBytes, getVerkleTreeIndexesForStorageSlot, setLengthLeft, } from '@ethereumjs/util';
import { ERROR } from '../exceptions.js';

@@ -44,6 +43,13 @@ import { updateSstoreGasEIP1283 } from './EIP1283.js';

async function (runState, gas, common) {
if (common.isActivatedEIP(2929) === true) {
const address = runState.stack.peek()[0];
gas += accessAddressEIP2929(runState, addresstoBytes(address), common);
const address = addresstoBytes(runState.stack.peek()[0]);
let charge2929Gas = true;
if (common.isActivatedEIP(6800)) {
const balanceAddress = new Address(address);
const coldAccessGas = runState.env.accessWitness.touchAddressOnReadAndComputeGas(balanceAddress, 0, VERKLE_BALANCE_LEAF_KEY);
gas += coldAccessGas;
charge2929Gas = coldAccessGas === BIGINT_0;
}
if (common.isActivatedEIP(2929)) {
gas += accessAddressEIP2929(runState, address, common, charge2929Gas);
}
return gas;

@@ -72,3 +78,3 @@ },

gas += common.param('gasPrices', 'copy') * divCeil(dataLength, BIGINT_32);
if (common.isActivatedEIP(6800)) {
if (common.isActivatedEIP(6800) && runState.env.chargeCodeAccesses === true) {
const contract = runState.interpreter.getAddress();

@@ -90,9 +96,16 @@ let codeEnd = _codeOffset + dataLength;

async function (runState, gas, common) {
if (common.isActivatedEIP(2929) === true) {
const address = runState.stack.peek()[0];
gas += accessAddressEIP2929(runState, addresstoBytes(address), common);
const addressBytes = addresstoBytes(runState.stack.peek()[0]);
const address = new Address(addressBytes);
let charge2929Gas = true;
if (common.isActivatedEIP(6800) &&
runState.interpreter._evm.getPrecompile(address) === undefined) {
let coldAccessGas = BIGINT_0;
coldAccessGas += runState.env.accessWitness.touchAddressOnReadAndComputeGas(address, 0, VERKLE_VERSION_LEAF_KEY);
coldAccessGas += runState.env.accessWitness.touchAddressOnReadAndComputeGas(address, 0, VERKLE_CODE_SIZE_LEAF_KEY);
gas += coldAccessGas;
// if cold access gas has been charged 2929 gas shouldn't be charged
charge2929Gas = coldAccessGas === BIGINT_0;
}
if (common.isActivatedEIP(6800) === true) {
const address = new Address(addresstoBytes(runState.stack.peek()[0]));
gas += runState.env.accessWitness.touchAddressOnReadAndComputeGas(address, 0, CODE_SIZE_LEAF_KEY);
if (common.isActivatedEIP(2929)) {
gas += accessAddressEIP2929(runState, addressBytes, common, charge2929Gas);
}

@@ -106,17 +119,28 @@ return gas;

async function (runState, gas, common) {
const [address, memOffset, _codeOffset, dataLength] = runState.stack.peek(4);
const [addressBigInt, memOffset, _codeOffset, dataLength] = runState.stack.peek(4);
const addressBytes = addresstoBytes(addressBigInt);
const address = new Address(addressBytes);
gas += subMemUsage(runState, memOffset, dataLength, common);
if (common.isActivatedEIP(2929) === true) {
gas += accessAddressEIP2929(runState, addresstoBytes(address), common);
let charge2929Gas = true;
if (common.isActivatedEIP(6800) &&
runState.interpreter._evm.getPrecompile(address) === undefined) {
let coldAccessGas = BIGINT_0;
coldAccessGas += runState.env.accessWitness.touchAddressOnReadAndComputeGas(address, 0, VERKLE_VERSION_LEAF_KEY);
coldAccessGas += runState.env.accessWitness.touchAddressOnReadAndComputeGas(address, 0, VERKLE_CODE_SIZE_LEAF_KEY);
gas += coldAccessGas;
// if cold access gas has been charged 2929 gas shouldn't be charged
charge2929Gas = coldAccessGas === BIGINT_0;
}
if (common.isActivatedEIP(2929)) {
gas += accessAddressEIP2929(runState, addressBytes, common, charge2929Gas);
}
if (dataLength !== BIGINT_0) {
gas += common.param('gasPrices', 'copy') * divCeil(dataLength, BIGINT_32);
if (common.isActivatedEIP(6800)) {
const contract = new Address(addresstoBytes(address));
let codeEnd = _codeOffset + dataLength;
const codeSize = BigInt((await runState.stateManager.getContractCode(contract)).length);
const codeSize = BigInt((await runState.stateManager.getContractCode(address)).length);
if (codeEnd > codeSize) {
codeEnd = codeSize;
}
gas += runState.env.accessWitness.touchCodeChunksRangeOnReadAndChargeGas(contract, Number(_codeOffset), Number(codeEnd));
gas += runState.env.accessWitness.touchCodeChunksRangeOnReadAndChargeGas(address, Number(_codeOffset), Number(codeEnd));
}

@@ -146,6 +170,14 @@ }

async function (runState, gas, common) {
if (common.isActivatedEIP(2929) === true) {
const address = runState.stack.peek()[0];
gas += accessAddressEIP2929(runState, addresstoBytes(address), common);
const address = addresstoBytes(runState.stack.peek()[0]);
let charge2929Gas = true;
if (common.isActivatedEIP(6800)) {
const codeAddress = new Address(address);
let coldAccessGas = BIGINT_0;
coldAccessGas += runState.env.accessWitness.touchAddressOnReadAndComputeGas(codeAddress, 0, VERKLE_CODE_HASH_LEAF_KEY);
gas += coldAccessGas;
charge2929Gas = coldAccessGas === BIGINT_0;
}
if (common.isActivatedEIP(2929)) {
gas += accessAddressEIP2929(runState, address, common, charge2929Gas);
}
return gas;

@@ -187,10 +219,13 @@ },

const keyBuf = setLengthLeft(bigIntToBytes(key), 32);
if (common.isActivatedEIP(2929) === true) {
gas += accessStorageEIP2929(runState, keyBuf, false, common);
}
if (common.isActivatedEIP(6800) === true) {
let charge2929Gas = true;
if (common.isActivatedEIP(6800)) {
const address = runState.interpreter.getAddress();
const { treeIndex, subIndex } = getTreeIndexesForStorageSlot(key);
gas += runState.env.accessWitness.touchAddressOnReadAndComputeGas(address, treeIndex, subIndex);
const { treeIndex, subIndex } = getVerkleTreeIndexesForStorageSlot(key);
const coldAccessGas = runState.env.accessWitness.touchAddressOnReadAndComputeGas(address, treeIndex, subIndex);
gas += coldAccessGas;
charge2929Gas = coldAccessGas === BIGINT_0;
}
if (common.isActivatedEIP(2929)) {
gas += accessStorageEIP2929(runState, keyBuf, false, common, charge2929Gas);
}
return gas;

@@ -222,3 +257,5 @@ },

else if (common.gteHardfork(Hardfork.Istanbul)) {
gas += updateSstoreGasEIP2200(runState, currentStorage, originalStorage, setLengthLeftStorage(value), keyBytes, common);
if (!common.isActivatedEIP(6800)) {
gas += updateSstoreGasEIP2200(runState, currentStorage, originalStorage, setLengthLeftStorage(value), keyBytes, common);
}
}

@@ -228,13 +265,16 @@ else {

}
if (common.isActivatedEIP(2929) === true) {
let charge2929Gas = true;
if (common.isActivatedEIP(6800)) {
const contract = runState.interpreter.getAddress();
const { treeIndex, subIndex } = getVerkleTreeIndexesForStorageSlot(key);
const coldAccessGas = runState.env.accessWitness.touchAddressOnWriteAndComputeGas(contract, treeIndex, subIndex);
gas += coldAccessGas;
charge2929Gas = coldAccessGas === BIGINT_0;
}
if (common.isActivatedEIP(2929)) {
// We have to do this after the Istanbul (EIP2200) checks.
// Otherwise, we might run out of gas, due to "sentry check" of 2300 gas,
// if we deduct extra gas first.
gas += accessStorageEIP2929(runState, keyBytes, true, common);
gas += accessStorageEIP2929(runState, keyBytes, true, common, charge2929Gas);
}
if (common.isActivatedEIP(6800) === true) {
const contract = runState.interpreter.getAddress();
const { treeIndex, subIndex } = getTreeIndexesForStorageSlot(key);
gas += runState.env.accessWitness.touchAddressOnWriteAndComputeGas(contract, treeIndex, subIndex);
}
return gas;

@@ -282,6 +322,6 @@ },

const [_value, offset, length] = runState.stack.peek(3);
if (common.isActivatedEIP(2929) === true) {
if (common.isActivatedEIP(2929)) {
gas += accessAddressEIP2929(runState, runState.interpreter.getAddress().bytes, common, false);
}
if (common.isActivatedEIP(3860) === true) {
if (common.isActivatedEIP(3860)) {
gas += ((length + BIGINT_31) / BIGINT_32) * common.param('gasPrices', 'initCodeWordCost');

@@ -307,6 +347,18 @@ }

gas += subMemUsage(runState, outOffset, outLength, common);
if (common.isActivatedEIP(2929) === true) {
gas += accessAddressEIP2929(runState, toAddress.bytes, common);
let charge2929Gas = true;
if (common.isActivatedEIP(6800) &&
runState.interpreter._evm.getPrecompile(toAddress) === undefined) {
// TODO: add check if toAddress is not a precompile
const coldAccessGas = runState.env.accessWitness.touchAndChargeMessageCall(toAddress);
if (value !== BIGINT_0) {
const contractAddress = runState.interpreter.getAddress();
gas += runState.env.accessWitness.touchAndChargeValueTransfer(contractAddress, toAddress);
}
gas += coldAccessGas;
charge2929Gas = coldAccessGas === BIGINT_0;
}
if (value !== BIGINT_0) {
if (common.isActivatedEIP(2929)) {
gas += accessAddressEIP2929(runState, toAddress.bytes, common, charge2929Gas);
}
if (value !== BIGINT_0 && !common.isActivatedEIP(6800)) {
gas += common.param('gasPrices', 'callValueTransfer');

@@ -331,10 +383,2 @@ }

}
if (common.isActivatedEIP(6800)) {
// TODO: add check if toAddress is not a precompile
gas += runState.env.accessWitness.touchAndChargeMessageCall(toAddress);
if (value !== BIGINT_0) {
const contractAddress = runState.interpreter.getAddress();
gas += runState.env.accessWitness.touchAndChargeValueTransfer(contractAddress, toAddress);
}
}
const gasLimit = maxCallGas(currentGasLimit, runState.interpreter.getGasLeft() - gas, runState, common);

@@ -358,15 +402,18 @@ // note that TangerineWhistle or later this cannot happen

const [currentGasLimit, toAddr, value, inOffset, inLength, outOffset, outLength] = runState.stack.peek(7);
const toAddress = new Address(addresstoBytes(toAddr));
gas += subMemUsage(runState, inOffset, inLength, common);
gas += subMemUsage(runState, outOffset, outLength, common);
if (common.isActivatedEIP(2929) === true) {
gas += accessAddressEIP2929(runState, addresstoBytes(toAddr), common);
let charge2929Gas = true;
if (common.isActivatedEIP(6800) &&
runState.interpreter._evm.getPrecompile(toAddress) === undefined) {
const coldAccessGas = runState.env.accessWitness.touchAndChargeMessageCall(toAddress);
gas += coldAccessGas;
charge2929Gas = coldAccessGas === BIGINT_0;
}
if (common.isActivatedEIP(2929)) {
gas += accessAddressEIP2929(runState, addresstoBytes(toAddr), common, charge2929Gas);
}
if (value !== BIGINT_0) {
gas += common.param('gasPrices', 'callValueTransfer');
}
if (common.isActivatedEIP(6800)) {
const toAddress = new Address(addresstoBytes(toAddr));
// TODO: add check if toAddress is not a precompile
gas += runState.env.accessWitness.touchAndChargeMessageCall(toAddress);
}
const gasLimit = maxCallGas(currentGasLimit, runState.interpreter.getGasLeft() - gas, runState, common);

@@ -396,12 +443,16 @@ // note that TangerineWhistle or later this cannot happen

const [currentGasLimit, toAddr, inOffset, inLength, outOffset, outLength] = runState.stack.peek(6);
const toAddress = new Address(addresstoBytes(toAddr));
gas += subMemUsage(runState, inOffset, inLength, common);
gas += subMemUsage(runState, outOffset, outLength, common);
if (common.isActivatedEIP(2929) === true) {
gas += accessAddressEIP2929(runState, addresstoBytes(toAddr), common);
}
if (common.isActivatedEIP(6800)) {
const toAddress = new Address(addresstoBytes(toAddr));
let charge2929Gas = true;
if (common.isActivatedEIP(6800) &&
runState.interpreter._evm.getPrecompile(toAddress) === undefined) {
// TODO: add check if toAddress is not a precompile
gas += runState.env.accessWitness.touchAndChargeMessageCall(toAddress);
const coldAccessGas = runState.env.accessWitness.touchAndChargeMessageCall(toAddress);
gas += coldAccessGas;
charge2929Gas = coldAccessGas === BIGINT_0;
}
if (common.isActivatedEIP(2929)) {
gas += accessAddressEIP2929(runState, addresstoBytes(toAddr), common, charge2929Gas);
}
const gasLimit = maxCallGas(currentGasLimit, runState.interpreter.getGasLeft() - gas, runState, common);

@@ -426,6 +477,6 @@ // note that TangerineWhistle or later this cannot happen

gas += subMemUsage(runState, offset, length, common);
if (common.isActivatedEIP(2929) === true) {
if (common.isActivatedEIP(2929)) {
gas += accessAddressEIP2929(runState, runState.interpreter.getAddress().bytes, common, false);
}
if (common.isActivatedEIP(3860) === true) {
if (common.isActivatedEIP(3860)) {
gas += ((length + BIGINT_31) / BIGINT_32) * common.param('gasPrices', 'initCodeWordCost');

@@ -444,3 +495,6 @@ }

async function (runState, gas, common) {
const [_address, memOffset, memLength] = runState.stack.peek(3);
const [address, memOffset, memLength] = runState.stack.peek(3);
// Note: 2929 is always active if AUTH can be reached,
// since it needs London as minimum hardfork
gas += accessAddressEIP2929(runState, bigIntToBytes(address), common);
gas += subMemUsage(runState, memOffset, memLength, common);

@@ -457,6 +511,3 @@ return gas;

}
const [currentGasLimit, addr, value, valueExt, argsOffset, argsLength, retOffset, retLength,] = runState.stack.peek(8);
if (valueExt !== BIGINT_0) {
trap(ERROR.AUTHCALL_NONZERO_VALUEEXT);
}
const [currentGasLimit, addr, value, argsOffset, argsLength, retOffset, retLength] = runState.stack.peek(7);
const toAddress = new Address(addresstoBytes(addr));

@@ -482,2 +533,13 @@ gas += common.param('gasPrices', 'warmstorageread');

runState.messageGasLimit = gasLimit;
if (value > BIGINT_0) {
const account = (await runState.stateManager.getAccount(runState.auth)) ?? new Account();
if (account.balance < value) {
trap(ERROR.OUT_OF_GAS);
}
account.balance -= value;
const toAddr = new Address(addresstoBytes(addr));
const target = (await runState.stateManager.getAccount(toAddr)) ?? new Account();
target.balance += value;
await runState.stateManager.putAccount(toAddr, target);
}
return gas;

@@ -493,10 +555,13 @@ },

gas += subMemUsage(runState, outOffset, outLength, common);
if (common.isActivatedEIP(2929) === true) {
gas += accessAddressEIP2929(runState, addresstoBytes(toAddr), common);
}
let charge2929Gas = true;
if (common.isActivatedEIP(6800)) {
const toAddress = new Address(addresstoBytes(toAddr));
// TODO: add check if toAddress is not a precompile
gas += runState.env.accessWitness.touchAndChargeMessageCall(toAddress);
const coldAccessGas = runState.env.accessWitness.touchAndChargeMessageCall(toAddress);
gas += coldAccessGas;
charge2929Gas = coldAccessGas === BIGINT_0;
}
if (common.isActivatedEIP(2929)) {
gas += accessAddressEIP2929(runState, addresstoBytes(toAddr), common, charge2929Gas);
}
const gasLimit = maxCallGas(currentGasLimit, runState.interpreter.getGasLeft() - gas, runState, common); // we set TangerineWhistle or later to true here, as STATICCALL was available from Byzantium (which is after TangerineWhistle)

@@ -525,6 +590,7 @@ runState.messageGasLimit = gasLimit;

const selfdestructToAddress = new Address(addresstoBytes(selfdestructToaddressBigInt));
const contractAddress = runState.interpreter.getAddress();
let deductGas = false;
const balance = await runState.interpreter.getExternalBalance(contractAddress);
if (common.gteHardfork(Hardfork.SpuriousDragon)) {
// EIP-161: State Trie Clearing
const balance = await runState.interpreter.getExternalBalance(runState.interpreter.getAddress());
if (balance > BIGINT_0) {

@@ -548,5 +614,24 @@ // This technically checks if account is empty or non-existent

}
if (common.isActivatedEIP(2929) === true) {
gas += accessAddressEIP2929(runState, selfdestructToAddress.bytes, common, true, true);
let selfDestructToCharge2929Gas = true;
if (common.isActivatedEIP(6800)) {
// read accesses for version and code size
if (runState.interpreter._evm.getPrecompile(contractAddress) === undefined) {
gas += runState.env.accessWitness.touchAddressOnReadAndComputeGas(contractAddress, 0, VERKLE_VERSION_LEAF_KEY);
gas += runState.env.accessWitness.touchAddressOnReadAndComputeGas(contractAddress, 0, VERKLE_CODE_SIZE_LEAF_KEY);
}
gas += runState.env.accessWitness.touchAddressOnReadAndComputeGas(contractAddress, 0, VERKLE_BALANCE_LEAF_KEY);
if (balance > BIGINT_0) {
gas += runState.env.accessWitness.touchAddressOnWriteAndComputeGas(contractAddress, 0, VERKLE_BALANCE_LEAF_KEY);
}
let selfDestructToColdAccessGas = runState.env.accessWitness.touchAddressOnReadAndComputeGas(selfdestructToAddress, 0, VERKLE_BALANCE_LEAF_KEY);
if (balance > BIGINT_0) {
selfDestructToColdAccessGas +=
runState.env.accessWitness.touchAddressOnWriteAndComputeGas(selfdestructToAddress, 0, VERKLE_BALANCE_LEAF_KEY);
}
gas += selfDestructToColdAccessGas;
selfDestructToCharge2929Gas = selfDestructToColdAccessGas === BIGINT_0;
}
if (common.isActivatedEIP(2929)) {
gas += accessAddressEIP2929(runState, selfdestructToAddress.bytes, common, selfDestructToCharge2929Gas, true);
}
return gas;

@@ -553,0 +638,0 @@ },

@@ -47,6 +47,2 @@ import type { RunState } from '../interpreter.js';

/**
* Checks if a jumpsub is valid given a destination (defined as a 2 in the validJumps array)
*/
export declare function jumpSubIsValid(runState: RunState, dest: number): boolean;
/**
* Returns an overflow-safe slice of an array. It right-pads

@@ -53,0 +49,0 @@ * the data with zeros to `length`.

@@ -110,8 +110,2 @@ import { Hardfork } from '@ethereumjs/common';

/**
* Checks if a jumpsub is valid given a destination (defined as a 2 in the validJumps array)
*/
export function jumpSubIsValid(runState, dest) {
return runState.validJumps[dest] === 2;
}
/**
* Returns an overflow-safe slice of an array. It right-pads

@@ -118,0 +112,0 @@ * the data with zeros to `length`.

import { type Address } from '@ethereumjs/util';
import { MCLBLS, NobleBLS } from './bls12_381/index.js';
import type { PrecompileFunc, PrecompileInput } from './types.js';

@@ -39,4 +40,4 @@ import type { Common } from '@ethereumjs/common';

declare function getPrecompileName(addressUnprefixedStr: string): string | undefined;
export { getActivePrecompiles, getPrecompileName, precompileEntries, precompiles, ripemdPrecompileAddress, };
export { getActivePrecompiles, getPrecompileName, MCLBLS, NobleBLS, precompileEntries, precompiles, ripemdPrecompileAddress, };
export type { AddPrecompile, CustomPrecompile, DeletePrecompile, PrecompileFunc, PrecompileInput };
//# sourceMappingURL=index.d.ts.map

@@ -13,2 +13,12 @@ import { Hardfork } from '@ethereumjs/common';

import { precompile0a } from './0a-kzg-point-evaluation.js';
import { precompile0b } from './0b-bls12-g1add.js';
import { precompile0c } from './0c-bls12-g1mul.js';
import { precompile0d } from './0d-bls12-g1msm.js';
import { precompile0e } from './0e-bls12-g2add.js';
import { precompile0f } from './0f-bls12-g2mul.js';
import { precompile10 } from './10-bls12-g2msm.js';
import { precompile11 } from './11-bls12-pairing.js';
import { precompile12 } from './12-bls12-map-fp-to-g1.js';
import { precompile13 } from './13-bls12-map-fp2-to-g2.js';
import { MCLBLS, NobleBLS } from './bls12_381/index.js';
var PrecompileAvailabilityCheck;

@@ -111,2 +121,83 @@ (function (PrecompileAvailabilityCheck) {

},
{
address: '000000000000000000000000000000000000000b',
check: {
type: PrecompileAvailabilityCheck.EIP,
param: 2537,
},
precompile: precompile0b,
name: 'BLS12_G1ADD',
},
{
address: '000000000000000000000000000000000000000c',
check: {
type: PrecompileAvailabilityCheck.EIP,
param: 2537,
},
precompile: precompile0c,
name: 'BLS12_G1MUL',
},
{
address: '000000000000000000000000000000000000000d',
check: {
type: PrecompileAvailabilityCheck.EIP,
param: 2537,
},
precompile: precompile0d,
name: 'BLS12_G1MSM',
},
{
address: '000000000000000000000000000000000000000e',
check: {
type: PrecompileAvailabilityCheck.EIP,
param: 2537,
},
precompile: precompile0e,
name: 'BLS12_G2ADD',
},
{
address: '000000000000000000000000000000000000000f',
check: {
type: PrecompileAvailabilityCheck.EIP,
param: 2537,
},
precompile: precompile0f,
name: 'BLS12_G2MUL',
},
{
address: '0000000000000000000000000000000000000010',
check: {
type: PrecompileAvailabilityCheck.EIP,
param: 2537,
},
precompile: precompile10,
name: 'BLS12_G2MSM',
},
{
address: '0000000000000000000000000000000000000011',
check: {
type: PrecompileAvailabilityCheck.EIP,
param: 2537,
},
precompile: precompile11,
name: 'BLS12_PAIRING',
},
{
address: '0000000000000000000000000000000000000012',
check: {
type: PrecompileAvailabilityCheck.EIP,
param: 2537,
},
precompile: precompile12,
name: 'BLS12_MAP_FP_TO_G1',
},
{
address: '0000000000000000000000000000000000000013',
check: {
type: PrecompileAvailabilityCheck.EIP,
param: 2537,
},
precompile: precompile13,
name: 'BLS12_MAP_FP2_TO_G2',
},
];

@@ -124,2 +215,11 @@ const precompiles = {

'000000000000000000000000000000000000000a': precompile0a,
'000000000000000000000000000000000000000b': precompile0b,
'000000000000000000000000000000000000000c': precompile0c,
'000000000000000000000000000000000000000d': precompile0d,
'000000000000000000000000000000000000000e': precompile0e,
'000000000000000000000000000000000000000f': precompile0f,
'0000000000000000000000000000000000000010': precompile10,
'0000000000000000000000000000000000000011': precompile11,
'0000000000000000000000000000000000000012': precompile12,
'0000000000000000000000000000000000000013': precompile13,
};

@@ -153,3 +253,3 @@ function getActivePrecompiles(common, customPrecompiles) {

}
export { getActivePrecompiles, getPrecompileName, precompileEntries, precompiles, ripemdPrecompileAddress, };
export { getActivePrecompiles, getPrecompileName, MCLBLS, NobleBLS, precompileEntries, precompiles, ripemdPrecompileAddress, };
//# sourceMappingURL=index.js.map

@@ -8,5 +8,4 @@ import type { EvmError } from './exceptions.js';

import type { PrecompileFunc } from './precompiles/types.js';
import type { Common, EVMStateManagerInterface } from '@ethereumjs/common';
import type { AccessWitness } from '@ethereumjs/statemanager';
import type { Account, Address, AsyncEventEmitter } from '@ethereumjs/util';
import type { AccessWitnessInterface, Common, EVMStateManagerInterface } from '@ethereumjs/common';
import type { Account, Address, AsyncEventEmitter, PrefixedHexString } from '@ethereumjs/util';
export declare type DeleteOpcode = {

@@ -70,3 +69,3 @@ opcode: number;

*/
selfdestruct?: Set<string>;
selfdestruct?: Set<PrefixedHexString>;
/**

@@ -99,3 +98,3 @@ * The address of the account that is executing this code (`address(this)`). Defaults to the zero address.

*/
createdAddresses?: Set<string>;
createdAddresses?: Set<PrefixedHexString>;
/**

@@ -118,3 +117,3 @@ * Skip balance checks if true. If caller balance is less than message value,

message?: Message;
accessWitness?: AccessWitness;
accessWitness?: AccessWitnessInterface;
}

@@ -141,3 +140,3 @@ interface NewContractEvent {

accessList?: Map<string, Set<string>>;
preimages?: Map<string, Uint8Array>;
preimages?: Map<PrefixedHexString, Uint8Array>;
addAlwaysWarmAddress(address: string, addToAccessList?: boolean): void;

@@ -168,7 +167,6 @@ addAlwaysWarmSlot(address: string, slot: string, addToAccessList?: boolean): void;

* - [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559) - Fee market change for ETH 1.0 chain
* - [EIP-2315](https://eips.ethereum.org/EIPS/eip-2315) - Simple subroutines for the EVM (`outdated`)
* - [EIP-2537](https://eips.ethereum.org/EIPS/eip-2537) - BLS precompiles (removed in v4.0.0, see latest v3 release)
* - [EIP-2565](https://eips.ethereum.org/EIPS/eip-2565) - ModExp gas cost
* - [EIP-2718](https://eips.ethereum.org/EIPS/eip-2565) - Transaction Types
* - [EIP-2935](https://eips.ethereum.org/EIPS/eip-2935) - Save historical block hashes in state (`experimental`)
* - [EIP-2935](https://eips.ethereum.org/EIPS/eip-2935) - Serve historical block hashes from state (Prague)
* - [EIP-2929](https://eips.ethereum.org/EIPS/eip-2929) - gas cost increases for state access opcodes

@@ -192,7 +190,13 @@ * - [EIP-2930](https://eips.ethereum.org/EIPS/eip-2930) - Optional access list tx type

* - [EIP-4844](https://eips.ethereum.org/EIPS/eip-4844) - Shard Blob Transactions (Cancun)
* - [EIP-7702](https://eips.ethereum.org/EIPS/eip-7702) - EOA code transactions (Prague) (`outdated`)
* - [EIP-7709](https://eips.ethereum.org/EIPS/eip-7709) - Read BLOCKHASH from storage and update cost (Osaka)
* - [EIP-4895](https://eips.ethereum.org/EIPS/eip-4895) - Beacon chain push withdrawals as operations (Shanghai)
* - [EIP-5133](https://eips.ethereum.org/EIPS/eip-5133) - Delaying Difficulty Bomb to mid-September 2022 (Gray Glacier)
* - [EIP-5656](https://eips.ethereum.org/EIPS/eip-5656) - MCOPY - Memory copying instruction (Cancun)
* - [EIP-6110](https://eips.ethereum.org/EIPS/eip-6110) - Supply validator deposits on chain (Prague)
* - [EIP-6780](https://eips.ethereum.org/EIPS/eip-6780) - SELFDESTRUCT only in same transaction (Cancun)
* - [EIP-7002](https://eips.ethereum.org/EIPS/eip-7002) - Execution layer triggerable withdrawals (Prague)
* - [EIP-7251](https://eips.ethereum.org/EIPS/eip-7251) - Execution layer triggerable validator consolidations (Prague)
* - [EIP-7516](https://eips.ethereum.org/EIPS/eip-7516) - BLOBBASEFEE opcode (Cancun)
* - [EIP-7685](https://eips.ethereum.org/EIPS/eip-7685) - General purpose execution layer requests (Prague)
*

@@ -238,2 +242,23 @@ * *Annotations:*

customPrecompiles?: CustomPrecompile[];
/**
* For the EIP-2537 BLS Precompiles, the native JS `@noble/curves`
* https://github.com/paulmillr/noble-curves BLS12-381 curve implementation
* is used (see `noble.ts` file in the `precompiles` folder).
*
* To use an alternative implementation this option can be used by passing
* in a wrapper implementation integrating the desired library and adhering
* to the `EVMBLSInterface` specification.
*
* An interface for the MCL WASM implementation https://github.com/herumi/mcl-wasm
* is shipped with this library which can be used as follows (with `mcl-wasm` being
* explicitly added to the set of dependencies):
*
* ```ts
* import * as mcl from 'mcl-wasm'
*
* await mcl.init(mcl.BLS12_381)
* const evm = await EVM.create({ bls: new MCLBLS(mcl) })
* ```
*/
bls?: EVMBLSInterface;
stateManager?: EVMStateManagerInterface;

@@ -290,7 +315,7 @@ /**

*/
selfdestruct?: Set<string>;
selfdestruct?: Set<PrefixedHexString>;
/**
* Map of addresses which were created (used in EIP 6780)
*/
createdAddresses?: Set<string>;
createdAddresses?: Set<PrefixedHexString>;
/**

@@ -305,2 +330,14 @@ * The gas refund counter

}
export declare type EVMBLSInterface = {
init?(): void;
addG1(input: Uint8Array): Uint8Array;
mulG1(input: Uint8Array): Uint8Array;
addG2(input: Uint8Array): Uint8Array;
mulG2(input: Uint8Array): Uint8Array;
mapFPtoG1(input: Uint8Array): Uint8Array;
mapFP2toG2(input: Uint8Array): Uint8Array;
msmG1(input: Uint8Array): Uint8Array;
msmG2(input: Uint8Array): Uint8Array;
pairingCheck(input: Uint8Array): Uint8Array;
};
/**

@@ -353,7 +390,7 @@ * Log that the contract emits.

export interface bn128 {
ec_pairing: (input_str: string) => string;
ec_add: (input_str: string) => string;
ec_mul: (input_hex: string) => string;
ec_pairing: (input_str: string) => PrefixedHexString;
ec_add: (input_str: string) => PrefixedHexString;
ec_mul: (input_hex: string) => PrefixedHexString;
}
export {};
//# sourceMappingURL=types.d.ts.map
{
"name": "@ethereumjs/evm",
"version": "3.0.0",
"version": "3.1.0",
"description": "JavaScript Ethereum Virtual Machine (EVM) implementation",

@@ -50,15 +50,17 @@ "keywords": [

"profiling": "0x ./benchmarks/run.js profiling",
"test": "npm run test:node && npm run test:browser",
"test:browser": "npx vitest run -c=vitest.config.browser.ts --browser.provider=playwright --browser.name=webkit --browser.headless",
"test": "npm run test:node",
"test:browser": "npx vitest run --config=./vitest.config.browser.mts",
"test:node": "npx vitest run",
"tsc": "../../config/cli/ts-compile.sh"
"tsc": "../../config/cli/ts-compile.sh",
"visualize:bundle": "npx vite build --config=./vite.config.bundler.ts --emptyOutDir=false --outDir ."
},
"dependencies": {
"@ethereumjs/common": "^4.3.0",
"@ethereumjs/statemanager": "^2.3.0",
"@ethereumjs/tx": "^5.3.0",
"@ethereumjs/util": "^9.0.3",
"@ethereumjs/common": "^4.4.0",
"@ethereumjs/statemanager": "^2.4.0",
"@ethereumjs/tx": "^5.4.0",
"@ethereumjs/util": "^9.1.0",
"@types/debug": "^4.1.9",
"debug": "^4.3.3",
"ethereum-cryptography": "^2.1.3",
"ethereum-cryptography": "^2.2.1",
"@noble/curves": "^1.4.2",
"rustbn-wasm": "^0.4.0"

@@ -72,8 +74,11 @@ },

"@types/node-dir": "^0.0.34",
"@types/rollup-plugin-visualizer": "^4.2.4",
"benchmark": "^2.1.4",
"kzg-wasm": "^0.3.1",
"kzg-wasm": "^0.4.0",
"level": "^8.0.0",
"mcl-wasm": "^1.5.0",
"memory-level": "^1.0.0",
"minimist": "^1.2.5",
"node-dir": "^0.1.17",
"rollup-plugin-visualizer": "^5.12.0",
"solc": "^0.8.1"

@@ -80,0 +85,0 @@ },

@@ -100,2 +100,55 @@ # @ethereumjs/evm

### Precompiles
This library support all EVM precompiles up to the `Prague` hardfork.
The following code allows to run precompiles in isolation, e.g. for testing purposes:
```ts
// ./examples/precompile.ts
import { Chain, Common, Hardfork } from '@ethereumjs/common'
import { EVM, getActivePrecompiles } from '@ethereumjs/evm'
import { bytesToHex, hexToBytes } from '@ethereumjs/util'
const main = async () => {
const common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Prague })
// Taken from test/eips/precompiles/bls/add_G1_bls.json
const data = hexToBytes(
'0x0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e100000000000000000000000000000000112b98340eee2777cc3c14163dea3ec97977ac3dc5c70da32e6e87578f44912e902ccef9efe28d4a78b8999dfbca942600000000000000000000000000000000186b28d92356c4dfec4b5201ad099dbdede3781f8998ddf929b4cd7756192185ca7b8f4ef7088f813270ac3d48868a21'
)
const gasLimit = BigInt(5000000)
const evm = await EVM.create({ common })
const precompile = getActivePrecompiles(common).get('000000000000000000000000000000000000000b')!
const callData = {
data,
gasLimit,
common,
_EVM: evm,
}
const result = await precompile(callData)
console.log(`Precompile result:${bytesToHex(result.returnValue)}`)
}
main()
```
### EIP-2537 BLS Precompiles (Prague)
Starting with `v3.1.0` the EVM support the BLS precompiles introduced with [EIP-2537](https://eips.ethereum.org/EIPS/eip-2537). These precompiles run natively using the [@noble/curves](https://github.com/paulmillr/noble-curves) library (❤️ to `@paulmillr`!).
An alternative WASM implementation (using [bls-wasm](https://github.com/herumi/bls-wasm)) can be optionally used like this if needed for performance reasons:
```ts
import { EVM, MCLBLS } from '@ethereumjs/evm'
const common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Prague })
await mcl.init(mcl.BLS12_381)
const mclbls = new MCLBLS(mcl)
const evm = await EVM.create({ common, bls })
```
## Examples

@@ -222,7 +275,6 @@

- [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559) - Fee market change for ETH 1.0 chain
- [EIP-2315](https://eips.ethereum.org/EIPS/eip-2315) - Simple subroutines for the EVM (`outdated`)
- [EIP-2537](https://eips.ethereum.org/EIPS/eip-2537) - BLS precompiles (removed in v4.0.0, see latest v3 release)
- [EIP-2565](https://eips.ethereum.org/EIPS/eip-2565) - ModExp gas cost
- [EIP-2718](https://eips.ethereum.org/EIPS/eip-2718) - Transaction Types
- [EIP-2935](https://eips.ethereum.org/EIPS/eip-2935) - Save historical block hashes in state (`experimental`)
- [EIP-2935](https://eips.ethereum.org/EIPS/eip-2935) - Serve historical block hashes from state (Prague)
- [EIP-2929](https://eips.ethereum.org/EIPS/eip-2929) - gas cost increases for state access opcodes

@@ -249,4 +301,10 @@ - [EIP-2930](https://eips.ethereum.org/EIPS/eip-2930) - Optional access list tx type

- [EIP-5656](https://eips.ethereum.org/EIPS/eip-5656) - MCOPY - Memory copying instruction (Cancun)
- [EIP-6110](https://eips.ethereum.org/EIPS/eip-6110) - Supply validator deposits on chain (Prague)
- [EIP-6780](https://eips.ethereum.org/EIPS/eip-6780) - SELFDESTRUCT only in same transaction (Cancun)
- [EIP-7002](https://eips.ethereum.org/EIPS/eip-7002) - Execution layer triggerable withdrawals (Prague)
- [EIP-7251](https://eips.ethereum.org/EIPS/eip-7251) - Execution layer triggerable validator consolidations (Prague)
- [EIP-7702](https://eips.ethereum.org/EIPS/eip-7702) - EOA code transactions (Prague) (`outdated`)
- [EIP-7709](https://eips.ethereum.org/EIPS/eip-7709) - Read BLOCKHASH from storage and update cost (Osaka)
- [EIP-7516](https://eips.ethereum.org/EIPS/eip-7516) - BLOBBASEFEE opcode (Cancun)
- [EIP-7685](https://eips.ethereum.org/EIPS/eip-7685) - General purpose execution layer requests (Prague)

@@ -253,0 +311,0 @@ ### WASM Crypto Support

@@ -10,2 +10,3 @@ import { Chain, Common, Hardfork } from '@ethereumjs/common'

KECCAK256_NULL,
KECCAK256_RLP,
MAX_INTEGER,

@@ -30,3 +31,3 @@ bigIntToBytes,

import { getOpcodesForHF } from './opcodes/index.js'
import { getActivePrecompiles, getPrecompileName } from './precompiles/index.js'
import { NobleBLS, getActivePrecompiles, getPrecompileName } from './precompiles/index.js'
import { TransientStorage } from './transientStorage.js'

@@ -45,2 +46,3 @@ import { DefaultBlockchain } from './types.js'

CustomOpcode,
EVMBLSInterface,
EVMEvents,

@@ -56,7 +58,6 @@ EVMInterface,

import type { EVMStateManagerInterface } from '@ethereumjs/common'
const { debug: createDebugLogger } = debugDefault
const debug = createDebugLogger('evm:evm')
const debugGas = createDebugLogger('evm:gas')
const debugPrecompiles = createDebugLogger('evm:precompiles')
const debug = debugDefault('evm:evm')
const debugGas = debugDefault('evm:gas')
const debugPrecompiles = debugDefault('evm:precompiles')

@@ -92,2 +93,3 @@ let initializedRustBN: bn128 | undefined = undefined

Hardfork.Prague,
Hardfork.Osaka,
]

@@ -137,2 +139,4 @@ protected _tx?: {

protected readonly _bls?: EVMBLSInterface
/**

@@ -161,3 +165,3 @@ * EVM is run in DEBUG mode (default: false)

const opts = createOpts ?? ({} as EVMOpts)
const bn128 = initializedRustBN ?? (await initRustBN())
const bn128 = initializedRustBN ?? ((await initRustBN()) as bn128)
initializedRustBN = bn128

@@ -202,4 +206,5 @@

const supportedEIPs = [
1153, 1559, 2315, 2565, 2718, 2929, 2930, 2935, 3074, 3198, 3529, 3540, 3541, 3607, 3651,
3670, 3855, 3860, 4399, 4895, 4788, 4844, 5133, 5656, 6780, 6800, 7516,
1153, 1559, 2537, 2565, 2718, 2929, 2930, 2935, 3074, 3198, 3529, 3540, 3541, 3607, 3651,
3670, 3855, 3860, 4399, 4895, 4788, 4844, 5133, 5656, 6110, 6780, 6800, 7002, 7251, 7516,
7685, 7702, 7709,
]

@@ -236,2 +241,7 @@

if (this.common.isActivatedEIP(2537)) {
this._bls = opts.bls ?? new NobleBLS()
this._bls.init?.()
}
this._emit = async (topic: string, data: any): Promise<void> => {

@@ -264,23 +274,34 @@ return new Promise((resolve) => this.events.emit(topic as keyof EVMEvents, data, resolve))

let gasLimit = message.gasLimit
const fromAddress = message.authcallOrigin ?? message.caller
if (this.common.isActivatedEIP(6800)) {
const sendsValue = message.value !== BIGINT_0
if (message.depth === 0) {
const originAccessGas = message.accessWitness!.touchTxOriginAndComputeGas(
message.authcallOrigin ?? message.caller
)
gasLimit -= originAccessGas
if (gasLimit < BIGINT_0) {
if (this.DEBUG) {
debugGas(`Origin access charged(${originAccessGas}) caused OOG (-> ${gasLimit})`)
}
return { execResult: OOGResult(message.gasLimit) }
} else {
if (this.DEBUG) {
debugGas(`Origin access used (${originAccessGas} gas (-> ${gasLimit}))`)
}
const originAccessGas = message.accessWitness!.touchTxOriginAndComputeGas(fromAddress)
debugGas(`originAccessGas=${originAccessGas} waived off for origin at depth=0`)
const destAccessGas = message.accessWitness!.touchTxTargetAndComputeGas(message.to, {
sendsValue,
})
debugGas(`destAccessGas=${destAccessGas} waived off for target at depth=0`)
}
let callAccessGas = message.accessWitness!.touchAndChargeMessageCall(message.to)
if (sendsValue) {
callAccessGas += message.accessWitness!.touchAndChargeValueTransfer(fromAddress, message.to)
}
gasLimit -= callAccessGas
if (gasLimit < BIGINT_0) {
if (this.DEBUG) {
debugGas(`callAccessGas charged(${callAccessGas}) caused OOG (-> ${gasLimit})`)
}
return { execResult: OOGResult(message.gasLimit) }
} else {
if (this.DEBUG) {
debugGas(`callAccessGas used (${callAccessGas} gas (-> ${gasLimit}))`)
}
}
}
let account = await this.stateManager.getAccount(message.authcallOrigin ?? message.caller)
let account = await this.stateManager.getAccount(fromAddress)
if (!account) {

@@ -299,22 +320,2 @@ account = new Account()

if (this.common.isActivatedEIP(6800)) {
if (message.depth === 0) {
const sendsValue = message.value !== BIGINT_0
const destAccessGas = message.accessWitness!.touchTxExistingAndComputeGas(message.to, {
sendsValue,
})
gasLimit -= destAccessGas
if (gasLimit < BIGINT_0) {
if (this.DEBUG) {
debugGas(`Destination access charged(${destAccessGas}) caused OOG (-> ${gasLimit})`)
}
return { execResult: OOGResult(message.gasLimit) }
} else {
if (this.DEBUG) {
debugGas(`Destination access used (${destAccessGas} gas (-> ${gasLimit}))`)
}
}
}
}
// Load `to` account

@@ -421,15 +422,8 @@ let toAccount = await this.stateManager.getAccount(message.to)

let gasLimit = message.gasLimit
const fromAddress = message.authcallOrigin ?? message.caller
if (this.common.isActivatedEIP(6800)) {
const originAccessGas = message.accessWitness!.touchTxOriginAndComputeGas(message.caller)
gasLimit -= originAccessGas
if (gasLimit < BIGINT_0) {
if (this.DEBUG) {
debugGas(`Origin access charged(${originAccessGas}) caused OOG (-> ${gasLimit})`)
}
return { execResult: OOGResult(message.gasLimit) }
} else {
if (this.DEBUG) {
debugGas(`Origin access used (${originAccessGas} gas (-> ${gasLimit}))`)
}
if (message.depth === 0) {
const originAccessGas = message.accessWitness!.touchTxOriginAndComputeGas(fromAddress)
debugGas(`originAccessGas=${originAccessGas} waived off for origin at depth=0`)
}

@@ -478,6 +472,4 @@ }

if (this.common.isActivatedEIP(6800)) {
const sendsValue = message.value !== BIGINT_0
const contractCreateAccessGas = message.accessWitness!.touchAndChargeContractCreateInit(
message.to,
{ sendsValue }
message.to
)

@@ -488,3 +480,3 @@ gasLimit -= contractCreateAccessGas

debugGas(
`Contract create (sendsValue=${sendsValue}) charge(${contractCreateAccessGas}) caused OOG (-> ${gasLimit})`
`ContractCreateInit charge(${contractCreateAccessGas}) caused OOG (-> ${gasLimit})`
)

@@ -495,5 +487,3 @@ }

if (this.DEBUG) {
debugGas(
`Contract create (sendsValue=${sendsValue}) charged (${contractCreateAccessGas} gas (-> ${gasLimit}))`
)
debugGas(`ContractCreateInit charged (${contractCreateAccessGas} gas (-> ${gasLimit}))`)
}

@@ -506,3 +496,5 @@ }

(toAccount.nonce && toAccount.nonce > BIGINT_0) ||
!(equalsBytes(toAccount.codeHash, KECCAK256_NULL) === true)
!(equalsBytes(toAccount.codeHash, KECCAK256_NULL) === true) ||
// See EIP 7610 and the discussion `https://ethereum-magicians.org/t/eip-7610-revert-creation-in-case-of-non-empty-storage`
!(equalsBytes(toAccount.storageRoot, KECCAK256_RLP) === true)
) {

@@ -565,3 +557,22 @@ if (this.DEBUG) {

}
if (exit) {
if (this.common.isActivatedEIP(6800)) {
const createCompleteAccessGas =
message.accessWitness!.touchAndChargeContractCreateCompleted(message.to)
gasLimit -= createCompleteAccessGas
if (gasLimit < BIGINT_0) {
if (this.DEBUG) {
debug(
`ContractCreateComplete access gas (${createCompleteAccessGas}) caused OOG (-> ${gasLimit})`
)
}
return { execResult: OOGResult(message.gasLimit) }
} else {
debug(
`ContractCreateComplete access used (${createCompleteAccessGas}) gas (-> ${gasLimit})`
)
}
}
return {

@@ -589,3 +600,3 @@ createdAddress: message.to,

let returnFee = BIGINT_0
if (!result.exceptionError) {
if (!result.exceptionError && !this.common.isActivatedEIP(6800)) {
returnFee =

@@ -711,3 +722,3 @@ BigInt(result.returnValue.length) * BigInt(this.common.param('gasPrices', 'createData'))

0,
message.code!.length - 1
result.returnValue.length - 1
)

@@ -723,5 +734,3 @@ gasLimit -= byteCodeWriteAccessfee

} else {
debug(
`ContractCreateComplete access used (${byteCodeWriteAccessfee}) gas (-> ${gasLimit})`
)
debug(`byteCodeWrite access used (${byteCodeWriteAccessfee}) gas (-> ${gasLimit})`)
result.executionGasUsed += byteCodeWriteAccessfee

@@ -910,3 +919,3 @@ }

if (!message.to && this.common.isActivatedEIP(2929) === true) {
if (!message.to && this.common.isActivatedEIP(2929)) {
message.code = message.data

@@ -913,0 +922,0 @@ this.journal.addWarmedAddress((await this._generateAddress(message)).bytes)

@@ -27,4 +27,2 @@ export enum ERROR {

AUTHCALL_UNSET = 'attempting to AUTHCALL without AUTH set',
AUTHCALL_NONZERO_VALUEEXT = 'attempting to execute AUTHCALL with nonzero external value',
AUTH_INVALID_S = 'invalid Signature: s-values greater than secp256k1n/2 are considered invalid',

@@ -31,0 +29,0 @@ // BLS errors

import { EOF } from './eof.js'
import { EVM } from './evm.js'
import { ERROR as EVMErrorMessage, EvmError } from './exceptions.js'
import { InterpreterStep } from './interpreter.js'
import { Message } from './message.js'
import { getOpcodesForHF } from './opcodes/index.js'
import { PrecompileInput, getActivePrecompiles } from './precompiles/index.js'
import {
MCLBLS,
NobleBLS,
type PrecompileInput,
getActivePrecompiles,
} from './precompiles/index.js'
import type { InterpreterStep } from './interpreter.js'
import type {
EVMInterface,
EVMOpts,
EVMResult,

@@ -17,9 +24,8 @@ EVMRunCallOpts,

} from './types.js'
export {
export * from './logger.js'
export type {
bn128,
EOF,
EVM,
EvmError,
EVMErrorMessage,
EVMInterface,
EVMOpts,
EVMResult,

@@ -29,8 +35,17 @@ EVMRunCallOpts,

ExecResult,
getActivePrecompiles,
getOpcodesForHF,
InterpreterStep,
Log,
Message,
PrecompileInput,
}
export {
EOF,
EVM,
EvmError,
EVMErrorMessage,
getActivePrecompiles,
getOpcodesForHF,
MCLBLS,
Message,
NobleBLS,
}
import { ConsensusAlgorithm } from '@ethereumjs/common'
import { StatelessVerkleStateManager } from '@ethereumjs/statemanager'
import {

@@ -27,8 +26,6 @@ Account,

import type { Block, Blockchain, EVMProfilerOpts, EVMResult, Log } from './types.js'
import type { Common, EVMStateManagerInterface } from '@ethereumjs/common'
import type { AccessWitness } from '@ethereumjs/statemanager'
import type { Address } from '@ethereumjs/util'
const { debug: createDebugLogger } = debugDefault
import type { AccessWitnessInterface, Common, EVMStateManagerInterface } from '@ethereumjs/common'
import type { Address, PrefixedHexString } from '@ethereumjs/util'
const debugGas = createDebugLogger('evm:gas')
const debugGas = debugDefault('evm:gas')

@@ -48,3 +45,3 @@ export interface InterpreterOpts {

*/
selfdestruct: Set<string>
selfdestruct: Set<PrefixedHexString>

@@ -54,3 +51,3 @@ /**

*/
createdAddresses?: Set<string>
createdAddresses?: Set<PrefixedHexString>
}

@@ -75,3 +72,3 @@

createdAddresses?: Set<string>
accessWitness?: AccessWitness
accessWitness?: AccessWitnessInterface
chargeCodeAccesses?: boolean

@@ -87,3 +84,2 @@ }

stack: Stack
returnStack: Stack
code: Uint8Array

@@ -114,3 +110,2 @@ shouldDoJumpAnalysis: boolean

stack: bigint[]
returnStack: bigint[]
pc: number

@@ -174,3 +169,2 @@ depth: number

stack: new Stack(),
returnStack: new Stack(1023), // 1023 return stack height limit per EIP 2315 spec
code: new Uint8Array(0),

@@ -280,10 +274,9 @@ validJumps: Uint8Array.from([]),

this.common.isActivatedEIP(6800) &&
this._runState.stateManager instanceof StatelessVerkleStateManager
// is this a code loaded from state using witnesses
this._runState.env.chargeCodeAccesses === true
) {
const contract = this._runState.interpreter.getAddress()
if (
!(this._runState.stateManager as StatelessVerkleStateManager).checkChunkWitnessPresent(
contract,
programCounter
)
!(await this._runState.stateManager.checkChunkWitnessPresent!(contract, programCounter))
) {

@@ -424,3 +417,2 @@ throw Error(`Invalid witness with missing codeChunk for pc=${programCounter}`)

stack: this._runState.stack.getStack(),
returnStack: this._runState.returnStack.getStack(),
depth: this._env.depth,

@@ -454,3 +446,3 @@ address: this._env.address,

if (!(name in this.opDebuggers)) {
this.opDebuggers[name] = createDebugLogger(`evm:ops:${name}`)
this.opDebuggers[name] = debugDefault(`evm:ops:${name}`)
}

@@ -506,5 +498,2 @@ this.opDebuggers[name](JSON.stringify(opTrace))

jumps[i] = 1
} else if (opcode === 0x5c) {
// Define a BEGINSUB as a 2 in the valid jumps array
jumps[i] = 2
}

@@ -867,2 +856,3 @@ }

blobVersionedHashes: this._env.blobVersionedHashes,
accessWitness: this._env.accessWitness,
})

@@ -892,2 +882,3 @@

blobVersionedHashes: this._env.blobVersionedHashes,
accessWitness: this._env.accessWitness,
})

@@ -917,2 +908,3 @@

blobVersionedHashes: this._env.blobVersionedHashes,
accessWitness: this._env.accessWitness,
})

@@ -943,2 +935,3 @@

blobVersionedHashes: this._env.blobVersionedHashes,
accessWitness: this._env.accessWitness,
})

@@ -970,2 +963,3 @@

blobVersionedHashes: this._env.blobVersionedHashes,
accessWitness: this._env.accessWitness,
})

@@ -983,3 +977,3 @@

this._runState.returnBytes = new Uint8Array(0)
let createdAddresses: Set<string>
let createdAddresses: Set<PrefixedHexString>
if (this.common.isActivatedEIP(6780)) {

@@ -1092,5 +1086,6 @@ createdAddresses = new Set(this._result.createdAddresses)

blobVersionedHashes: this._env.blobVersionedHashes,
accessWitness: this._env.accessWitness,
})
let createdAddresses: Set<string>
let createdAddresses: Set<PrefixedHexString>
if (this.common.isActivatedEIP(6780)) {

@@ -1097,0 +1092,0 @@ createdAddresses = new Set(this._result.createdAddresses)

@@ -5,18 +5,15 @@ import { Hardfork } from '@ethereumjs/common'

RIPEMD160_ADDRESS_STRING,
bigIntToHex,
bytesToHex,
bytesToUnprefixedHex,
stripHexPrefix,
toBytes,
unprefixedHexToBytes,
} from '@ethereumjs/util'
import debugDefault from 'debug'
import { hexToBytes } from 'ethereum-cryptography/utils'
import type { Common, EVMStateManagerInterface } from '@ethereumjs/common'
import type { Account } from '@ethereumjs/util'
import type { Account, PrefixedHexString } from '@ethereumjs/util'
import type { Debugger } from 'debug'
const { debug: createDebugLogger } = debugDefault
type AddressString = string
type HashString = string
type SlotString = string

@@ -52,3 +49,3 @@ type WarmSlots = Set<SlotString>

public accessList?: Map<AddressString, Set<SlotString>>
public preimages?: Map<HashString, Uint8Array>
public preimages?: Map<PrefixedHexString, Uint8Array>

@@ -61,3 +58,3 @@ constructor(stateManager: EVMStateManagerInterface, common: Common) {

this._debug = createDebugLogger('statemanager:statemanager')
this._debug = debugDefault('statemanager:statemanager')

@@ -200,14 +197,7 @@ // TODO maybe call into this.clearJournal

async cleanup(): Promise<void> {
if (this.common.gteHardfork(Hardfork.SpuriousDragon) === true) {
if (this.common.gteHardfork(Hardfork.SpuriousDragon)) {
for (const addressHex of this.touched) {
const address = new Address(toBytes('0x' + addressHex))
const address = new Address(hexToBytes(`0x${addressHex}`))
const account = await this.stateManager.getAccount(address)
if (account === undefined || account.isEmpty()) {
if (this.common.isActivatedEIP(2935)) {
// The history storage address is exempt of state clearing by EIP-158 if the EIP is activated
const addr = bigIntToHex(this.common.param('vm', 'historyStorageAddress')).slice(2)
if (addressHex === addr) {
continue
}
}
await this.deleteAccount(address)

@@ -214,0 +204,0 @@ if (this.DEBUG) {

import { Address, BIGINT_0 } from '@ethereumjs/util'
import type { PrecompileFunc } from './precompiles/index.js'
import type { AccessWitness } from '@ethereumjs/statemanager'
import type { AccessWitnessInterface } from '@ethereumjs/common'
import type { PrefixedHexString } from '@ethereumjs/util'

@@ -32,7 +33,7 @@ const defaults = {

*/
selfdestruct?: Set<string>
selfdestruct?: Set<PrefixedHexString>
/**
* Map of addresses which were created (used in EIP 6780)
*/
createdAddresses?: Set<string>
createdAddresses?: Set<PrefixedHexString>
delegatecall?: boolean

@@ -42,3 +43,3 @@ authcallOrigin?: Address

blobVersionedHashes?: Uint8Array[]
accessWitness?: AccessWitness
accessWitness?: AccessWitnessInterface
}

@@ -63,7 +64,7 @@

*/
selfdestruct?: Set<string>
selfdestruct?: Set<PrefixedHexString>
/**
* Map of addresses which were created (used in EIP 6780)
*/
createdAddresses?: Set<string>
createdAddresses?: Set<PrefixedHexString>
delegatecall: boolean

@@ -80,3 +81,3 @@ /**

blobVersionedHashes?: Uint8Array[]
accessWitness?: AccessWitness
accessWitness?: AccessWitnessInterface

@@ -83,0 +84,0 @@ constructor(opts: MessageOpts) {

@@ -278,10 +278,2 @@ import { Hardfork } from '@ethereumjs/common'

{
eip: 2315,
opcodes: {
0x5c: { name: 'BEGINSUB', isAsync: false, dynamicGas: false },
0x5d: { name: 'RETURNSUB', isAsync: false, dynamicGas: false },
0x5e: { name: 'JUMPSUB', isAsync: false, dynamicGas: false },
},
},
{
eip: 3198,

@@ -288,0 +280,0 @@ opcodes: {

@@ -23,3 +23,3 @@ import { BIGINT_0 } from '@ethereumjs/util'

): bigint {
if (common.isActivatedEIP(2929) === false) return BIGINT_0
if (!common.isActivatedEIP(2929)) return BIGINT_0

@@ -32,3 +32,4 @@ // Cold

// selfdestruct beneficiary address reads are charged an *additional* cold access
if (chargeGas) {
// if verkle not activated
if (chargeGas && !common.isActivatedEIP(6800)) {
return common.param('gasPrices', 'coldaccountaccess')

@@ -55,5 +56,6 @@ }

isSstore: boolean,
common: Common
common: Common,
chargeGas = true
): bigint {
if (common.isActivatedEIP(2929) === false) return BIGINT_0
if (!common.isActivatedEIP(2929)) return BIGINT_0

@@ -66,4 +68,6 @@ const address = runState.interpreter.getAddress().bytes

runState.interpreter.journal.addWarmedStorage(address, key)
return common.param('gasPrices', 'coldsload')
} else if (!isSstore) {
if (chargeGas && !common.isActivatedEIP(6800)) {
return common.param('gasPrices', 'coldsload')
}
} else if (chargeGas && (!isSstore || common.isActivatedEIP(6800))) {
return common.param('gasPrices', 'warmstorageread')

@@ -91,3 +95,3 @@ }

): bigint {
if (common.isActivatedEIP(2929) === false) return defaultCost
if (!common.isActivatedEIP(2929)) return defaultCost

@@ -94,0 +98,0 @@ const address = runState.interpreter.getAddress().bytes

import {
Account,
Address,
BIGINT_0,
BIGINT_1,
BIGINT_128,
BIGINT_160,

@@ -23,4 +23,4 @@ BIGINT_2,

TWO_POW256,
bigIntToAddressBytes,
bigIntToBytes,
bigIntToHex,
bytesToBigInt,

@@ -30,2 +30,3 @@ bytesToHex,

ecrecover,
getVerkleTreeIndexesForStorageSlot,
hexToBytes,

@@ -47,3 +48,2 @@ publicToAddress,

jumpIsValid,
jumpSubIsValid,
mod,

@@ -58,3 +58,3 @@ toTwos,

const EIP3074MAGIC = hexToBytes('0x03')
const EIP3074MAGIC = hexToBytes('0x04')

@@ -525,6 +525,17 @@ export interface SyncOpHandler {

const addressBigInt = runState.stack.pop()
const size = BigInt(
(await runState.stateManager.getContractCode(new Address(addresstoBytes(addressBigInt))))
.length
)
let size
if (typeof runState.stateManager.getContractCodeSize === 'function') {
size = BigInt(
await runState.stateManager.getContractCodeSize(
new Address(addresstoBytes(addressBigInt))
)
)
} else {
size = BigInt(
(await runState.stateManager.getContractCode(new Address(addresstoBytes(addressBigInt))))
.length
)
}
runState.stack.push(size)

@@ -605,3 +616,3 @@ },

if (common.isActivatedEIP(2935)) {
if (common.isActivatedEIP(7709)) {
if (number >= runState.interpreter.getBlockNumber()) {

@@ -613,5 +624,5 @@ runState.stack.push(BIGINT_0)

const diff = runState.interpreter.getBlockNumber() - number
const historyServeWindow = common.param('vm', 'historyServeWindow')
// block lookups must be within the `historyServeWindow`
if (diff > historyServeWindow || diff <= BIGINT_0) {
// block lookups must be within the original window even if historyStorageAddress's
// historyServeWindow is much greater than 256
if (diff > BIGINT_256 || diff <= BIGINT_0) {
runState.stack.push(BIGINT_0)

@@ -621,7 +632,18 @@ return

const historyAddress = Address.fromString(
bigIntToHex(common.param('vm', 'historyStorageAddress'))
const historyAddress = new Address(
bigIntToAddressBytes(common.param('vm', 'historyStorageAddress'))
)
const historyServeWindow = common.param('vm', 'historyServeWindow')
const key = setLengthLeft(bigIntToBytes(number % historyServeWindow), 32)
if (common.isActivatedEIP(6800)) {
const { treeIndex, subIndex } = getVerkleTreeIndexesForStorageSlot(number)
// create witnesses and charge gas
const statelessGas = runState.env.accessWitness!.touchAddressOnReadAndComputeGas(
historyAddress,
treeIndex,
subIndex
)
runState.interpreter.useGas(statelessGas, `BLOCKHASH`)
}
const storage = await runState.stateManager.getContractStorage(historyAddress, key)

@@ -851,77 +873,42 @@

[0x5b, function () {}],
// 0x5c: BEGINSUB (EIP 2315) / TLOAD (EIP 1153)
// 0x5c: TLOAD (EIP 1153)
[
0x5c,
function (runState, common) {
if (common.isActivatedEIP(2315)) {
// BEGINSUB
trap(ERROR.INVALID_BEGINSUB + ' at ' + describeLocation(runState))
} else if (common.isActivatedEIP(1153)) {
// TLOAD
const key = runState.stack.pop()
const keyBuf = setLengthLeft(bigIntToBytes(key), 32)
const value = runState.interpreter.transientStorageLoad(keyBuf)
const valueBN = value.length ? bytesToBigInt(value) : BIGINT_0
runState.stack.push(valueBN)
}
function (runState) {
const key = runState.stack.pop()
const keyBuf = setLengthLeft(bigIntToBytes(key), 32)
const value = runState.interpreter.transientStorageLoad(keyBuf)
const valueBN = value.length ? bytesToBigInt(value) : BIGINT_0
runState.stack.push(valueBN)
},
],
// 0x5d: RETURNSUB (EIP 2315) / TSTORE (EIP 1153)
// 0x5d: TSTORE (EIP 1153)
[
0x5d,
function (runState, common) {
if (common.isActivatedEIP(2315)) {
// RETURNSUB
if (runState.returnStack.length < 1) {
trap(ERROR.INVALID_RETURNSUB)
}
function (runState) {
// TSTORE
if (runState.interpreter.isStatic()) {
trap(ERROR.STATIC_STATE_CHANGE)
}
const [key, val] = runState.stack.popN(2)
const dest = runState.returnStack.pop()
runState.programCounter = Number(dest)
} else if (common.isActivatedEIP(1153)) {
// TSTORE
if (runState.interpreter.isStatic()) {
trap(ERROR.STATIC_STATE_CHANGE)
}
const [key, val] = runState.stack.popN(2)
const keyBuf = setLengthLeft(bigIntToBytes(key), 32)
// NOTE: this should be the shortest representation
let value
if (val === BIGINT_0) {
value = Uint8Array.from([])
} else {
value = bigIntToBytes(val)
}
const keyBuf = setLengthLeft(bigIntToBytes(key), 32)
// NOTE: this should be the shortest representation
let value
if (val === BIGINT_0) {
value = Uint8Array.from([])
} else {
value = bigIntToBytes(val)
}
runState.interpreter.transientStorageStore(keyBuf, value)
}
runState.interpreter.transientStorageStore(keyBuf, value)
},
],
// 0x5e: JUMPSUB (2315) / MCOPY (5656)
// 0x5e: MCOPY (5656)
[
0x5e,
function (runState, common) {
if (common.isActivatedEIP(2315)) {
// JUMPSUB
const dest = runState.stack.pop()
if (dest > runState.interpreter.getCodeSize()) {
trap(ERROR.INVALID_JUMPSUB + ' at ' + describeLocation(runState))
}
const destNum = Number(dest)
if (!jumpSubIsValid(runState, destNum)) {
trap(ERROR.INVALID_JUMPSUB + ' at ' + describeLocation(runState))
}
runState.returnStack.push(BigInt(runState.programCounter))
runState.programCounter = destNum + 1
} else if (common.isActivatedEIP(5656)) {
// MCOPY
const [dst, src, length] = runState.stack.popN(3)
const data = runState.memory.read(Number(src), Number(length), true)
runState.memory.write(Number(dst), Number(length), data)
}
function (runState) {
const [dst, src, length] = runState.stack.popN(3)
const data = runState.memory.read(Number(src), Number(length), true)
runState.memory.write(Number(dst), Number(length), data)
},

@@ -1157,23 +1144,44 @@ ],

if (memLength > BIGINT_128) {
memLength = BIGINT_128
if (memLength > BigInt(97)) {
memLength = BigInt(97)
}
let mem = runState.memory.read(Number(memOffset), Number(memLength))
if (mem.length < 128) {
mem = setLengthRight(mem, 128)
if (mem.length < 97) {
mem = setLengthRight(mem, 97)
}
const yParity = BigInt(mem[31])
const r = mem.subarray(32, 64)
const s = mem.subarray(64, 96)
const commit = mem.subarray(96, 128)
const yParity = BigInt(mem[0])
const r = mem.subarray(1, 33)
const s = mem.subarray(33, 65)
const commit = mem.subarray(65, 97)
if (bytesToBigInt(s) > SECP256K1_ORDER_DIV_2) {
trap(ERROR.AUTH_INVALID_S)
runState.stack.push(BIGINT_0)
runState.auth = undefined
return
}
if (yParity > BIGINT_1) {
runState.stack.push(BIGINT_0)
runState.auth = undefined
return
}
const paddedInvokerAddress = setLengthLeft(runState.interpreter._env.address.bytes, 32)
// we don't want strick check here on authority being in address range just last 20 bytes
const expectedAddress = new Address(bigIntToAddressBytes(authority, false))
const account = (await runState.stateManager.getAccount(expectedAddress)) ?? new Account()
if (account.isContract()) {
// EXTCODESIZE > 0
runState.stack.push(BIGINT_0)
runState.auth = undefined
return
}
const accountNonce = account.nonce
const invokedAddress = setLengthLeft(runState.interpreter._env.address.bytes, 32)
const chainId = setLengthLeft(bigIntToBytes(runState.interpreter.getChainId()), 32)
const message = concatBytes(EIP3074MAGIC, chainId, paddedInvokerAddress, commit)
const nonce = setLengthLeft(bigIntToBytes(accountNonce), 32)
const message = concatBytes(EIP3074MAGIC, chainId, nonce, invokedAddress, commit)

@@ -1198,4 +1206,2 @@ const keccakFunction = runState.interpreter._evm.common.customCrypto.keccak256 ?? keccak256

const expectedAddress = new Address(setLengthLeft(bigIntToBytes(authority), 20))
if (!expectedAddress.equals(address)) {

@@ -1216,12 +1222,4 @@ // expected address does not equal the recovered address, clear auth variable

async function (runState) {
const [
_currentGasLimit,
addr,
value,
_valueExt,
argsOffset,
argsLength,
retOffset,
retLength,
] = runState.stack.popN(8)
const [_currentGasLimit, addr, value, argsOffset, argsLength, retOffset, retLength] =
runState.stack.popN(7)

@@ -1228,0 +1226,0 @@ const toAddress = new Address(addresstoBytes(addr))

import { Hardfork } from '@ethereumjs/common'
import { CODE_SIZE_LEAF_KEY, getTreeIndexesForStorageSlot } from '@ethereumjs/statemanager'
import {
Account,
Address,

@@ -10,3 +10,8 @@ BIGINT_0,

BIGINT_32,
VERKLE_BALANCE_LEAF_KEY,
VERKLE_CODE_HASH_LEAF_KEY,
VERKLE_CODE_SIZE_LEAF_KEY,
VERKLE_VERSION_LEAF_KEY,
bigIntToBytes,
getVerkleTreeIndexesForStorageSlot,
setLengthLeft,

@@ -86,6 +91,20 @@ } from '@ethereumjs/util'

async function (runState, gas, common): Promise<bigint> {
if (common.isActivatedEIP(2929) === true) {
const address = runState.stack.peek()[0]
gas += accessAddressEIP2929(runState, addresstoBytes(address), common)
const address = addresstoBytes(runState.stack.peek()[0])
let charge2929Gas = true
if (common.isActivatedEIP(6800)) {
const balanceAddress = new Address(address)
const coldAccessGas = runState.env.accessWitness!.touchAddressOnReadAndComputeGas(
balanceAddress,
0,
VERKLE_BALANCE_LEAF_KEY
)
gas += coldAccessGas
charge2929Gas = coldAccessGas === BIGINT_0
}
if (common.isActivatedEIP(2929)) {
gas += accessAddressEIP2929(runState, address, common, charge2929Gas)
}
return gas

@@ -117,3 +136,3 @@ },

if (common.isActivatedEIP(6800)) {
if (common.isActivatedEIP(6800) && runState.env.chargeCodeAccesses === true) {
const contract = runState.interpreter.getAddress()

@@ -140,16 +159,31 @@ let codeEnd = _codeOffset + dataLength

async function (runState, gas, common): Promise<bigint> {
if (common.isActivatedEIP(2929) === true) {
const address = runState.stack.peek()[0]
gas += accessAddressEIP2929(runState, addresstoBytes(address), common)
}
const addressBytes = addresstoBytes(runState.stack.peek()[0])
const address = new Address(addressBytes)
if (common.isActivatedEIP(6800) === true) {
const address = new Address(addresstoBytes(runState.stack.peek()[0]))
gas += runState.env.accessWitness!.touchAddressOnReadAndComputeGas(
let charge2929Gas = true
if (
common.isActivatedEIP(6800) &&
runState.interpreter._evm.getPrecompile(address) === undefined
) {
let coldAccessGas = BIGINT_0
coldAccessGas += runState.env.accessWitness!.touchAddressOnReadAndComputeGas(
address,
0,
CODE_SIZE_LEAF_KEY
VERKLE_VERSION_LEAF_KEY
)
coldAccessGas += runState.env.accessWitness!.touchAddressOnReadAndComputeGas(
address,
0,
VERKLE_CODE_SIZE_LEAF_KEY
)
gas += coldAccessGas
// if cold access gas has been charged 2929 gas shouldn't be charged
charge2929Gas = coldAccessGas === BIGINT_0
}
if (common.isActivatedEIP(2929)) {
gas += accessAddressEIP2929(runState, addressBytes, common, charge2929Gas)
}
return gas

@@ -162,10 +196,34 @@ },

async function (runState, gas, common): Promise<bigint> {
const [address, memOffset, _codeOffset, dataLength] = runState.stack.peek(4)
const [addressBigInt, memOffset, _codeOffset, dataLength] = runState.stack.peek(4)
const addressBytes = addresstoBytes(addressBigInt)
const address = new Address(addressBytes)
gas += subMemUsage(runState, memOffset, dataLength, common)
if (common.isActivatedEIP(2929) === true) {
gas += accessAddressEIP2929(runState, addresstoBytes(address), common)
let charge2929Gas = true
if (
common.isActivatedEIP(6800) &&
runState.interpreter._evm.getPrecompile(address) === undefined
) {
let coldAccessGas = BIGINT_0
coldAccessGas += runState.env.accessWitness!.touchAddressOnReadAndComputeGas(
address,
0,
VERKLE_VERSION_LEAF_KEY
)
coldAccessGas += runState.env.accessWitness!.touchAddressOnReadAndComputeGas(
address,
0,
VERKLE_CODE_SIZE_LEAF_KEY
)
gas += coldAccessGas
// if cold access gas has been charged 2929 gas shouldn't be charged
charge2929Gas = coldAccessGas === BIGINT_0
}
if (common.isActivatedEIP(2929)) {
gas += accessAddressEIP2929(runState, addressBytes, common, charge2929Gas)
}
if (dataLength !== BIGINT_0) {

@@ -175,5 +233,4 @@ gas += common.param('gasPrices', 'copy') * divCeil(dataLength, BIGINT_32)

if (common.isActivatedEIP(6800)) {
const contract = new Address(addresstoBytes(address))
let codeEnd = _codeOffset + dataLength
const codeSize = BigInt((await runState.stateManager.getContractCode(contract)).length)
const codeSize = BigInt((await runState.stateManager.getContractCode(address)).length)
if (codeEnd > codeSize) {

@@ -184,3 +241,3 @@ codeEnd = codeSize

gas += runState.env.accessWitness!.touchCodeChunksRangeOnReadAndChargeGas(
contract,
address,
Number(_codeOffset),

@@ -216,6 +273,23 @@ Number(codeEnd)

async function (runState, gas, common): Promise<bigint> {
if (common.isActivatedEIP(2929) === true) {
const address = runState.stack.peek()[0]
gas += accessAddressEIP2929(runState, addresstoBytes(address), common)
const address = addresstoBytes(runState.stack.peek()[0])
let charge2929Gas = true
if (common.isActivatedEIP(6800)) {
const codeAddress = new Address(address)
let coldAccessGas = BIGINT_0
coldAccessGas += runState.env.accessWitness!.touchAddressOnReadAndComputeGas(
codeAddress,
0,
VERKLE_CODE_HASH_LEAF_KEY
)
gas += coldAccessGas
charge2929Gas = coldAccessGas === BIGINT_0
}
if (common.isActivatedEIP(2929)) {
gas += accessAddressEIP2929(runState, address, common, charge2929Gas)
}
return gas

@@ -258,10 +332,7 @@ },

if (common.isActivatedEIP(2929) === true) {
gas += accessStorageEIP2929(runState, keyBuf, false, common)
}
if (common.isActivatedEIP(6800) === true) {
let charge2929Gas = true
if (common.isActivatedEIP(6800)) {
const address = runState.interpreter.getAddress()
const { treeIndex, subIndex } = getTreeIndexesForStorageSlot(key)
gas += runState.env.accessWitness!.touchAddressOnReadAndComputeGas(
const { treeIndex, subIndex } = getVerkleTreeIndexesForStorageSlot(key)
const coldAccessGas = runState.env.accessWitness!.touchAddressOnReadAndComputeGas(
address,

@@ -271,3 +342,11 @@ treeIndex,

)
gas += coldAccessGas
charge2929Gas = coldAccessGas === BIGINT_0
}
if (common.isActivatedEIP(2929)) {
gas += accessStorageEIP2929(runState, keyBuf, false, common, charge2929Gas)
}
return gas

@@ -309,10 +388,12 @@ },

} else if (common.gteHardfork(Hardfork.Istanbul)) {
gas += updateSstoreGasEIP2200(
runState,
currentStorage,
originalStorage,
setLengthLeftStorage(value),
keyBytes,
common
)
if (!common.isActivatedEIP(6800)) {
gas += updateSstoreGasEIP2200(
runState,
currentStorage,
originalStorage,
setLengthLeftStorage(value),
keyBytes,
common
)
}
} else {

@@ -322,13 +403,7 @@ gas += updateSstoreGas(runState, currentStorage, setLengthLeftStorage(value), common)

if (common.isActivatedEIP(2929) === true) {
// We have to do this after the Istanbul (EIP2200) checks.
// Otherwise, we might run out of gas, due to "sentry check" of 2300 gas,
// if we deduct extra gas first.
gas += accessStorageEIP2929(runState, keyBytes, true, common)
}
if (common.isActivatedEIP(6800) === true) {
let charge2929Gas = true
if (common.isActivatedEIP(6800)) {
const contract = runState.interpreter.getAddress()
const { treeIndex, subIndex } = getTreeIndexesForStorageSlot(key)
gas += runState.env.accessWitness!.touchAddressOnWriteAndComputeGas(
const { treeIndex, subIndex } = getVerkleTreeIndexesForStorageSlot(key)
const coldAccessGas = runState.env.accessWitness!.touchAddressOnWriteAndComputeGas(
contract,

@@ -338,3 +413,14 @@ treeIndex,

)
gas += coldAccessGas
charge2929Gas = coldAccessGas === BIGINT_0
}
if (common.isActivatedEIP(2929)) {
// We have to do this after the Istanbul (EIP2200) checks.
// Otherwise, we might run out of gas, due to "sentry check" of 2300 gas,
// if we deduct extra gas first.
gas += accessStorageEIP2929(runState, keyBytes, true, common, charge2929Gas)
}
return gas

@@ -387,3 +473,3 @@ },

if (common.isActivatedEIP(2929) === true) {
if (common.isActivatedEIP(2929)) {
gas += accessAddressEIP2929(

@@ -397,3 +483,3 @@ runState,

if (common.isActivatedEIP(3860) === true) {
if (common.isActivatedEIP(3860)) {
gas += ((length + BIGINT_31) / BIGINT_32) * common.param('gasPrices', 'initCodeWordCost')

@@ -424,7 +510,27 @@ }

gas += subMemUsage(runState, outOffset, outLength, common)
if (common.isActivatedEIP(2929) === true) {
gas += accessAddressEIP2929(runState, toAddress.bytes, common)
let charge2929Gas = true
if (
common.isActivatedEIP(6800) &&
runState.interpreter._evm.getPrecompile(toAddress) === undefined
) {
// TODO: add check if toAddress is not a precompile
const coldAccessGas = runState.env.accessWitness!.touchAndChargeMessageCall(toAddress)
if (value !== BIGINT_0) {
const contractAddress = runState.interpreter.getAddress()
gas += runState.env.accessWitness!.touchAndChargeValueTransfer(
contractAddress,
toAddress
)
}
gas += coldAccessGas
charge2929Gas = coldAccessGas === BIGINT_0
}
if (value !== BIGINT_0) {
if (common.isActivatedEIP(2929)) {
gas += accessAddressEIP2929(runState, toAddress.bytes, common, charge2929Gas)
}
if (value !== BIGINT_0 && !common.isActivatedEIP(6800)) {
gas += common.param('gasPrices', 'callValueTransfer')

@@ -452,14 +558,2 @@ }

if (common.isActivatedEIP(6800)) {
// TODO: add check if toAddress is not a precompile
gas += runState.env.accessWitness!.touchAndChargeMessageCall(toAddress)
if (value !== BIGINT_0) {
const contractAddress = runState.interpreter.getAddress()
gas += runState.env.accessWitness!.touchAndChargeValueTransfer(
contractAddress,
toAddress
)
}
}
const gasLimit = maxCallGas(

@@ -491,2 +585,3 @@ currentGasLimit,

runState.stack.peek(7)
const toAddress = new Address(addresstoBytes(toAddr))

@@ -496,6 +591,17 @@ gas += subMemUsage(runState, inOffset, inLength, common)

if (common.isActivatedEIP(2929) === true) {
gas += accessAddressEIP2929(runState, addresstoBytes(toAddr), common)
let charge2929Gas = true
if (
common.isActivatedEIP(6800) &&
runState.interpreter._evm.getPrecompile(toAddress) === undefined
) {
const coldAccessGas = runState.env.accessWitness!.touchAndChargeMessageCall(toAddress)
gas += coldAccessGas
charge2929Gas = coldAccessGas === BIGINT_0
}
if (common.isActivatedEIP(2929)) {
gas += accessAddressEIP2929(runState, addresstoBytes(toAddr), common, charge2929Gas)
}
if (value !== BIGINT_0) {

@@ -505,8 +611,2 @@ gas += common.param('gasPrices', 'callValueTransfer')

if (common.isActivatedEIP(6800)) {
const toAddress = new Address(addresstoBytes(toAddr))
// TODO: add check if toAddress is not a precompile
gas += runState.env.accessWitness!.touchAndChargeMessageCall(toAddress)
}
const gasLimit = maxCallGas(

@@ -543,2 +643,3 @@ currentGasLimit,

runState.stack.peek(6)
const toAddress = new Address(addresstoBytes(toAddr))

@@ -548,10 +649,16 @@ gas += subMemUsage(runState, inOffset, inLength, common)

if (common.isActivatedEIP(2929) === true) {
gas += accessAddressEIP2929(runState, addresstoBytes(toAddr), common)
let charge2929Gas = true
if (
common.isActivatedEIP(6800) &&
runState.interpreter._evm.getPrecompile(toAddress) === undefined
) {
// TODO: add check if toAddress is not a precompile
const coldAccessGas = runState.env.accessWitness!.touchAndChargeMessageCall(toAddress)
gas += coldAccessGas
charge2929Gas = coldAccessGas === BIGINT_0
}
if (common.isActivatedEIP(6800)) {
const toAddress = new Address(addresstoBytes(toAddr))
// TODO: add check if toAddress is not a precompile
gas += runState.env.accessWitness!.touchAndChargeMessageCall(toAddress)
if (common.isActivatedEIP(2929)) {
gas += accessAddressEIP2929(runState, addresstoBytes(toAddr), common, charge2929Gas)
}

@@ -587,3 +694,3 @@

if (common.isActivatedEIP(2929) === true) {
if (common.isActivatedEIP(2929)) {
gas += accessAddressEIP2929(

@@ -597,3 +704,3 @@ runState,

if (common.isActivatedEIP(3860) === true) {
if (common.isActivatedEIP(3860)) {
gas += ((length + BIGINT_31) / BIGINT_32) * common.param('gasPrices', 'initCodeWordCost')

@@ -613,3 +720,6 @@ }

async function (runState, gas, common): Promise<bigint> {
const [_address, memOffset, memLength] = runState.stack.peek(3)
const [address, memOffset, memLength] = runState.stack.peek(3)
// Note: 2929 is always active if AUTH can be reached,
// since it needs London as minimum hardfork
gas += accessAddressEIP2929(runState, bigIntToBytes(address), common)
gas += subMemUsage(runState, memOffset, memLength, common)

@@ -627,17 +737,5 @@ return gas

const [
currentGasLimit,
addr,
value,
valueExt,
argsOffset,
argsLength,
retOffset,
retLength,
] = runState.stack.peek(8)
const [currentGasLimit, addr, value, argsOffset, argsLength, retOffset, retLength] =
runState.stack.peek(7)
if (valueExt !== BIGINT_0) {
trap(ERROR.AUTHCALL_NONZERO_VALUEEXT)
}
const toAddress = new Address(addresstoBytes(addr))

@@ -674,2 +772,17 @@

runState.messageGasLimit = gasLimit
if (value > BIGINT_0) {
const account = (await runState.stateManager.getAccount(runState.auth!)) ?? new Account()
if (account.balance < value) {
trap(ERROR.OUT_OF_GAS)
}
account.balance -= value
const toAddr = new Address(addresstoBytes(addr))
const target = (await runState.stateManager.getAccount(toAddr)) ?? new Account()
target.balance += value
await runState.stateManager.putAccount(toAddr, target)
}
return gas

@@ -688,12 +801,16 @@ },

if (common.isActivatedEIP(2929) === true) {
gas += accessAddressEIP2929(runState, addresstoBytes(toAddr), common)
}
let charge2929Gas = true
if (common.isActivatedEIP(6800)) {
const toAddress = new Address(addresstoBytes(toAddr))
// TODO: add check if toAddress is not a precompile
gas += runState.env.accessWitness!.touchAndChargeMessageCall(toAddress)
const coldAccessGas = runState.env.accessWitness!.touchAndChargeMessageCall(toAddress)
gas += coldAccessGas
charge2929Gas = coldAccessGas === BIGINT_0
}
if (common.isActivatedEIP(2929)) {
gas += accessAddressEIP2929(runState, addresstoBytes(toAddr), common, charge2929Gas)
}
const gasLimit = maxCallGas(

@@ -729,8 +846,9 @@ currentGasLimit,

const selfdestructToAddress = new Address(addresstoBytes(selfdestructToaddressBigInt))
const contractAddress = runState.interpreter.getAddress()
let deductGas = false
const balance = await runState.interpreter.getExternalBalance(contractAddress)
if (common.gteHardfork(Hardfork.SpuriousDragon)) {
// EIP-161: State Trie Clearing
const balance = await runState.interpreter.getExternalBalance(
runState.interpreter.getAddress()
)
if (balance > BIGINT_0) {

@@ -755,5 +873,60 @@ // This technically checks if account is empty or non-existent

if (common.isActivatedEIP(2929) === true) {
gas += accessAddressEIP2929(runState, selfdestructToAddress.bytes, common, true, true)
let selfDestructToCharge2929Gas = true
if (common.isActivatedEIP(6800)) {
// read accesses for version and code size
if (runState.interpreter._evm.getPrecompile(contractAddress) === undefined) {
gas += runState.env.accessWitness!.touchAddressOnReadAndComputeGas(
contractAddress,
0,
VERKLE_VERSION_LEAF_KEY
)
gas += runState.env.accessWitness!.touchAddressOnReadAndComputeGas(
contractAddress,
0,
VERKLE_CODE_SIZE_LEAF_KEY
)
}
gas += runState.env.accessWitness!.touchAddressOnReadAndComputeGas(
contractAddress,
0,
VERKLE_BALANCE_LEAF_KEY
)
if (balance > BIGINT_0) {
gas += runState.env.accessWitness!.touchAddressOnWriteAndComputeGas(
contractAddress,
0,
VERKLE_BALANCE_LEAF_KEY
)
}
let selfDestructToColdAccessGas =
runState.env.accessWitness!.touchAddressOnReadAndComputeGas(
selfdestructToAddress,
0,
VERKLE_BALANCE_LEAF_KEY
)
if (balance > BIGINT_0) {
selfDestructToColdAccessGas +=
runState.env.accessWitness!.touchAddressOnWriteAndComputeGas(
selfdestructToAddress,
0,
VERKLE_BALANCE_LEAF_KEY
)
}
gas += selfDestructToColdAccessGas
selfDestructToCharge2929Gas = selfDestructToColdAccessGas === BIGINT_0
}
if (common.isActivatedEIP(2929)) {
gas += accessAddressEIP2929(
runState,
selfdestructToAddress.bytes,
common,
selfDestructToCharge2929Gas,
true
)
}
return gas

@@ -760,0 +933,0 @@ },

@@ -140,9 +140,2 @@ import { Hardfork } from '@ethereumjs/common'

/**
* Checks if a jumpsub is valid given a destination (defined as a 2 in the validJumps array)
*/
export function jumpSubIsValid(runState: RunState, dest: number): boolean {
return runState.validJumps[dest] === 2
}
/**
* Returns an overflow-safe slice of an array. It right-pads

@@ -149,0 +142,0 @@ * the data with zeros to `length`.

@@ -14,2 +14,12 @@ import { Hardfork } from '@ethereumjs/common'

import { precompile0a } from './0a-kzg-point-evaluation.js'
import { precompile0b } from './0b-bls12-g1add.js'
import { precompile0c } from './0c-bls12-g1mul.js'
import { precompile0d } from './0d-bls12-g1msm.js'
import { precompile0e } from './0e-bls12-g2add.js'
import { precompile0f } from './0f-bls12-g2mul.js'
import { precompile10 } from './10-bls12-g2msm.js'
import { precompile11 } from './11-bls12-pairing.js'
import { precompile12 } from './12-bls12-map-fp-to-g1.js'
import { precompile13 } from './13-bls12-map-fp2-to-g2.js'
import { MCLBLS, NobleBLS } from './bls12_381/index.js'

@@ -142,2 +152,83 @@ import type { PrecompileFunc, PrecompileInput } from './types.js'

},
{
address: '000000000000000000000000000000000000000b',
check: {
type: PrecompileAvailabilityCheck.EIP,
param: 2537,
},
precompile: precompile0b,
name: 'BLS12_G1ADD',
},
{
address: '000000000000000000000000000000000000000c',
check: {
type: PrecompileAvailabilityCheck.EIP,
param: 2537,
},
precompile: precompile0c,
name: 'BLS12_G1MUL',
},
{
address: '000000000000000000000000000000000000000d',
check: {
type: PrecompileAvailabilityCheck.EIP,
param: 2537,
},
precompile: precompile0d,
name: 'BLS12_G1MSM',
},
{
address: '000000000000000000000000000000000000000e',
check: {
type: PrecompileAvailabilityCheck.EIP,
param: 2537,
},
precompile: precompile0e,
name: 'BLS12_G2ADD',
},
{
address: '000000000000000000000000000000000000000f',
check: {
type: PrecompileAvailabilityCheck.EIP,
param: 2537,
},
precompile: precompile0f,
name: 'BLS12_G2MUL',
},
{
address: '0000000000000000000000000000000000000010',
check: {
type: PrecompileAvailabilityCheck.EIP,
param: 2537,
},
precompile: precompile10,
name: 'BLS12_G2MSM',
},
{
address: '0000000000000000000000000000000000000011',
check: {
type: PrecompileAvailabilityCheck.EIP,
param: 2537,
},
precompile: precompile11,
name: 'BLS12_PAIRING',
},
{
address: '0000000000000000000000000000000000000012',
check: {
type: PrecompileAvailabilityCheck.EIP,
param: 2537,
},
precompile: precompile12,
name: 'BLS12_MAP_FP_TO_G1',
},
{
address: '0000000000000000000000000000000000000013',
check: {
type: PrecompileAvailabilityCheck.EIP,
param: 2537,
},
precompile: precompile13,
name: 'BLS12_MAP_FP2_TO_G2',
},
]

@@ -156,2 +247,11 @@

'000000000000000000000000000000000000000a': precompile0a,
'000000000000000000000000000000000000000b': precompile0b,
'000000000000000000000000000000000000000c': precompile0c,
'000000000000000000000000000000000000000d': precompile0d,
'000000000000000000000000000000000000000e': precompile0e,
'000000000000000000000000000000000000000f': precompile0f,
'0000000000000000000000000000000000000010': precompile10,
'0000000000000000000000000000000000000011': precompile11,
'0000000000000000000000000000000000000012': precompile12,
'0000000000000000000000000000000000000013': precompile13,
}

@@ -211,2 +311,4 @@

getPrecompileName,
MCLBLS,
NobleBLS,
precompileEntries,

@@ -213,0 +315,0 @@ precompiles,

@@ -10,5 +10,4 @@ import { zeros } from '@ethereumjs/util'

import type { PrecompileFunc } from './precompiles/types.js'
import type { Common, EVMStateManagerInterface } from '@ethereumjs/common'
import type { AccessWitness } from '@ethereumjs/statemanager'
import type { Account, Address, AsyncEventEmitter } from '@ethereumjs/util'
import type { AccessWitnessInterface, Common, EVMStateManagerInterface } from '@ethereumjs/common'
import type { Account, Address, AsyncEventEmitter, PrefixedHexString } from '@ethereumjs/util'

@@ -76,3 +75,3 @@ export type DeleteOpcode = {

*/
selfdestruct?: Set<string>
selfdestruct?: Set<PrefixedHexString>
/**

@@ -110,3 +109,3 @@ * The address of the account that is executing this code (`address(this)`). Defaults to the zero address.

*/
createdAddresses?: Set<string>
createdAddresses?: Set<PrefixedHexString>
/**

@@ -130,3 +129,3 @@ * Skip balance checks if true. If caller balance is less than message value,

accessWitness?: AccessWitness
accessWitness?: AccessWitnessInterface
}

@@ -157,3 +156,3 @@

accessList?: Map<string, Set<string>>
preimages?: Map<string, Uint8Array>
preimages?: Map<PrefixedHexString, Uint8Array>
addAlwaysWarmAddress(address: string, addToAccessList?: boolean): void

@@ -187,7 +186,6 @@ addAlwaysWarmSlot(address: string, slot: string, addToAccessList?: boolean): void

* - [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559) - Fee market change for ETH 1.0 chain
* - [EIP-2315](https://eips.ethereum.org/EIPS/eip-2315) - Simple subroutines for the EVM (`outdated`)
* - [EIP-2537](https://eips.ethereum.org/EIPS/eip-2537) - BLS precompiles (removed in v4.0.0, see latest v3 release)
* - [EIP-2565](https://eips.ethereum.org/EIPS/eip-2565) - ModExp gas cost
* - [EIP-2718](https://eips.ethereum.org/EIPS/eip-2565) - Transaction Types
* - [EIP-2935](https://eips.ethereum.org/EIPS/eip-2935) - Save historical block hashes in state (`experimental`)
* - [EIP-2935](https://eips.ethereum.org/EIPS/eip-2935) - Serve historical block hashes from state (Prague)
* - [EIP-2929](https://eips.ethereum.org/EIPS/eip-2929) - gas cost increases for state access opcodes

@@ -211,7 +209,13 @@ * - [EIP-2930](https://eips.ethereum.org/EIPS/eip-2930) - Optional access list tx type

* - [EIP-4844](https://eips.ethereum.org/EIPS/eip-4844) - Shard Blob Transactions (Cancun)
* - [EIP-7702](https://eips.ethereum.org/EIPS/eip-7702) - EOA code transactions (Prague) (`outdated`)
* - [EIP-7709](https://eips.ethereum.org/EIPS/eip-7709) - Read BLOCKHASH from storage and update cost (Osaka)
* - [EIP-4895](https://eips.ethereum.org/EIPS/eip-4895) - Beacon chain push withdrawals as operations (Shanghai)
* - [EIP-5133](https://eips.ethereum.org/EIPS/eip-5133) - Delaying Difficulty Bomb to mid-September 2022 (Gray Glacier)
* - [EIP-5656](https://eips.ethereum.org/EIPS/eip-5656) - MCOPY - Memory copying instruction (Cancun)
* - [EIP-6110](https://eips.ethereum.org/EIPS/eip-6110) - Supply validator deposits on chain (Prague)
* - [EIP-6780](https://eips.ethereum.org/EIPS/eip-6780) - SELFDESTRUCT only in same transaction (Cancun)
* - [EIP-7002](https://eips.ethereum.org/EIPS/eip-7002) - Execution layer triggerable withdrawals (Prague)
* - [EIP-7251](https://eips.ethereum.org/EIPS/eip-7251) - Execution layer triggerable validator consolidations (Prague)
* - [EIP-7516](https://eips.ethereum.org/EIPS/eip-7516) - BLOBBASEFEE opcode (Cancun)
* - [EIP-7685](https://eips.ethereum.org/EIPS/eip-7685) - General purpose execution layer requests (Prague)
*

@@ -268,2 +272,24 @@ * *Annotations:*

/**
* For the EIP-2537 BLS Precompiles, the native JS `@noble/curves`
* https://github.com/paulmillr/noble-curves BLS12-381 curve implementation
* is used (see `noble.ts` file in the `precompiles` folder).
*
* To use an alternative implementation this option can be used by passing
* in a wrapper implementation integrating the desired library and adhering
* to the `EVMBLSInterface` specification.
*
* An interface for the MCL WASM implementation https://github.com/herumi/mcl-wasm
* is shipped with this library which can be used as follows (with `mcl-wasm` being
* explicitly added to the set of dependencies):
*
* ```ts
* import * as mcl from 'mcl-wasm'
*
* await mcl.init(mcl.BLS12_381)
* const evm = await EVM.create({ bls: new MCLBLS(mcl) })
* ```
*/
bls?: EVMBLSInterface
/*

@@ -327,7 +353,7 @@ * The StateManager which is used to update the trie

*/
selfdestruct?: Set<string>
selfdestruct?: Set<PrefixedHexString>
/**
* Map of addresses which were created (used in EIP 6780)
*/
createdAddresses?: Set<string>
createdAddresses?: Set<PrefixedHexString>
/**

@@ -343,2 +369,15 @@ * The gas refund counter

export type EVMBLSInterface = {
init?(): void
addG1(input: Uint8Array): Uint8Array
mulG1(input: Uint8Array): Uint8Array
addG2(input: Uint8Array): Uint8Array
mulG2(input: Uint8Array): Uint8Array
mapFPtoG1(input: Uint8Array): Uint8Array
mapFP2toG2(input: Uint8Array): Uint8Array
msmG1(input: Uint8Array): Uint8Array
msmG2(input: Uint8Array): Uint8Array
pairingCheck(input: Uint8Array): Uint8Array
}
/**

@@ -399,5 +438,5 @@ * Log that the contract emits.

export interface bn128 {
ec_pairing: (input_str: string) => string
ec_add: (input_str: string) => string
ec_mul: (input_hex: string) => string
ec_pairing: (input_str: string) => PrefixedHexString
ec_add: (input_str: string) => PrefixedHexString
ec_mul: (input_hex: string) => PrefixedHexString
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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