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

@ethereumjs/common

Package Overview
Dependencies
Maintainers
3
Versions
34
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@ethereumjs/common - npm Package Compare versions

Comparing version 2.6.5 to 3.0.0-beta.1

dist/common.d.ts

6

dist/chains/goerli.json

@@ -5,3 +5,3 @@ {

"networkId": 5,
"defaultHardfork": "istanbul",
"defaultHardfork": "london",
"consensus": {

@@ -18,3 +18,2 @@ "type": "poa",

"genesis": {
"hash": "0xbf7e331f7f7c1dd2e05159666b3bf8bc7a8a3a9eb1d518969eab529dd9b88c1a",
"timestamp": "0x5c51a607",

@@ -24,4 +23,3 @@ "gasLimit": 10485760,

"nonce": "0x0000000000000000",
"extraData": "0x22466c6578692069732061207468696e6722202d204166726900000000000000e0a2bd4258d2768837baa26a28fe71dc079f84c70000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"stateRoot": "0x5d6cded585e73c4e322c30c2f782a336316f17dd85a4863b9d838d2d4b8b3008"
"extraData": "0x22466c6578692069732061207468696e6722202d204166726900000000000000e0a2bd4258d2768837baa26a28fe71dc079f84c70000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
},

@@ -28,0 +26,0 @@ "hardforks": [

@@ -5,7 +5,10 @@ {

"networkId": 42,
"defaultHardfork": "istanbul",
"defaultHardfork": "london",
"consensus": {
"type": "poa",
"algorithm": "aura",
"aura": {}
"algorithm": "clique",
"clique": {
"period": 15,
"epoch": 30000
}
},

@@ -15,9 +18,6 @@ "comment": "Parity PoA test network",

"genesis": {
"hash": "0xa3c565fc15c7478862d50ccd6561e3c06b24cc509bf388941c25ea985ce32cb9",
"timestamp": null,
"gasLimit": 6000000,
"difficulty": 131072,
"nonce": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"extraData": "0x",
"stateRoot": "0x2480155b48a1cea17d67dbfdfaafe821c1d19cdd478c5358e8ec56dec24502b2"
"extraData": "0x"
},

@@ -24,0 +24,0 @@ "hardforks": [

@@ -5,3 +5,3 @@ {

"networkId": 1,
"defaultHardfork": "istanbul",
"defaultHardfork": "london",
"consensus": {

@@ -15,9 +15,6 @@ "type": "pow",

"genesis": {
"hash": "0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3",
"timestamp": null,
"gasLimit": 5000,
"difficulty": 17179869184,
"nonce": "0x0000000000000042",
"extraData": "0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fa",
"stateRoot": "0xd7f8974fb5ac78d9ac099b9ad5018bedc2ce0a72dad1827a1709da30580f0544"
"extraData": "0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fa"
},

@@ -24,0 +21,0 @@ "hardforks": [

@@ -5,3 +5,3 @@ {

"networkId": 4,
"defaultHardfork": "istanbul",
"defaultHardfork": "london",
"consensus": {

@@ -18,3 +18,2 @@ "type": "poa",

"genesis": {
"hash": "0x6341fd3daf94b748c72ced5a5b26028f2474f5f00d824504e4fa37a75767e177",
"timestamp": "0x58ee40ba",

@@ -24,4 +23,3 @@ "gasLimit": 4700000,

"nonce": "0x0000000000000000",
"extraData": "0x52657370656374206d7920617574686f7269746168207e452e436172746d616e42eb768f2244c8811c63729a21a3569731535f067ffc57839b00206d1ad20c69a1981b489f772031b279182d99e65703f0076e4812653aab85fca0f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"stateRoot": "0x53580584816f617295ea26c0e17641e0120cab2f0a8ffb53a866fd53aa8e8c2d"
"extraData": "0x52657370656374206d7920617574686f7269746168207e452e436172746d616e42eb768f2244c8811c63729a21a3569731535f067ffc57839b00206d1ad20c69a1981b489f772031b279182d99e65703f0076e4812653aab85fca0f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
},

@@ -28,0 +26,0 @@ "hardforks": [

@@ -5,3 +5,3 @@ {

"networkId": 3,
"defaultHardfork": "istanbul",
"defaultHardfork": "london",
"consensus": {

@@ -15,9 +15,6 @@ "type": "pow",

"genesis": {
"hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d",
"timestamp": null,
"gasLimit": 16777216,
"difficulty": 1048576,
"nonce": "0x0000000000000042",
"extraData": "0x3535353535353535353535353535353535353535353535353535353535353535",
"stateRoot": "0x217b0bbcfb72e2d57e28f33cb361b9983513177755dc3f33ce3e7022ed62b77b"
"extraData": "0x3535353535353535353535353535353535353535353535353535353535353535"
},

@@ -24,0 +21,0 @@ "hardforks": [

@@ -5,3 +5,3 @@ {

"networkId": 11155111,
"defaultHardfork": "istanbul",
"defaultHardfork": "london",
"consensus": {

@@ -15,3 +15,2 @@ "type": "pow",

"genesis": {
"hash": "0x25a5cc106eea7138acab33231d7160d69cb777ee0c2c553fcddf5138993e6dd9",
"timestamp": "0x6159af19",

@@ -21,4 +20,3 @@ "gasLimit": 30000000,

"nonce": "0x0000000000000000",
"extraData": "0x5365706f6c69612c20417468656e732c204174746963612c2047726565636521",
"stateRoot": "0x5eb6e371a698b8d68f665192350ffcecbbbf322916f4b51bd79bb6887da3f494"
"extraData": "0x5365706f6c69612c20417468656e732c204174746963612c2047726565636521"
},

@@ -25,0 +23,0 @@ "hardforks": [

@@ -1,2 +0,4 @@

import { eipsType } from './../types';
export declare const EIPs: eipsType;
export declare const EIPs: {
[key: number]: any;
};
//# sourceMappingURL=index.d.ts.map

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

2930: require('./2930.json'),
3074: require('./3074.json'),
3198: require('./3198.json'),

@@ -15,0 +16,0 @@ 3529: require('./3529.json'),

export declare const hardforks: any[][];
//# sourceMappingURL=index.d.ts.map

@@ -1,555 +0,4 @@

/// <reference types="bn.js" />
/// <reference types="node" />
import { EventEmitter } from 'events';
import { BN, BNLike } from 'ethereumjs-util';
import { BootstrapNode, Chain as IChain, GenesisBlock, GenesisState, Hardfork as HardforkParams } from './types';
export declare enum CustomChain {
/**
* Polygon (Matic) Mainnet
*
* - [Documentation](https://docs.matic.network/docs/develop/network-details/network)
*/
PolygonMainnet = "polygon-mainnet",
/**
* Polygon (Matic) Mumbai Testnet
*
* - [Documentation](https://docs.matic.network/docs/develop/network-details/network)
*/
PolygonMumbai = "polygon-mumbai",
/**
* Arbitrum Rinkeby Testnet
*
* - [Documentation](https://developer.offchainlabs.com/docs/public_testnet)
*/
ArbitrumRinkebyTestnet = "arbitrum-rinkeby-testnet",
/**
* xDai EVM sidechain with a native stable token
*
* - [Documentation](https://www.xdaichain.com/)
*/
xDaiChain = "x-dai-chain",
/**
* Optimistic Kovan - testnet for Optimism roll-up
*
* - [Documentation](https://community.optimism.io/docs/developers/tutorials.html)
*/
OptimisticKovan = "optimistic-kovan",
/**
* Optimistic Ethereum - mainnet for Optimism roll-up
*
* - [Documentation](https://community.optimism.io/docs/developers/tutorials.html)
*/
OptimisticEthereum = "optimistic-ethereum"
}
export declare enum Chain {
Mainnet = 1,
Ropsten = 3,
Rinkeby = 4,
Kovan = 42,
Goerli = 5,
Sepolia = 11155111
}
export declare enum Hardfork {
Chainstart = "chainstart",
Homestead = "homestead",
Dao = "dao",
TangerineWhistle = "tangerineWhistle",
SpuriousDragon = "spuriousDragon",
Byzantium = "byzantium",
Constantinople = "constantinople",
Petersburg = "petersburg",
Istanbul = "istanbul",
MuirGlacier = "muirGlacier",
Berlin = "berlin",
London = "london",
ArrowGlacier = "arrowGlacier",
GrayGlacier = "grayGlacier",
MergeForkIdTransition = "mergeForkIdTransition",
Merge = "merge",
Shanghai = "shanghai"
}
export declare enum ConsensusType {
ProofOfStake = "pos",
ProofOfWork = "pow",
ProofOfAuthority = "poa"
}
export declare enum ConsensusAlgorithm {
Ethash = "ethash",
Clique = "clique",
Casper = "casper"
}
interface BaseOpts {
/**
* String identifier ('byzantium') for hardfork or {@link Hardfork} enum.
*
* Default: Hardfork.Istanbul
*/
hardfork?: string | Hardfork;
/**
* Limit parameter returns to the given hardforks
*/
supportedHardforks?: Array<string | Hardfork>;
/**
* Selected EIPs which can be activated, please use an array for instantiation
* (e.g. `eips: [ 2537, ]`)
*
* Currently supported:
*
* - [EIP-2537](https://eips.ethereum.org/EIPS/eip-2537) - BLS12-381 precompiles
*/
eips?: number[];
}
/**
* Options for instantiating a {@link Common} instance.
*/
export interface CommonOpts extends BaseOpts {
/**
* Chain name ('mainnet'), id (1), or {@link Chain} enum,
* either from a chain directly supported or a custom chain
* passed in via {@link CommonOpts.customChains}.
*/
chain: string | number | Chain | BN | object;
/**
* Initialize (in addition to the supported chains) with the selected
* custom chains
*
* Usage (directly with the respective chain intialization via the {@link CommonOpts.chain} option):
*
* Pattern 1 (without genesis state):
*
* ```javascript
* import myCustomChain1 from '[PATH_TO_MY_CHAINS]/myCustomChain1.json'
* const common = new Common({ chain: 'myCustomChain1', customChains: [ myCustomChain1 ]})
* ```
*
* Pattern 2 (with genesis state see {@link GenesisState} for format):
*
* ```javascript
* const simpleState = {
* '0x0...01': '0x100', // For EoA
* }
* import myCustomChain1 from '[PATH_TO_MY_CHAINS]/myCustomChain1.json'
* import chain1GenesisState from '[PATH_TO_GENESIS_STATES]/chain1GenesisState.json'
* const common = new Common({ chain: 'myCustomChain1', customChains: [ [ myCustomChain1, simpleState ] ]})
* ```
*
* Pattern 3 (with complex genesis state, containing contract accounts and storage).
* Note that in {@link AccountState} there are two
* accepted types. This allows to easily insert accounts in the genesis state:
*
* A complex genesis state with Contract and EoA states would have the following format:
*
* ```javascript
* const complexState = {
* '0x0...01': '0x100', // For EoA
* '0x0...02': ['0x1', '0xRUNTIME_BYTECODE', [[ keyOne, valueOne ], [ keyTwo, valueTwo ]]] // For contracts
* }
* import myCustomChain1 from '[PATH_TO_MY_CHAINS]/myCustomChain1.json'
* const common = new Common({ chain: 'myCustomChain1', customChains: [ [ myCustomChain1, complexState ] ]})
* ```
*/
customChains?: IChain[] | [IChain, GenesisState][];
}
/**
* Options to be used with the {@link Common.custom} static constructor.
*/
export interface CustomCommonOpts extends BaseOpts {
/**
* The name (`mainnet`), id (`1`), or {@link Chain} enum of
* a standard chain used to base the custom chain params on.
*/
baseChain?: string | number | Chain | BN;
}
interface hardforkOptions {
/** optional, only allow supported HFs (default: false) */
onlySupported?: boolean;
/** optional, only active HFs (default: false) */
onlyActive?: boolean;
}
/**
* Common class to access chain and hardfork parameters and to provide
* a unified and shared view on the network and hardfork state.
*
* Use the {@link Common.custom} static constructor for creating simple
* custom chain {@link Common} objects (more complete custom chain setups
* can be created via the main constructor and the {@link CommonOpts.customChains} parameter).
*/
export default class Common extends EventEmitter {
readonly DEFAULT_HARDFORK: string | Hardfork;
private _chainParams;
private _hardfork;
private _supportedHardforks;
private _eips;
private _customChains;
/**
* Creates a {@link Common} object for a custom chain, based on a standard one.
*
* It uses all the {@link Chain} parameters from the {@link baseChain} option except the ones overridden
* in a provided {@link chainParamsOrName} dictionary. Some usage example:
*
* ```javascript
* Common.custom({chainId: 123})
* ```
*
* There are also selected supported custom chains which can be initialized by using one of the
* {@link CustomChains} for {@link chainParamsOrName}, e.g.:
*
* ```javascript
* Common.custom(CustomChains.MaticMumbai)
* ```
*
* Note that these supported custom chains only provide some base parameters (usually the chain and
* network ID and a name) and can only be used for selected use cases (e.g. sending a tx with
* the `@ethereumjs/tx` library to a Layer-2 chain).
*
* @param chainParamsOrName Custom parameter dict (`name` will default to `custom-chain`) or string with name of a supported custom chain
* @param opts Custom chain options to set the {@link CustomCommonOpts.baseChain}, selected {@link CustomCommonOpts.hardfork} and others
*/
static custom(chainParamsOrName: Partial<IChain> | CustomChain, opts?: CustomCommonOpts): Common;
/**
* Creates a {@link Common} object for a custom chain, based on a standard one. It uses all the `Chain`
* params from {@link baseChain} except the ones overridden in {@link customChainParams}.
*
* @deprecated Use {@link Common.custom} instead
*
* @param baseChain The name (`mainnet`) or id (`1`) of a standard chain used to base the custom
* chain params on.
* @param customChainParams The custom parameters of the chain.
* @param hardfork String identifier ('byzantium') for hardfork (optional)
* @param supportedHardforks Limit parameter returns to the given hardforks (optional)
*/
static forCustomChain(baseChain: string | number | Chain, customChainParams: Partial<IChain>, hardfork?: string | Hardfork, supportedHardforks?: Array<string | Hardfork>): Common;
/**
* Static method to determine if a {@link chainId} is supported as a standard chain
* @param chainId BN id (`1`) of a standard chain
* @returns boolean
*/
static isSupportedChainId(chainId: BN): boolean;
private static _getChainParams;
/**
*
* @constructor
*/
constructor(opts: CommonOpts);
/**
* Sets the chain
* @param chain String ('mainnet') or Number (1) chain
* representation. Or, a Dictionary of chain parameters for a private network.
* @returns The dictionary with parameters set as chain
*/
setChain(chain: string | number | Chain | BN | object): any;
/**
* Sets the hardfork to get params for
* @param hardfork String identifier (e.g. 'byzantium') or {@link Hardfork} enum
*/
setHardfork(hardfork: string | Hardfork): void;
/**
* Returns the hardfork based on the block number or an optional
* total difficulty (Merge HF) provided.
*
* An optional TD takes precedence in case the corresponding HF block
* is set to `null` or otherwise needs to match (if not an error
* will be thrown).
*
* @param blockNumber
* @param td
* @returns The name of the HF
*/
getHardforkByBlockNumber(blockNumber: BNLike, td?: BNLike): string;
/**
* Sets a new hardfork based on the block number or an optional
* total difficulty (Merge HF) provided.
*
* An optional TD takes precedence in case the corresponding HF block
* is set to `null` or otherwise needs to match (if not an error
* will be thrown).
*
* @param blockNumber
* @param td
* @returns The name of the HF set
*/
setHardforkByBlockNumber(blockNumber: BNLike, td?: BNLike): string;
/**
* Internal helper function to choose between hardfork set and hardfork provided as param
* @param hardfork Hardfork given to function as a parameter
* @returns Hardfork chosen to be used
*/
_chooseHardfork(hardfork?: string | Hardfork | null, onlySupported?: boolean): string;
/**
* Internal helper function, returns the params for the given hardfork for the chain set
* @param hardfork Hardfork name
* @returns Dictionary with hardfork params
*/
_getHardfork(hardfork: string | Hardfork): any;
/**
* Internal helper function to check if a hardfork is set to be supported by the library
* @param hardfork Hardfork name
* @returns True if hardfork is supported
*/
_isSupportedHardfork(hardfork: string | Hardfork | null): boolean;
/**
* Sets the active EIPs
* @param eips
*/
setEIPs(eips?: number[]): void;
/**
* Returns a parameter for the current chain setup
*
* If the parameter is present in an EIP, the EIP always takes precendence.
* Otherwise the parameter if taken from the latest applied HF with
* a change on the respective parameter.
*
* @param topic Parameter topic ('gasConfig', 'gasPrices', 'vm', 'pow')
* @param name Parameter name (e.g. 'minGasLimit' for 'gasConfig' topic)
* @returns The value requested or `null` if not found
*/
param(topic: string, name: string): any;
/**
* Returns the parameter corresponding to a hardfork
* @param topic Parameter topic ('gasConfig', 'gasPrices', 'vm', 'pow')
* @param name Parameter name (e.g. 'minGasLimit' for 'gasConfig' topic)
* @param hardfork Hardfork name
* @returns The value requested or `null` if not found
*/
paramByHardfork(topic: string, name: string, hardfork: string | Hardfork): any;
/**
* Returns a parameter corresponding to an EIP
* @param topic Parameter topic ('gasConfig', 'gasPrices', 'vm', 'pow')
* @param name Parameter name (e.g. 'minGasLimit' for 'gasConfig' topic)
* @param eip Number of the EIP
* @returns The value requested or `null` if not found
*/
paramByEIP(topic: string, name: string, eip: number): any;
/**
* Returns a parameter for the hardfork active on block number
* @param topic Parameter topic
* @param name Parameter name
* @param blockNumber Block number
*/
paramByBlock(topic: string, name: string, blockNumber: BNLike): any;
/**
* Checks if an EIP is activated by either being included in the EIPs
* manually passed in with the {@link CommonOpts.eips} or in a
* hardfork currently being active
*
* Note: this method only works for EIPs being supported
* by the {@link CommonOpts.eips} constructor option
* @param eip
*/
isActivatedEIP(eip: number): boolean;
/**
* Checks if set or provided hardfork is active on block number
* @param hardfork Hardfork name or null (for HF set)
* @param blockNumber
* @param opts Hardfork options (onlyActive unused)
* @returns True if HF is active on block number
*/
hardforkIsActiveOnBlock(hardfork: string | Hardfork | null, blockNumber: BNLike, opts?: hardforkOptions): boolean;
/**
* Alias to hardforkIsActiveOnBlock when hardfork is set
* @param blockNumber
* @param opts Hardfork options (onlyActive unused)
* @returns True if HF is active on block number
*/
activeOnBlock(blockNumber: BNLike, opts?: hardforkOptions): boolean;
/**
* Sequence based check if given or set HF1 is greater than or equal HF2
* @param hardfork1 Hardfork name or null (if set)
* @param hardfork2 Hardfork name
* @param opts Hardfork options
* @returns True if HF1 gte HF2
*/
hardforkGteHardfork(hardfork1: string | Hardfork | null, hardfork2: string | Hardfork, opts?: hardforkOptions): boolean;
/**
* Alias to hardforkGteHardfork when hardfork is set
* @param hardfork Hardfork name
* @param opts Hardfork options
* @returns True if hardfork set is greater than hardfork provided
*/
gteHardfork(hardfork: string | Hardfork, opts?: hardforkOptions): boolean;
/**
* Checks if given or set hardfork is active on the chain
* @param hardfork Hardfork name, optional if HF set
* @param opts Hardfork options (onlyActive unused)
* @returns True if hardfork is active on the chain
*/
hardforkIsActiveOnChain(hardfork?: string | Hardfork | null, opts?: hardforkOptions): boolean;
/**
* Returns the active hardfork switches for the current chain
* @param blockNumber up to block if provided, otherwise for the whole chain
* @param opts Hardfork options (onlyActive unused)
* @return Array with hardfork arrays
*/
activeHardforks(blockNumber?: BNLike | null, opts?: hardforkOptions): HardforkParams[];
/**
* Returns the latest active hardfork name for chain or block or throws if unavailable
* @param blockNumber up to block if provided, otherwise for the whole chain
* @param opts Hardfork options (onlyActive unused)
* @return Hardfork name
*/
activeHardfork(blockNumber?: BNLike | null, opts?: hardforkOptions): string;
/**
* Returns the hardfork change block for hardfork provided or set
* @param hardfork Hardfork name, optional if HF set
* @returns Block number or null if unscheduled
* @deprecated Please use {@link Common.hardforkBlockBN} for large number support
*/
hardforkBlock(hardfork?: string | Hardfork): number | null;
/**
* Returns the hardfork change block for hardfork provided or set
* @param hardfork Hardfork name, optional if HF set
* @returns Block number or null if unscheduled
*/
hardforkBlockBN(hardfork?: string | Hardfork): BN | null;
/**
* Returns the hardfork change total difficulty (Merge HF) for hardfork provided or set
* @param hardfork Hardfork name, optional if HF set
* @returns Total difficulty or null if no set
*/
hardforkTD(hardfork?: string | Hardfork): BN | null;
/**
* True if block number provided is the hardfork (given or set) change block
* @param blockNumber Number of the block to check
* @param hardfork Hardfork name, optional if HF set
* @returns True if blockNumber is HF block
*/
isHardforkBlock(blockNumber: BNLike, hardfork?: string | Hardfork): boolean;
/**
* Returns the change block for the next hardfork after the hardfork provided or set
* @param hardfork Hardfork name, optional if HF set
* @returns Block number or null if not available
* @deprecated Please use {@link Common.nextHardforkBlockBN} for large number support
*/
nextHardforkBlock(hardfork?: string | Hardfork): number | null;
/**
* Returns the change block for the next hardfork after the hardfork provided or set
* @param hardfork Hardfork name, optional if HF set
* @returns Block number or null if not available
*/
nextHardforkBlockBN(hardfork?: string | Hardfork): BN | null;
/**
* True if block number provided is the hardfork change block following the hardfork given or set
* @param blockNumber Number of the block to check
* @param hardfork Hardfork name, optional if HF set
* @returns True if blockNumber is HF block
*/
isNextHardforkBlock(blockNumber: BNLike, hardfork?: string | Hardfork): boolean;
/**
* Internal helper function to calculate a fork hash
* @param hardfork Hardfork name
* @returns Fork hash as hex string
*/
_calcForkHash(hardfork: string | Hardfork): string;
/**
* Returns an eth/64 compliant fork hash (EIP-2124)
* @param hardfork Hardfork name, optional if HF set
*/
forkHash(hardfork?: string | Hardfork): any;
/**
*
* @param forkHash Fork hash as a hex string
* @returns Array with hardfork data (name, block, forkHash)
*/
hardforkForForkHash(forkHash: string): any | null;
/**
* Returns the Genesis parameters of the current chain
* @returns Genesis dictionary
*/
genesis(): GenesisBlock;
/**
* Returns the Genesis state of the current chain,
* all values are provided as hex-prefixed strings.
*/
genesisState(): GenesisState;
/**
* Returns the hardforks for current chain
* @returns {Array} Array with arrays of hardforks
*/
hardforks(): HardforkParams[];
/**
* Returns bootstrap nodes for the current chain
* @returns {Dictionary} Dict with bootstrap nodes
*/
bootstrapNodes(): BootstrapNode[];
/**
* Returns DNS networks for the current chain
* @returns {String[]} Array of DNS ENR urls
*/
dnsNetworks(): string[];
/**
* Returns the hardfork set
* @returns Hardfork name
*/
hardfork(): string | Hardfork;
/**
* Returns the Id of current chain
* @returns chain Id
* @deprecated Please use {@link Common.chainIdBN} for large number support
*/
chainId(): number;
/**
* Returns the Id of current chain
* @returns chain Id
*/
chainIdBN(): BN;
/**
* Returns the name of current chain
* @returns chain name (lower case)
*/
chainName(): string;
/**
* Returns the Id of current network
* @returns network Id
* @deprecated Please use {@link Common.networkIdBN} for large number support
*/
networkId(): number;
/**
* Returns the Id of current network
* @returns network Id
*/
networkIdBN(): BN;
/**
* Returns the active EIPs
* @returns List of EIPs
*/
eips(): number[];
/**
* Returns the consensus type of the network
* Possible values: "pow"|"poa"|"pos"
*
* Note: This value can update along a hardfork.
*/
consensusType(): string | ConsensusType;
/**
* Returns the concrete consensus implementation
* algorithm or protocol for the network
* e.g. "ethash" for "pow" consensus type,
* "clique" for "poa" consensus type or
* "casper" for "pos" consensus type.
*
* Note: This value can update along a hardfork.
*/
consensusAlgorithm(): string | ConsensusAlgorithm;
/**
* Returns a dictionary with consensus configuration
* parameters based on the consensus algorithm
*
* Expected returns (parameters must be present in
* the respective chain json files):
*
* ethash: -
* clique: period, epoch
* aura: -
* casper: -
*
* Note: This value can update along a hardfork.
*/
consensusConfig(): {
[key: string]: any;
};
/**
* Returns a deep copy of this {@link Common} instance.
*/
copy(): Common;
}
export {};
export { Common as default } from './common';
export * from './enums';
export * from './types';
//# 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.ConsensusAlgorithm = exports.ConsensusType = exports.Hardfork = exports.Chain = exports.CustomChain = void 0;
const events_1 = require("events");
const crc_32_1 = require("crc-32");
const ethereumjs_util_1 = require("ethereumjs-util");
const chains_1 = require("./chains");
const hardforks_1 = require("./hardforks");
const eips_1 = require("./eips");
var CustomChain;
(function (CustomChain) {
/**
* Polygon (Matic) Mainnet
*
* - [Documentation](https://docs.matic.network/docs/develop/network-details/network)
*/
CustomChain["PolygonMainnet"] = "polygon-mainnet";
/**
* Polygon (Matic) Mumbai Testnet
*
* - [Documentation](https://docs.matic.network/docs/develop/network-details/network)
*/
CustomChain["PolygonMumbai"] = "polygon-mumbai";
/**
* Arbitrum Rinkeby Testnet
*
* - [Documentation](https://developer.offchainlabs.com/docs/public_testnet)
*/
CustomChain["ArbitrumRinkebyTestnet"] = "arbitrum-rinkeby-testnet";
/**
* xDai EVM sidechain with a native stable token
*
* - [Documentation](https://www.xdaichain.com/)
*/
CustomChain["xDaiChain"] = "x-dai-chain";
/**
* Optimistic Kovan - testnet for Optimism roll-up
*
* - [Documentation](https://community.optimism.io/docs/developers/tutorials.html)
*/
CustomChain["OptimisticKovan"] = "optimistic-kovan";
/**
* Optimistic Ethereum - mainnet for Optimism roll-up
*
* - [Documentation](https://community.optimism.io/docs/developers/tutorials.html)
*/
CustomChain["OptimisticEthereum"] = "optimistic-ethereum";
})(CustomChain = exports.CustomChain || (exports.CustomChain = {}));
var Chain;
(function (Chain) {
Chain[Chain["Mainnet"] = 1] = "Mainnet";
Chain[Chain["Ropsten"] = 3] = "Ropsten";
Chain[Chain["Rinkeby"] = 4] = "Rinkeby";
Chain[Chain["Kovan"] = 42] = "Kovan";
Chain[Chain["Goerli"] = 5] = "Goerli";
Chain[Chain["Sepolia"] = 11155111] = "Sepolia";
})(Chain = exports.Chain || (exports.Chain = {}));
var Hardfork;
(function (Hardfork) {
Hardfork["Chainstart"] = "chainstart";
Hardfork["Homestead"] = "homestead";
Hardfork["Dao"] = "dao";
Hardfork["TangerineWhistle"] = "tangerineWhistle";
Hardfork["SpuriousDragon"] = "spuriousDragon";
Hardfork["Byzantium"] = "byzantium";
Hardfork["Constantinople"] = "constantinople";
Hardfork["Petersburg"] = "petersburg";
Hardfork["Istanbul"] = "istanbul";
Hardfork["MuirGlacier"] = "muirGlacier";
Hardfork["Berlin"] = "berlin";
Hardfork["London"] = "london";
Hardfork["ArrowGlacier"] = "arrowGlacier";
Hardfork["GrayGlacier"] = "grayGlacier";
Hardfork["MergeForkIdTransition"] = "mergeForkIdTransition";
Hardfork["Merge"] = "merge";
Hardfork["Shanghai"] = "shanghai";
})(Hardfork = exports.Hardfork || (exports.Hardfork = {}));
var ConsensusType;
(function (ConsensusType) {
ConsensusType["ProofOfStake"] = "pos";
ConsensusType["ProofOfWork"] = "pow";
ConsensusType["ProofOfAuthority"] = "poa";
})(ConsensusType = exports.ConsensusType || (exports.ConsensusType = {}));
var ConsensusAlgorithm;
(function (ConsensusAlgorithm) {
ConsensusAlgorithm["Ethash"] = "ethash";
ConsensusAlgorithm["Clique"] = "clique";
ConsensusAlgorithm["Casper"] = "casper";
})(ConsensusAlgorithm = exports.ConsensusAlgorithm || (exports.ConsensusAlgorithm = {}));
/**
* Common class to access chain and hardfork parameters and to provide
* a unified and shared view on the network and hardfork state.
*
* Use the {@link Common.custom} static constructor for creating simple
* custom chain {@link Common} objects (more complete custom chain setups
* can be created via the main constructor and the {@link CommonOpts.customChains} parameter).
*/
class Common extends events_1.EventEmitter {
/**
*
* @constructor
*/
constructor(opts) {
var _a, _b;
super();
this._supportedHardforks = [];
this._eips = [];
this._customChains = (_a = opts.customChains) !== null && _a !== void 0 ? _a : [];
this._chainParams = this.setChain(opts.chain);
this.DEFAULT_HARDFORK = (_b = this._chainParams.defaultHardfork) !== null && _b !== void 0 ? _b : Hardfork.Istanbul;
for (const hf of this._chainParams.hardforks) {
if (!hf.forkHash) {
hf.forkHash = this._calcForkHash(hf.name);
}
}
this._hardfork = this.DEFAULT_HARDFORK;
if (opts.supportedHardforks) {
this._supportedHardforks = opts.supportedHardforks;
}
if (opts.hardfork) {
this.setHardfork(opts.hardfork);
}
if (opts.eips) {
this.setEIPs(opts.eips);
}
}
/**
* Creates a {@link Common} object for a custom chain, based on a standard one.
*
* It uses all the {@link Chain} parameters from the {@link baseChain} option except the ones overridden
* in a provided {@link chainParamsOrName} dictionary. Some usage example:
*
* ```javascript
* Common.custom({chainId: 123})
* ```
*
* There are also selected supported custom chains which can be initialized by using one of the
* {@link CustomChains} for {@link chainParamsOrName}, e.g.:
*
* ```javascript
* Common.custom(CustomChains.MaticMumbai)
* ```
*
* Note that these supported custom chains only provide some base parameters (usually the chain and
* network ID and a name) and can only be used for selected use cases (e.g. sending a tx with
* the `@ethereumjs/tx` library to a Layer-2 chain).
*
* @param chainParamsOrName Custom parameter dict (`name` will default to `custom-chain`) or string with name of a supported custom chain
* @param opts Custom chain options to set the {@link CustomCommonOpts.baseChain}, selected {@link CustomCommonOpts.hardfork} and others
*/
static custom(chainParamsOrName, opts = {}) {
var _a;
const baseChain = (_a = opts.baseChain) !== null && _a !== void 0 ? _a : 'mainnet';
const standardChainParams = Object.assign({}, Common._getChainParams(baseChain));
standardChainParams['name'] = 'custom-chain';
if (typeof chainParamsOrName !== 'string') {
return new Common(Object.assign({ chain: Object.assign(Object.assign({}, standardChainParams), chainParamsOrName) }, opts));
}
else {
if (chainParamsOrName === CustomChain.PolygonMainnet) {
return Common.custom({
name: CustomChain.PolygonMainnet,
chainId: 137,
networkId: 137,
}, opts);
}
if (chainParamsOrName === CustomChain.PolygonMumbai) {
return Common.custom({
name: CustomChain.PolygonMumbai,
chainId: 80001,
networkId: 80001,
}, opts);
}
if (chainParamsOrName === CustomChain.ArbitrumRinkebyTestnet) {
return Common.custom({
name: CustomChain.ArbitrumRinkebyTestnet,
chainId: 421611,
networkId: 421611,
}, opts);
}
if (chainParamsOrName === CustomChain.xDaiChain) {
return Common.custom({
name: CustomChain.xDaiChain,
chainId: 100,
networkId: 100,
}, opts);
}
if (chainParamsOrName === CustomChain.OptimisticKovan) {
return Common.custom({
name: CustomChain.OptimisticKovan,
chainId: 69,
networkId: 69,
}, Object.assign({ hardfork: Hardfork.Berlin }, opts));
}
if (chainParamsOrName === CustomChain.OptimisticEthereum) {
return Common.custom({
name: CustomChain.OptimisticEthereum,
chainId: 10,
networkId: 10,
}, Object.assign({ hardfork: Hardfork.Berlin }, opts));
}
throw new Error(`Custom chain ${chainParamsOrName} not supported`);
}
}
/**
* Creates a {@link Common} object for a custom chain, based on a standard one. It uses all the `Chain`
* params from {@link baseChain} except the ones overridden in {@link customChainParams}.
*
* @deprecated Use {@link Common.custom} instead
*
* @param baseChain The name (`mainnet`) or id (`1`) of a standard chain used to base the custom
* chain params on.
* @param customChainParams The custom parameters of the chain.
* @param hardfork String identifier ('byzantium') for hardfork (optional)
* @param supportedHardforks Limit parameter returns to the given hardforks (optional)
*/
static forCustomChain(baseChain, customChainParams, hardfork, supportedHardforks) {
const standardChainParams = Common._getChainParams(baseChain);
return new Common({
chain: Object.assign(Object.assign({}, standardChainParams), customChainParams),
hardfork: hardfork,
supportedHardforks: supportedHardforks,
});
}
/**
* Static method to determine if a {@link chainId} is supported as a standard chain
* @param chainId BN id (`1`) of a standard chain
* @returns boolean
*/
static isSupportedChainId(chainId) {
const initializedChains = (0, chains_1._getInitializedChains)();
return Boolean(initializedChains['names'][chainId.toString()]);
}
static _getChainParams(chain, customChains) {
const initializedChains = (0, chains_1._getInitializedChains)(customChains);
if (typeof chain === 'number' || ethereumjs_util_1.BN.isBN(chain)) {
chain = chain.toString();
if (initializedChains['names'][chain]) {
const name = initializedChains['names'][chain];
return initializedChains[name];
}
throw new Error(`Chain with ID ${chain} not supported`);
}
if (initializedChains[chain]) {
return initializedChains[chain];
}
throw new Error(`Chain with name ${chain} not supported`);
}
/**
* Sets the chain
* @param chain String ('mainnet') or Number (1) chain
* representation. Or, a Dictionary of chain parameters for a private network.
* @returns The dictionary with parameters set as chain
*/
setChain(chain) {
if (typeof chain === 'number' || typeof chain === 'string' || ethereumjs_util_1.BN.isBN(chain)) {
// Filter out genesis states if passed in to customChains
let plainCustomChains;
if (this._customChains &&
this._customChains.length > 0 &&
Array.isArray(this._customChains[0])) {
plainCustomChains = this._customChains.map((e) => e[0]);
}
else {
plainCustomChains = this._customChains;
}
this._chainParams = Common._getChainParams(chain, plainCustomChains);
}
else if (typeof chain === 'object') {
if (this._customChains.length > 0) {
throw new Error('Chain must be a string, number, or BN when initialized with customChains passed in');
}
const required = ['networkId', 'genesis', 'hardforks', 'bootstrapNodes'];
for (const param of required) {
if (chain[param] === undefined) {
throw new Error(`Missing required chain parameter: ${param}`);
}
}
this._chainParams = chain;
}
else {
throw new Error('Wrong input format');
}
return this._chainParams;
}
/**
* Sets the hardfork to get params for
* @param hardfork String identifier (e.g. 'byzantium') or {@link Hardfork} enum
*/
setHardfork(hardfork) {
if (!this._isSupportedHardfork(hardfork)) {
throw new Error(`Hardfork ${hardfork} not set as supported in supportedHardforks`);
}
let existing = false;
for (const hfChanges of hardforks_1.hardforks) {
if (hfChanges[0] === hardfork) {
if (this._hardfork !== hardfork) {
this._hardfork = hardfork;
this.emit('hardforkChanged', hardfork);
}
existing = true;
}
}
if (!existing) {
throw new Error(`Hardfork with name ${hardfork} not supported`);
}
}
/**
* Returns the hardfork based on the block number or an optional
* total difficulty (Merge HF) provided.
*
* An optional TD takes precedence in case the corresponding HF block
* is set to `null` or otherwise needs to match (if not an error
* will be thrown).
*
* @param blockNumber
* @param td
* @returns The name of the HF
*/
getHardforkByBlockNumber(blockNumber, td) {
blockNumber = (0, ethereumjs_util_1.toType)(blockNumber, ethereumjs_util_1.TypeOutput.BN);
td = (0, ethereumjs_util_1.toType)(td, ethereumjs_util_1.TypeOutput.BN);
let hardfork = Hardfork.Chainstart;
let minTdHF;
let maxTdHF;
let previousHF;
for (const hf of this.hardforks()) {
// Skip comparison for not applied HFs
if (hf.block === null) {
if (td !== undefined && td !== null && hf.td !== undefined && hf.td !== null) {
if (td.gte(new ethereumjs_util_1.BN(hf.td))) {
return hf.name;
}
}
continue;
}
if (blockNumber.gte(new ethereumjs_util_1.BN(hf.block))) {
hardfork = hf.name;
}
if (td && hf.td) {
if (td.gte(new ethereumjs_util_1.BN(hf.td))) {
minTdHF = hf.name;
}
else {
maxTdHF = previousHF;
}
}
previousHF = hf.name;
}
if (td) {
let msgAdd = `block number: ${blockNumber} (-> ${hardfork}), `;
if (minTdHF) {
if (!this.hardforkGteHardfork(hardfork, minTdHF)) {
const msg = 'HF determined by block number is lower than the minimum total difficulty HF';
msgAdd += `total difficulty: ${td} (-> ${minTdHF})`;
throw new Error(`${msg}: ${msgAdd}`);
}
}
if (maxTdHF) {
if (!this.hardforkGteHardfork(maxTdHF, hardfork)) {
const msg = 'Maximum HF determined by total difficulty is lower than the block number HF';
msgAdd += `total difficulty: ${td} (-> ${maxTdHF})`;
throw new Error(`${msg}: ${msgAdd}`);
}
}
}
return hardfork;
}
/**
* Sets a new hardfork based on the block number or an optional
* total difficulty (Merge HF) provided.
*
* An optional TD takes precedence in case the corresponding HF block
* is set to `null` or otherwise needs to match (if not an error
* will be thrown).
*
* @param blockNumber
* @param td
* @returns The name of the HF set
*/
setHardforkByBlockNumber(blockNumber, td) {
const hardfork = this.getHardforkByBlockNumber(blockNumber, td);
this.setHardfork(hardfork);
return hardfork;
}
/**
* Internal helper function to choose between hardfork set and hardfork provided as param
* @param hardfork Hardfork given to function as a parameter
* @returns Hardfork chosen to be used
*/
_chooseHardfork(hardfork, onlySupported = true) {
if (!hardfork) {
hardfork = this._hardfork;
}
else if (onlySupported && !this._isSupportedHardfork(hardfork)) {
throw new Error(`Hardfork ${hardfork} not set as supported in supportedHardforks`);
}
return hardfork;
}
/**
* Internal helper function, returns the params for the given hardfork for the chain set
* @param hardfork Hardfork name
* @returns Dictionary with hardfork params
*/
_getHardfork(hardfork) {
const hfs = this.hardforks();
for (const hf of hfs) {
if (hf['name'] === hardfork)
return hf;
}
throw new Error(`Hardfork ${hardfork} not defined for chain ${this.chainName()}`);
}
/**
* Internal helper function to check if a hardfork is set to be supported by the library
* @param hardfork Hardfork name
* @returns True if hardfork is supported
*/
_isSupportedHardfork(hardfork) {
if (this._supportedHardforks.length > 0) {
for (const supportedHf of this._supportedHardforks) {
if (hardfork === supportedHf)
return true;
}
}
else {
return true;
}
return false;
}
/**
* Sets the active EIPs
* @param eips
*/
setEIPs(eips = []) {
for (const eip of eips) {
if (!(eip in eips_1.EIPs)) {
throw new Error(`${eip} not supported`);
}
const minHF = this.gteHardfork(eips_1.EIPs[eip]['minimumHardfork']);
if (!minHF) {
throw new Error(`${eip} cannot be activated on hardfork ${this.hardfork()}, minimumHardfork: ${minHF}`);
}
if (eips_1.EIPs[eip].requiredEIPs) {
;
eips_1.EIPs[eip].requiredEIPs.forEach((elem) => {
if (!(eips.includes(elem) || this.isActivatedEIP(elem))) {
throw new Error(`${eip} requires EIP ${elem}, but is not included in the EIP list`);
}
});
}
}
this._eips = eips;
}
/**
* Returns a parameter for the current chain setup
*
* If the parameter is present in an EIP, the EIP always takes precendence.
* Otherwise the parameter if taken from the latest applied HF with
* a change on the respective parameter.
*
* @param topic Parameter topic ('gasConfig', 'gasPrices', 'vm', 'pow')
* @param name Parameter name (e.g. 'minGasLimit' for 'gasConfig' topic)
* @returns The value requested or `null` if not found
*/
param(topic, name) {
// TODO: consider the case that different active EIPs
// can change the same parameter
let value = null;
for (const eip of this._eips) {
value = this.paramByEIP(topic, name, eip);
if (value !== null) {
return value;
}
}
return this.paramByHardfork(topic, name, this._hardfork);
}
/**
* Returns the parameter corresponding to a hardfork
* @param topic Parameter topic ('gasConfig', 'gasPrices', 'vm', 'pow')
* @param name Parameter name (e.g. 'minGasLimit' for 'gasConfig' topic)
* @param hardfork Hardfork name
* @returns The value requested or `null` if not found
*/
paramByHardfork(topic, name, hardfork) {
hardfork = this._chooseHardfork(hardfork);
let value = null;
for (const hfChanges of hardforks_1.hardforks) {
// EIP-referencing HF file (e.g. berlin.json)
if ('eips' in hfChanges[1]) {
const hfEIPs = hfChanges[1]['eips'];
for (const eip of hfEIPs) {
const valueEIP = this.paramByEIP(topic, name, eip);
value = valueEIP !== null ? valueEIP : value;
}
// Paramater-inlining HF file (e.g. istanbul.json)
}
else {
if (!hfChanges[1][topic]) {
throw new Error(`Topic ${topic} not defined`);
}
if (hfChanges[1][topic][name] !== undefined) {
value = hfChanges[1][topic][name].v;
}
}
if (hfChanges[0] === hardfork)
break;
}
return value;
}
/**
* Returns a parameter corresponding to an EIP
* @param topic Parameter topic ('gasConfig', 'gasPrices', 'vm', 'pow')
* @param name Parameter name (e.g. 'minGasLimit' for 'gasConfig' topic)
* @param eip Number of the EIP
* @returns The value requested or `null` if not found
*/
paramByEIP(topic, name, eip) {
if (!(eip in eips_1.EIPs)) {
throw new Error(`${eip} not supported`);
}
const eipParams = eips_1.EIPs[eip];
if (!(topic in eipParams)) {
throw new Error(`Topic ${topic} not defined`);
}
if (eipParams[topic][name] === undefined) {
return null;
}
const value = eipParams[topic][name].v;
return value;
}
/**
* Returns a parameter for the hardfork active on block number
* @param topic Parameter topic
* @param name Parameter name
* @param blockNumber Block number
*/
paramByBlock(topic, name, blockNumber) {
const activeHfs = this.activeHardforks(blockNumber);
const hardfork = activeHfs[activeHfs.length - 1]['name'];
return this.paramByHardfork(topic, name, hardfork);
}
/**
* Checks if an EIP is activated by either being included in the EIPs
* manually passed in with the {@link CommonOpts.eips} or in a
* hardfork currently being active
*
* Note: this method only works for EIPs being supported
* by the {@link CommonOpts.eips} constructor option
* @param eip
*/
isActivatedEIP(eip) {
if (this.eips().includes(eip)) {
return true;
}
for (const hfChanges of hardforks_1.hardforks) {
const hf = hfChanges[1];
if (this.gteHardfork(hf['name']) && 'eips' in hf) {
if (hf['eips'].includes(eip)) {
return true;
}
}
}
return false;
}
/**
* Checks if set or provided hardfork is active on block number
* @param hardfork Hardfork name or null (for HF set)
* @param blockNumber
* @param opts Hardfork options (onlyActive unused)
* @returns True if HF is active on block number
*/
hardforkIsActiveOnBlock(hardfork, blockNumber, opts = {}) {
var _a;
blockNumber = (0, ethereumjs_util_1.toType)(blockNumber, ethereumjs_util_1.TypeOutput.BN);
const onlySupported = (_a = opts.onlySupported) !== null && _a !== void 0 ? _a : false;
hardfork = this._chooseHardfork(hardfork, onlySupported);
const hfBlock = this.hardforkBlockBN(hardfork);
if (hfBlock && blockNumber.gte(hfBlock)) {
return true;
}
return false;
}
/**
* Alias to hardforkIsActiveOnBlock when hardfork is set
* @param blockNumber
* @param opts Hardfork options (onlyActive unused)
* @returns True if HF is active on block number
*/
activeOnBlock(blockNumber, opts) {
return this.hardforkIsActiveOnBlock(null, blockNumber, opts);
}
/**
* Sequence based check if given or set HF1 is greater than or equal HF2
* @param hardfork1 Hardfork name or null (if set)
* @param hardfork2 Hardfork name
* @param opts Hardfork options
* @returns True if HF1 gte HF2
*/
hardforkGteHardfork(hardfork1, hardfork2, opts = {}) {
const onlyActive = opts.onlyActive === undefined ? false : opts.onlyActive;
hardfork1 = this._chooseHardfork(hardfork1, opts.onlySupported);
let hardforks;
if (onlyActive) {
hardforks = this.activeHardforks(null, opts);
}
else {
hardforks = this.hardforks();
}
let posHf1 = -1, posHf2 = -1;
let index = 0;
for (const hf of hardforks) {
if (hf['name'] === hardfork1)
posHf1 = index;
if (hf['name'] === hardfork2)
posHf2 = index;
index += 1;
}
return posHf1 >= posHf2 && posHf2 !== -1;
}
/**
* Alias to hardforkGteHardfork when hardfork is set
* @param hardfork Hardfork name
* @param opts Hardfork options
* @returns True if hardfork set is greater than hardfork provided
*/
gteHardfork(hardfork, opts) {
return this.hardforkGteHardfork(null, hardfork, opts);
}
/**
* Checks if given or set hardfork is active on the chain
* @param hardfork Hardfork name, optional if HF set
* @param opts Hardfork options (onlyActive unused)
* @returns True if hardfork is active on the chain
*/
hardforkIsActiveOnChain(hardfork, opts = {}) {
var _a;
const onlySupported = (_a = opts.onlySupported) !== null && _a !== void 0 ? _a : false;
hardfork = this._chooseHardfork(hardfork, onlySupported);
for (const hf of this.hardforks()) {
if (hf['name'] === hardfork && hf['block'] !== null)
return true;
}
return false;
}
/**
* Returns the active hardfork switches for the current chain
* @param blockNumber up to block if provided, otherwise for the whole chain
* @param opts Hardfork options (onlyActive unused)
* @return Array with hardfork arrays
*/
activeHardforks(blockNumber, opts = {}) {
const activeHardforks = [];
const hfs = this.hardforks();
for (const hf of hfs) {
if (hf['block'] === null)
continue;
if (blockNumber !== undefined && blockNumber !== null && blockNumber < hf['block'])
break;
if (opts.onlySupported && !this._isSupportedHardfork(hf['name']))
continue;
activeHardforks.push(hf);
}
return activeHardforks;
}
/**
* Returns the latest active hardfork name for chain or block or throws if unavailable
* @param blockNumber up to block if provided, otherwise for the whole chain
* @param opts Hardfork options (onlyActive unused)
* @return Hardfork name
*/
activeHardfork(blockNumber, opts = {}) {
const activeHardforks = this.activeHardforks(blockNumber, opts);
if (activeHardforks.length > 0) {
return activeHardforks[activeHardforks.length - 1]['name'];
}
else {
throw new Error(`No (supported) active hardfork found`);
}
}
/**
* Returns the hardfork change block for hardfork provided or set
* @param hardfork Hardfork name, optional if HF set
* @returns Block number or null if unscheduled
* @deprecated Please use {@link Common.hardforkBlockBN} for large number support
*/
hardforkBlock(hardfork) {
const block = this.hardforkBlockBN(hardfork);
return (0, ethereumjs_util_1.toType)(block, ethereumjs_util_1.TypeOutput.Number);
}
/**
* Returns the hardfork change block for hardfork provided or set
* @param hardfork Hardfork name, optional if HF set
* @returns Block number or null if unscheduled
*/
hardforkBlockBN(hardfork) {
hardfork = this._chooseHardfork(hardfork, false);
const block = this._getHardfork(hardfork)['block'];
if (block === undefined || block === null) {
return null;
}
return new ethereumjs_util_1.BN(block);
}
/**
* Returns the hardfork change total difficulty (Merge HF) for hardfork provided or set
* @param hardfork Hardfork name, optional if HF set
* @returns Total difficulty or null if no set
*/
hardforkTD(hardfork) {
hardfork = this._chooseHardfork(hardfork, false);
const td = this._getHardfork(hardfork)['td'];
if (td === undefined || td === null) {
return null;
}
return new ethereumjs_util_1.BN(td);
}
/**
* True if block number provided is the hardfork (given or set) change block
* @param blockNumber Number of the block to check
* @param hardfork Hardfork name, optional if HF set
* @returns True if blockNumber is HF block
*/
isHardforkBlock(blockNumber, hardfork) {
blockNumber = (0, ethereumjs_util_1.toType)(blockNumber, ethereumjs_util_1.TypeOutput.BN);
hardfork = this._chooseHardfork(hardfork, false);
const block = this.hardforkBlockBN(hardfork);
return block ? block.eq(blockNumber) : false;
}
/**
* Returns the change block for the next hardfork after the hardfork provided or set
* @param hardfork Hardfork name, optional if HF set
* @returns Block number or null if not available
* @deprecated Please use {@link Common.nextHardforkBlockBN} for large number support
*/
nextHardforkBlock(hardfork) {
const block = this.nextHardforkBlockBN(hardfork);
return (0, ethereumjs_util_1.toType)(block, ethereumjs_util_1.TypeOutput.Number);
}
/**
* Returns the change block for the next hardfork after the hardfork provided or set
* @param hardfork Hardfork name, optional if HF set
* @returns Block number or null if not available
*/
nextHardforkBlockBN(hardfork) {
hardfork = this._chooseHardfork(hardfork, false);
const hfBlock = this.hardforkBlockBN(hardfork);
if (hfBlock === null) {
return null;
}
// Next fork block number or null if none available
// Logic: if accumulator is still null and on the first occurrence of
// a block greater than the current hfBlock set the accumulator,
// pass on the accumulator as the final result from this time on
const nextHfBlock = this.hardforks().reduce((acc, hf) => {
const block = new ethereumjs_util_1.BN(hf.block);
return block.gt(hfBlock) && acc === null ? block : acc;
}, null);
return nextHfBlock;
}
/**
* True if block number provided is the hardfork change block following the hardfork given or set
* @param blockNumber Number of the block to check
* @param hardfork Hardfork name, optional if HF set
* @returns True if blockNumber is HF block
*/
isNextHardforkBlock(blockNumber, hardfork) {
blockNumber = (0, ethereumjs_util_1.toType)(blockNumber, ethereumjs_util_1.TypeOutput.BN);
hardfork = this._chooseHardfork(hardfork, false);
const nextHardforkBlock = this.nextHardforkBlockBN(hardfork);
return nextHardforkBlock === null ? false : nextHardforkBlock.eq(blockNumber);
}
/**
* Internal helper function to calculate a fork hash
* @param hardfork Hardfork name
* @returns Fork hash as hex string
*/
_calcForkHash(hardfork) {
const genesis = Buffer.from(this.genesis().hash.substr(2), 'hex');
let hfBuffer = Buffer.alloc(0);
let prevBlock = 0;
for (const hf of this.hardforks()) {
const block = hf.block;
// Skip for chainstart (0), not applied HFs (null) and
// when already applied on same block number HFs
if (block !== 0 && block !== null && block !== prevBlock) {
const hfBlockBuffer = Buffer.from(block.toString(16).padStart(16, '0'), 'hex');
hfBuffer = Buffer.concat([hfBuffer, hfBlockBuffer]);
}
if (hf.name === hardfork)
break;
if (block !== null) {
prevBlock = block;
}
}
const inputBuffer = Buffer.concat([genesis, hfBuffer]);
// CRC32 delivers result as signed (negative) 32-bit integer,
// convert to hex string
const forkhash = (0, ethereumjs_util_1.intToBuffer)((0, crc_32_1.buf)(inputBuffer) >>> 0).toString('hex');
return `0x${forkhash}`;
}
/**
* Returns an eth/64 compliant fork hash (EIP-2124)
* @param hardfork Hardfork name, optional if HF set
*/
forkHash(hardfork) {
hardfork = this._chooseHardfork(hardfork, false);
const data = this._getHardfork(hardfork);
if (data['block'] === null && data['td'] === undefined) {
const msg = 'No fork hash calculation possible for future hardfork';
throw new Error(msg);
}
if (data['forkHash'] !== undefined) {
return data['forkHash'];
}
return this._calcForkHash(hardfork);
}
/**
*
* @param forkHash Fork hash as a hex string
* @returns Array with hardfork data (name, block, forkHash)
*/
hardforkForForkHash(forkHash) {
const resArray = this.hardforks().filter((hf) => {
return hf.forkHash === forkHash;
});
return resArray.length >= 1 ? resArray[resArray.length - 1] : null;
}
/**
* Returns the Genesis parameters of the current chain
* @returns Genesis dictionary
*/
genesis() {
return this._chainParams['genesis'];
}
/**
* Returns the Genesis state of the current chain,
* all values are provided as hex-prefixed strings.
*/
genesisState() {
// Use require statements here in favor of import statements
// to load json files on demand
// (high memory usage by large mainnet.json genesis state file)
switch (this.chainName()) {
case 'mainnet':
return require('./genesisStates/mainnet.json');
case 'ropsten':
return require('./genesisStates/ropsten.json');
case 'rinkeby':
return require('./genesisStates/rinkeby.json');
case 'kovan':
return require('./genesisStates/kovan.json');
case 'goerli':
return require('./genesisStates/goerli.json');
case 'sepolia':
return require('./genesisStates/sepolia.json');
}
// Custom chains with genesis state provided
if (this._customChains &&
this._customChains.length > 0 &&
Array.isArray(this._customChains[0])) {
for (const chainArrayWithGenesis of this._customChains) {
if (chainArrayWithGenesis[0].name === this.chainName()) {
return chainArrayWithGenesis[1];
}
}
}
return {};
}
/**
* Returns the hardforks for current chain
* @returns {Array} Array with arrays of hardforks
*/
hardforks() {
return this._chainParams['hardforks'];
}
/**
* Returns bootstrap nodes for the current chain
* @returns {Dictionary} Dict with bootstrap nodes
*/
bootstrapNodes() {
return this._chainParams['bootstrapNodes'];
}
/**
* Returns DNS networks for the current chain
* @returns {String[]} Array of DNS ENR urls
*/
dnsNetworks() {
return this._chainParams['dnsNetworks'];
}
/**
* Returns the hardfork set
* @returns Hardfork name
*/
hardfork() {
return this._hardfork;
}
/**
* Returns the Id of current chain
* @returns chain Id
* @deprecated Please use {@link Common.chainIdBN} for large number support
*/
chainId() {
return (0, ethereumjs_util_1.toType)(this.chainIdBN(), ethereumjs_util_1.TypeOutput.Number);
}
/**
* Returns the Id of current chain
* @returns chain Id
*/
chainIdBN() {
return new ethereumjs_util_1.BN(this._chainParams['chainId']);
}
/**
* Returns the name of current chain
* @returns chain name (lower case)
*/
chainName() {
return this._chainParams['name'];
}
/**
* Returns the Id of current network
* @returns network Id
* @deprecated Please use {@link Common.networkIdBN} for large number support
*/
networkId() {
return (0, ethereumjs_util_1.toType)(this.networkIdBN(), ethereumjs_util_1.TypeOutput.Number);
}
/**
* Returns the Id of current network
* @returns network Id
*/
networkIdBN() {
return new ethereumjs_util_1.BN(this._chainParams['networkId']);
}
/**
* Returns the active EIPs
* @returns List of EIPs
*/
eips() {
return this._eips;
}
/**
* Returns the consensus type of the network
* Possible values: "pow"|"poa"|"pos"
*
* Note: This value can update along a hardfork.
*/
consensusType() {
const hardfork = this.hardfork();
let value;
for (const hfChanges of hardforks_1.hardforks) {
if ('consensus' in hfChanges[1]) {
value = hfChanges[1]['consensus']['type'];
}
if (hfChanges[0] === hardfork)
break;
}
if (value) {
return value;
}
return this._chainParams['consensus']['type'];
}
/**
* Returns the concrete consensus implementation
* algorithm or protocol for the network
* e.g. "ethash" for "pow" consensus type,
* "clique" for "poa" consensus type or
* "casper" for "pos" consensus type.
*
* Note: This value can update along a hardfork.
*/
consensusAlgorithm() {
const hardfork = this.hardfork();
let value;
for (const hfChanges of hardforks_1.hardforks) {
if ('consensus' in hfChanges[1]) {
value = hfChanges[1]['consensus']['algorithm'];
}
if (hfChanges[0] === hardfork)
break;
}
if (value) {
return value;
}
return this._chainParams['consensus']['algorithm'];
}
/**
* Returns a dictionary with consensus configuration
* parameters based on the consensus algorithm
*
* Expected returns (parameters must be present in
* the respective chain json files):
*
* ethash: -
* clique: period, epoch
* aura: -
* casper: -
*
* Note: This value can update along a hardfork.
*/
consensusConfig() {
const hardfork = this.hardfork();
let value;
for (const hfChanges of hardforks_1.hardforks) {
if ('consensus' in hfChanges[1]) {
// The config parameter is named after the respective consensus algorithm
value = hfChanges[1]['consensus'][hfChanges[1]['consensus']['algorithm']];
}
if (hfChanges[0] === hardfork)
break;
}
if (value) {
return value;
}
const consensusAlgorithm = this.consensusAlgorithm();
return this._chainParams['consensus'][consensusAlgorithm];
}
/**
* Returns a deep copy of this {@link Common} instance.
*/
copy() {
const copy = Object.assign(Object.create(Object.getPrototypeOf(this)), this);
copy.removeAllListeners();
return copy;
}
}
exports.default = Common;
exports.default = void 0;
var common_1 = require("./common");
Object.defineProperty(exports, "default", { enumerable: true, get: function () { return common_1.Common; } });
__exportStar(require("./enums"), exports);
__exportStar(require("./types"), exports);
//# sourceMappingURL=index.js.map

@@ -1,53 +0,35 @@

/// <reference types="bn.js" />
import { BN, PrefixedHexString } from 'ethereumjs-util';
import { ConsensusAlgorithm, ConsensusType, Hardfork as HardforkName } from '.';
export interface genesisStatesType {
names: {
[key: string]: string;
};
[key: string]: {};
import { ConsensusAlgorithm, ConsensusType, Hardfork, Chain } from './enums';
export interface ChainName {
[chainId: string]: string;
}
export interface chainsType {
names: {
[key: string]: string;
};
[key: string]: any;
export interface ChainsConfig {
[key: string]: ChainConfig | ChainName;
}
export interface Chain {
export declare type CliqueConfig = {
period: number;
epoch: number;
};
export declare type EthashConfig = {};
export declare type CasperConfig = {};
export interface ChainConfig {
name: string;
chainId: number | BN;
networkId: number | BN;
defaultHardfork?: string;
chainId: number | bigint;
networkId: number | bigint;
defaultHardfork: string;
comment: string;
url: string;
genesis: GenesisBlock;
hardforks: Hardfork[];
bootstrapNodes: BootstrapNode[];
genesis: GenesisBlockConfig;
hardforks: HardforkConfig[];
bootstrapNodes: BootstrapNodeConfig[];
dnsNetworks?: string[];
consensus?: {
consensus: {
type: ConsensusType | string;
algorithm: ConsensusAlgorithm | string;
clique?: {
period: number;
epoch: number;
};
ethash?: any;
casper?: any;
clique?: CliqueConfig;
ethash?: EthashConfig;
casper?: CasperConfig;
};
}
declare type StoragePair = [key: PrefixedHexString, value: PrefixedHexString];
export declare type AccountState = [
balance: PrefixedHexString,
code: PrefixedHexString,
storage: Array<StoragePair>
];
export interface GenesisState {
[key: PrefixedHexString]: PrefixedHexString | AccountState;
}
export interface eipsType {
[key: number]: any;
}
export interface GenesisBlock {
hash: string;
timestamp: string | null;
export interface GenesisBlockConfig {
timestamp?: string;
gasLimit: number;

@@ -57,7 +39,6 @@ difficulty: number;

extraData: string;
stateRoot: string;
baseFeePerGas?: string;
}
export interface Hardfork {
name: HardforkName | string;
export interface HardforkConfig {
name: Hardfork | string;
block: number | null;

@@ -67,3 +48,3 @@ td?: number;

}
export interface BootstrapNode {
export interface BootstrapNodeConfig {
ip: string;

@@ -77,2 +58,53 @@ port: number | string;

}
interface BaseOpts {
/**
* String identifier ('byzantium') for hardfork or {@link Hardfork} enum.
*
* Default: Hardfork.London
*/
hardfork?: string | Hardfork;
/**
* Selected EIPs which can be activated, please use an array for instantiation
* (e.g. `eips: [ 2537, ]`)
*
* Currently supported:
*
* - [EIP-2537](https://eips.ethereum.org/EIPS/eip-2537) - BLS12-381 precompiles
*/
eips?: number[];
}
/**
* Options for instantiating a {@link Common} instance.
*/
export interface CommonOpts extends BaseOpts {
/**
* Chain name ('mainnet'), id (1), or {@link Chain} enum,
* either from a chain directly supported or a custom chain
* passed in via {@link CommonOpts.customChains}.
*/
chain: string | number | Chain | bigint | object;
/**
* Initialize (in addition to the supported chains) with the selected
* custom chains. Custom genesis state should be passed to the Blockchain class if used.
*
* Usage (directly with the respective chain initialization via the {@link CommonOpts.chain} option):
*
* ```javascript
* import myCustomChain1 from '[PATH_TO_MY_CHAINS]/myCustomChain1.json'
* const common = new Common({ chain: 'myCustomChain1', customChains: [ myCustomChain1 ]})
* ```
*/
customChains?: ChainConfig[];
}
/**
* Options to be used with the {@link Common.custom} static constructor.
*/
export interface CustomCommonOpts extends BaseOpts {
/**
* The name (`mainnet`), id (`1`), or {@link Chain} enum of
* a standard chain used to base the custom chain params on.
*/
baseChain?: string | number | Chain | bigint;
}
export {};
//# sourceMappingURL=types.d.ts.map
{
"name": "@ethereumjs/common",
"version": "2.6.5",
"version": "3.0.0-beta.1",
"description": "Resources common to all Ethereum implementations",

@@ -17,3 +17,2 @@ "license": "MIT",

"dist",
"dist.browser",
"src"

@@ -23,7 +22,4 @@ ],

"types": "dist/index.d.ts",
"browser": "dist.browser/index.js",
"scripts": {
"build": "npm run build:node && npm run build:browser",
"build:node": "../../config/cli/ts-build.sh node",
"build:browser": "../../config/cli/ts-build.sh browser",
"build": "../../config/cli/ts-build.sh",
"prepublishOnly": "../../config/cli/prepublish.sh",

@@ -43,3 +39,3 @@ "clean": "../../config/cli/clean-package.sh",

"crc-32": "^1.2.0",
"ethereumjs-util": "^7.1.5"
"@ethereumjs/util": "8.0.0-beta.1"
},

@@ -46,0 +42,0 @@ "devDependencies": {

@@ -45,3 +45,3 @@ # @ethereumjs/common

Current `DEFAULT_HARDFORK`: `istanbul`
Current `DEFAULT_HARDFORK`: `london`

@@ -59,5 +59,2 @@ Here are some simple usage examples:

// Access genesis data for Ropsten network
c.genesis().hash // 0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d
// Get bootstrap nodes for chain/network

@@ -70,14 +67,2 @@ c.bootstrapNodes() // Array with current nodes

If the initializing library only supports a certain range of `hardforks` you can use the `supportedHardforks` option to restrict hardfork access on the `Common` instance:
```typescript
const c = new Common({
chain: 'ropsten',
supportedHardforks: ['byzantium', 'constantinople', 'petersburg'],
})
```
This will throw an error when a param is requested for an unsupported hardfork
to prevent unpredictable behavior.
For an improved developer experience, there are `Chain` and `Hardfork` enums available:

@@ -220,44 +205,4 @@

It is also possible (`v2.5.0`+) to pass in a custom genesis state file (see e.g. `src/genesisStates/goerli.json` for an example on the format needed) along with the custom chain configuration:
Custom genesis states should be passed to the `@ethereumjs/blockchain` directly.
```typescript
import myCustomChain1 from '[PATH_TO_MY_CHAINS]/myCustomChain1.json'
import chain1GenesisState from '[PATH_TO_GENESIS_STATES]/chain1GenesisState.json'
const common = new Common({
chain: 'myCustomChain1',
customChains: [[myCustomChain1, chain1GenesisState]],
})
```
A more complex example with genesis state with Contract and EoA states would have the following format:
```typescript
const complexState = {
// For EoA
'0x0...01': '0x100',
// For contracts
'0x0...02': [
'0x1',
'0xRUNTIME_BYTECODE',
[
[key1, value1],
[key2, value2],
],
],
}
import myCustomChain1 from '[PATH_TO_MY_CHAINS]/myCustomChain1.json'
const common = new Common({
chain: 'myCustomChain1',
customChains: [[myCustomChain1, complexState]],
})
```
Accessing the genesis state can be done as follows:
```typescript
const genesisState = common.genesisState()
```
This now also provides direct access to custom genesis states passed into `Common` as described above. The old Common-separate `genesisStateByName()` and `genesisStateById()` functions are now `deprecated` and usage should be avoided.
## Hardforks

@@ -295,7 +240,6 @@

- `petersburg` (`Hardfork.Petersburg`) (aka `constantinopleFix`, apply together with `constantinople`)
- `istanbul` (`Hardfork.Istanbul`) (`DEFAULT_HARDFORK` (`v2.0.0` release series))
- `istanbul` (`Hardfork.Instanbul`)
- `muirGlacier` (`Hardfork.MuirGlacier`)
- `berlin` (`Hardfork.Berlin`) (since `v2.2.0`)
- `london` (`Hardfork.London`) (since `v2.4.0`)
- `grayGlacier` (`Hardfork.GrayGlacier`) (since `v2.6.5`)
- `london` (`Hardfork.London`) (`DEFAULT_HARDFORK`) (since `v2.4.0`)
- `merge` (`Hardfork.Merge`) (since `v2.5.0`, `experimental`)

@@ -354,3 +298,2 @@

- [EIP-4399](https://eips.ethereum.org/EIPS/eip-4399): Supplant DIFFICULTY opcode with PREVRANDAO (Merge) (`experimental`)
- [EIP-5133](https://eips.ethereum.org/EIPS/eip-5133): Delaying the difficulty bomb to Mid September 2022

@@ -357,0 +300,0 @@ ## Bootstrap Nodes

@@ -5,3 +5,3 @@ {

"networkId": 5,
"defaultHardfork": "istanbul",
"defaultHardfork": "london",
"consensus": {

@@ -18,3 +18,2 @@ "type": "poa",

"genesis": {
"hash": "0xbf7e331f7f7c1dd2e05159666b3bf8bc7a8a3a9eb1d518969eab529dd9b88c1a",
"timestamp": "0x5c51a607",

@@ -24,4 +23,3 @@ "gasLimit": 10485760,

"nonce": "0x0000000000000000",
"extraData": "0x22466c6578692069732061207468696e6722202d204166726900000000000000e0a2bd4258d2768837baa26a28fe71dc079f84c70000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"stateRoot": "0x5d6cded585e73c4e322c30c2f782a336316f17dd85a4863b9d838d2d4b8b3008"
"extraData": "0x22466c6578692069732061207468696e6722202d204166726900000000000000e0a2bd4258d2768837baa26a28fe71dc079f84c70000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
},

@@ -73,6 +71,6 @@ "hardforks": [

"forkHash": "0x757a1c47"
},
},
{
"name": "london",
"block": 5062605,
"block": 5062605,
"forkHash": "0xb8c6299d"

@@ -79,0 +77,0 @@ },

@@ -5,7 +5,10 @@ {

"networkId": 42,
"defaultHardfork": "istanbul",
"defaultHardfork": "london",
"consensus": {
"type": "poa",
"algorithm": "aura",
"aura": {}
"algorithm": "clique",
"clique": {
"period": 15,
"epoch": 30000
}
},

@@ -15,9 +18,6 @@ "comment": "Parity PoA test network",

"genesis": {
"hash": "0xa3c565fc15c7478862d50ccd6561e3c06b24cc509bf388941c25ea985ce32cb9",
"timestamp": null,
"gasLimit": 6000000,
"difficulty": 131072,
"nonce": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"extraData": "0x",
"stateRoot": "0x2480155b48a1cea17d67dbfdfaafe821c1d19cdd478c5358e8ec56dec24502b2"
"extraData": "0x"
},

@@ -69,3 +69,3 @@ "hardforks": [

"forkHash": "0x1a0f10d9"
},
},
{

@@ -72,0 +72,0 @@ "name": "london",

@@ -5,3 +5,3 @@ {

"networkId": 1,
"defaultHardfork": "istanbul",
"defaultHardfork": "london",
"consensus": {

@@ -15,9 +15,6 @@ "type": "pow",

"genesis": {
"hash": "0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3",
"timestamp": null,
"gasLimit": 5000,
"difficulty": 17179869184,
"nonce": "0x0000000000000042",
"extraData": "0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fa",
"stateRoot": "0xd7f8974fb5ac78d9ac099b9ad5018bedc2ce0a72dad1827a1709da30580f0544"
"extraData": "0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fa"
},

@@ -24,0 +21,0 @@ "hardforks": [

@@ -5,3 +5,3 @@ {

"networkId": 4,
"defaultHardfork": "istanbul",
"defaultHardfork": "london",
"consensus": {

@@ -18,3 +18,2 @@ "type": "poa",

"genesis": {
"hash": "0x6341fd3daf94b748c72ced5a5b26028f2474f5f00d824504e4fa37a75767e177",
"timestamp": "0x58ee40ba",

@@ -24,4 +23,3 @@ "gasLimit": 4700000,

"nonce": "0x0000000000000000",
"extraData": "0x52657370656374206d7920617574686f7269746168207e452e436172746d616e42eb768f2244c8811c63729a21a3569731535f067ffc57839b00206d1ad20c69a1981b489f772031b279182d99e65703f0076e4812653aab85fca0f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"stateRoot": "0x53580584816f617295ea26c0e17641e0120cab2f0a8ffb53a866fd53aa8e8c2d"
"extraData": "0x52657370656374206d7920617574686f7269746168207e452e436172746d616e42eb768f2244c8811c63729a21a3569731535f067ffc57839b00206d1ad20c69a1981b489f772031b279182d99e65703f0076e4812653aab85fca0f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
},

@@ -73,6 +71,6 @@ "hardforks": [

"forkHash": "0x6910c8bd"
},
},
{
"name": "london",
"block": 8897988,
"block": 8897988,
"forkHash": "0x8e29f2f3"

@@ -79,0 +77,0 @@ },

@@ -5,3 +5,3 @@ {

"networkId": 3,
"defaultHardfork": "istanbul",
"defaultHardfork": "london",
"consensus": {

@@ -15,9 +15,6 @@ "type": "pow",

"genesis": {
"hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d",
"timestamp": null,
"gasLimit": 16777216,
"difficulty": 1048576,
"nonce": "0x0000000000000042",
"extraData": "0x3535353535353535353535353535353535353535353535353535353535353535",
"stateRoot": "0x217b0bbcfb72e2d57e28f33cb361b9983513177755dc3f33ce3e7022ed62b77b"
"extraData": "0x3535353535353535353535353535353535353535353535353535353535353535"
},

@@ -74,6 +71,6 @@ "hardforks": [

"forkHash": "0xa157d377"
},
},
{
"name": "london",
"block": 10499401,
"block": 10499401,
"forkHash": "0x7119b6b3"

@@ -80,0 +77,0 @@ },

@@ -5,3 +5,3 @@ {

"networkId": 11155111,
"defaultHardfork": "istanbul",
"defaultHardfork": "london",
"consensus": {

@@ -15,3 +15,2 @@ "type": "pow",

"genesis": {
"hash": "0x25a5cc106eea7138acab33231d7160d69cb777ee0c2c553fcddf5138993e6dd9",
"timestamp": "0x6159af19",

@@ -21,4 +20,3 @@ "gasLimit": 30000000,

"nonce": "0x0000000000000000",
"extraData": "0x5365706f6c69612c20417468656e732c204174746963612c2047726565636521",
"stateRoot": "0x5eb6e371a698b8d68f665192350ffcecbbbf322916f4b51bd79bb6887da3f494"
"extraData": "0x5365706f6c69612c20417468656e732c204174746963612c2047726565636521"
},

@@ -75,6 +73,6 @@ "hardforks": [

"forkHash": "0xfe3366e7"
},
},
{
"name": "london",
"block": 0,
"block": 0,
"forkHash": "0xfe3366e7"

@@ -81,0 +79,0 @@ },

@@ -1,4 +0,2 @@

import { eipsType } from './../types'
export const EIPs: eipsType = {
export const EIPs: { [key: number]: any } = {
1153: require('./1153.json'),

@@ -12,2 +10,3 @@ 1559: require('./1559.json'),

2930: require('./2930.json'),
3074: require('./3074.json'),
3198: require('./3198.json'),

@@ -14,0 +13,0 @@ 3529: require('./3529.json'),

@@ -1,1238 +0,3 @@

import { EventEmitter } from 'events'
import { buf as crc32Buffer } from 'crc-32'
import { BN, BNLike, toType, TypeOutput, intToBuffer } from 'ethereumjs-util'
import { _getInitializedChains } from './chains'
import { hardforks as HARDFORK_CHANGES } from './hardforks'
import { EIPs } from './eips'
import {
BootstrapNode,
Chain as IChain,
GenesisBlock,
GenesisState,
Hardfork as HardforkParams,
} from './types'
export enum CustomChain {
/**
* Polygon (Matic) Mainnet
*
* - [Documentation](https://docs.matic.network/docs/develop/network-details/network)
*/
PolygonMainnet = 'polygon-mainnet',
/**
* Polygon (Matic) Mumbai Testnet
*
* - [Documentation](https://docs.matic.network/docs/develop/network-details/network)
*/
PolygonMumbai = 'polygon-mumbai',
/**
* Arbitrum Rinkeby Testnet
*
* - [Documentation](https://developer.offchainlabs.com/docs/public_testnet)
*/
ArbitrumRinkebyTestnet = 'arbitrum-rinkeby-testnet',
/**
* xDai EVM sidechain with a native stable token
*
* - [Documentation](https://www.xdaichain.com/)
*/
xDaiChain = 'x-dai-chain',
/**
* Optimistic Kovan - testnet for Optimism roll-up
*
* - [Documentation](https://community.optimism.io/docs/developers/tutorials.html)
*/
OptimisticKovan = 'optimistic-kovan',
/**
* Optimistic Ethereum - mainnet for Optimism roll-up
*
* - [Documentation](https://community.optimism.io/docs/developers/tutorials.html)
*/
OptimisticEthereum = 'optimistic-ethereum',
}
export enum Chain {
Mainnet = 1,
Ropsten = 3,
Rinkeby = 4,
Kovan = 42,
Goerli = 5,
Sepolia = 11155111,
}
export enum Hardfork {
Chainstart = 'chainstart',
Homestead = 'homestead',
Dao = 'dao',
TangerineWhistle = 'tangerineWhistle',
SpuriousDragon = 'spuriousDragon',
Byzantium = 'byzantium',
Constantinople = 'constantinople',
Petersburg = 'petersburg',
Istanbul = 'istanbul',
MuirGlacier = 'muirGlacier',
Berlin = 'berlin',
London = 'london',
ArrowGlacier = 'arrowGlacier',
GrayGlacier = 'grayGlacier',
MergeForkIdTransition = 'mergeForkIdTransition',
Merge = 'merge',
Shanghai = 'shanghai',
}
export enum ConsensusType {
ProofOfStake = 'pos',
ProofOfWork = 'pow',
ProofOfAuthority = 'poa',
}
export enum ConsensusAlgorithm {
Ethash = 'ethash',
Clique = 'clique',
Casper = 'casper',
}
interface BaseOpts {
/**
* String identifier ('byzantium') for hardfork or {@link Hardfork} enum.
*
* Default: Hardfork.Istanbul
*/
hardfork?: string | Hardfork
/**
* Limit parameter returns to the given hardforks
*/
supportedHardforks?: Array<string | Hardfork>
/**
* Selected EIPs which can be activated, please use an array for instantiation
* (e.g. `eips: [ 2537, ]`)
*
* Currently supported:
*
* - [EIP-2537](https://eips.ethereum.org/EIPS/eip-2537) - BLS12-381 precompiles
*/
eips?: number[]
}
/**
* Options for instantiating a {@link Common} instance.
*/
export interface CommonOpts extends BaseOpts {
/**
* Chain name ('mainnet'), id (1), or {@link Chain} enum,
* either from a chain directly supported or a custom chain
* passed in via {@link CommonOpts.customChains}.
*/
chain: string | number | Chain | BN | object
/**
* Initialize (in addition to the supported chains) with the selected
* custom chains
*
* Usage (directly with the respective chain intialization via the {@link CommonOpts.chain} option):
*
* Pattern 1 (without genesis state):
*
* ```javascript
* import myCustomChain1 from '[PATH_TO_MY_CHAINS]/myCustomChain1.json'
* const common = new Common({ chain: 'myCustomChain1', customChains: [ myCustomChain1 ]})
* ```
*
* Pattern 2 (with genesis state see {@link GenesisState} for format):
*
* ```javascript
* const simpleState = {
* '0x0...01': '0x100', // For EoA
* }
* import myCustomChain1 from '[PATH_TO_MY_CHAINS]/myCustomChain1.json'
* import chain1GenesisState from '[PATH_TO_GENESIS_STATES]/chain1GenesisState.json'
* const common = new Common({ chain: 'myCustomChain1', customChains: [ [ myCustomChain1, simpleState ] ]})
* ```
*
* Pattern 3 (with complex genesis state, containing contract accounts and storage).
* Note that in {@link AccountState} there are two
* accepted types. This allows to easily insert accounts in the genesis state:
*
* A complex genesis state with Contract and EoA states would have the following format:
*
* ```javascript
* const complexState = {
* '0x0...01': '0x100', // For EoA
* '0x0...02': ['0x1', '0xRUNTIME_BYTECODE', [[ keyOne, valueOne ], [ keyTwo, valueTwo ]]] // For contracts
* }
* import myCustomChain1 from '[PATH_TO_MY_CHAINS]/myCustomChain1.json'
* const common = new Common({ chain: 'myCustomChain1', customChains: [ [ myCustomChain1, complexState ] ]})
* ```
*/
customChains?: IChain[] | [IChain, GenesisState][]
}
/**
* Options to be used with the {@link Common.custom} static constructor.
*/
export interface CustomCommonOpts extends BaseOpts {
/**
* The name (`mainnet`), id (`1`), or {@link Chain} enum of
* a standard chain used to base the custom chain params on.
*/
baseChain?: string | number | Chain | BN
}
interface hardforkOptions {
/** optional, only allow supported HFs (default: false) */
onlySupported?: boolean
/** optional, only active HFs (default: false) */
onlyActive?: boolean
}
/**
* Common class to access chain and hardfork parameters and to provide
* a unified and shared view on the network and hardfork state.
*
* Use the {@link Common.custom} static constructor for creating simple
* custom chain {@link Common} objects (more complete custom chain setups
* can be created via the main constructor and the {@link CommonOpts.customChains} parameter).
*/
export default class Common extends EventEmitter {
readonly DEFAULT_HARDFORK: string | Hardfork
private _chainParams: IChain
private _hardfork: string | Hardfork
private _supportedHardforks: Array<string | Hardfork> = []
private _eips: number[] = []
private _customChains: IChain[] | [IChain, GenesisState][]
/**
* Creates a {@link Common} object for a custom chain, based on a standard one.
*
* It uses all the {@link Chain} parameters from the {@link baseChain} option except the ones overridden
* in a provided {@link chainParamsOrName} dictionary. Some usage example:
*
* ```javascript
* Common.custom({chainId: 123})
* ```
*
* There are also selected supported custom chains which can be initialized by using one of the
* {@link CustomChains} for {@link chainParamsOrName}, e.g.:
*
* ```javascript
* Common.custom(CustomChains.MaticMumbai)
* ```
*
* Note that these supported custom chains only provide some base parameters (usually the chain and
* network ID and a name) and can only be used for selected use cases (e.g. sending a tx with
* the `@ethereumjs/tx` library to a Layer-2 chain).
*
* @param chainParamsOrName Custom parameter dict (`name` will default to `custom-chain`) or string with name of a supported custom chain
* @param opts Custom chain options to set the {@link CustomCommonOpts.baseChain}, selected {@link CustomCommonOpts.hardfork} and others
*/
static custom(
chainParamsOrName: Partial<IChain> | CustomChain,
opts: CustomCommonOpts = {}
): Common {
const baseChain = opts.baseChain ?? 'mainnet'
const standardChainParams = { ...Common._getChainParams(baseChain) }
standardChainParams['name'] = 'custom-chain'
if (typeof chainParamsOrName !== 'string') {
return new Common({
chain: {
...standardChainParams,
...chainParamsOrName,
},
...opts,
})
} else {
if (chainParamsOrName === CustomChain.PolygonMainnet) {
return Common.custom(
{
name: CustomChain.PolygonMainnet,
chainId: 137,
networkId: 137,
},
opts
)
}
if (chainParamsOrName === CustomChain.PolygonMumbai) {
return Common.custom(
{
name: CustomChain.PolygonMumbai,
chainId: 80001,
networkId: 80001,
},
opts
)
}
if (chainParamsOrName === CustomChain.ArbitrumRinkebyTestnet) {
return Common.custom(
{
name: CustomChain.ArbitrumRinkebyTestnet,
chainId: 421611,
networkId: 421611,
},
opts
)
}
if (chainParamsOrName === CustomChain.xDaiChain) {
return Common.custom(
{
name: CustomChain.xDaiChain,
chainId: 100,
networkId: 100,
},
opts
)
}
if (chainParamsOrName === CustomChain.OptimisticKovan) {
return Common.custom(
{
name: CustomChain.OptimisticKovan,
chainId: 69,
networkId: 69,
},
// Optimism has not implemented the London hardfork yet (targeting Q1.22)
{ hardfork: Hardfork.Berlin, ...opts }
)
}
if (chainParamsOrName === CustomChain.OptimisticEthereum) {
return Common.custom(
{
name: CustomChain.OptimisticEthereum,
chainId: 10,
networkId: 10,
},
// Optimism has not implemented the London hardfork yet (targeting Q1.22)
{ hardfork: Hardfork.Berlin, ...opts }
)
}
throw new Error(`Custom chain ${chainParamsOrName} not supported`)
}
}
/**
* Creates a {@link Common} object for a custom chain, based on a standard one. It uses all the `Chain`
* params from {@link baseChain} except the ones overridden in {@link customChainParams}.
*
* @deprecated Use {@link Common.custom} instead
*
* @param baseChain The name (`mainnet`) or id (`1`) of a standard chain used to base the custom
* chain params on.
* @param customChainParams The custom parameters of the chain.
* @param hardfork String identifier ('byzantium') for hardfork (optional)
* @param supportedHardforks Limit parameter returns to the given hardforks (optional)
*/
static forCustomChain(
baseChain: string | number | Chain,
customChainParams: Partial<IChain>,
hardfork?: string | Hardfork,
supportedHardforks?: Array<string | Hardfork>
): Common {
const standardChainParams = Common._getChainParams(baseChain)
return new Common({
chain: {
...standardChainParams,
...customChainParams,
},
hardfork: hardfork,
supportedHardforks: supportedHardforks,
})
}
/**
* Static method to determine if a {@link chainId} is supported as a standard chain
* @param chainId BN id (`1`) of a standard chain
* @returns boolean
*/
static isSupportedChainId(chainId: BN): boolean {
const initializedChains: any = _getInitializedChains()
return Boolean(initializedChains['names'][chainId.toString()])
}
private static _getChainParams(
chain: string | number | Chain | BN,
customChains?: IChain[]
): IChain {
const initializedChains: any = _getInitializedChains(customChains)
if (typeof chain === 'number' || BN.isBN(chain)) {
chain = chain.toString()
if (initializedChains['names'][chain]) {
const name: string = initializedChains['names'][chain]
return initializedChains[name]
}
throw new Error(`Chain with ID ${chain} not supported`)
}
if (initializedChains[chain]) {
return initializedChains[chain]
}
throw new Error(`Chain with name ${chain} not supported`)
}
/**
*
* @constructor
*/
constructor(opts: CommonOpts) {
super()
this._customChains = opts.customChains ?? []
this._chainParams = this.setChain(opts.chain)
this.DEFAULT_HARDFORK = this._chainParams.defaultHardfork ?? Hardfork.Istanbul
for (const hf of this._chainParams.hardforks) {
if (!hf.forkHash) {
hf.forkHash = this._calcForkHash(hf.name)
}
}
this._hardfork = this.DEFAULT_HARDFORK
if (opts.supportedHardforks) {
this._supportedHardforks = opts.supportedHardforks
}
if (opts.hardfork) {
this.setHardfork(opts.hardfork)
}
if (opts.eips) {
this.setEIPs(opts.eips)
}
}
/**
* Sets the chain
* @param chain String ('mainnet') or Number (1) chain
* representation. Or, a Dictionary of chain parameters for a private network.
* @returns The dictionary with parameters set as chain
*/
setChain(chain: string | number | Chain | BN | object): any {
if (typeof chain === 'number' || typeof chain === 'string' || BN.isBN(chain)) {
// Filter out genesis states if passed in to customChains
let plainCustomChains: IChain[]
if (
this._customChains &&
this._customChains.length > 0 &&
Array.isArray(this._customChains[0])
) {
plainCustomChains = (this._customChains as [IChain, GenesisState][]).map((e) => e[0])
} else {
plainCustomChains = this._customChains as IChain[]
}
this._chainParams = Common._getChainParams(chain, plainCustomChains)
} else if (typeof chain === 'object') {
if (this._customChains.length > 0) {
throw new Error(
'Chain must be a string, number, or BN when initialized with customChains passed in'
)
}
const required = ['networkId', 'genesis', 'hardforks', 'bootstrapNodes']
for (const param of required) {
if ((<any>chain)[param] === undefined) {
throw new Error(`Missing required chain parameter: ${param}`)
}
}
this._chainParams = chain as IChain
} else {
throw new Error('Wrong input format')
}
return this._chainParams
}
/**
* Sets the hardfork to get params for
* @param hardfork String identifier (e.g. 'byzantium') or {@link Hardfork} enum
*/
setHardfork(hardfork: string | Hardfork): void {
if (!this._isSupportedHardfork(hardfork)) {
throw new Error(`Hardfork ${hardfork} not set as supported in supportedHardforks`)
}
let existing = false
for (const hfChanges of HARDFORK_CHANGES) {
if (hfChanges[0] === hardfork) {
if (this._hardfork !== hardfork) {
this._hardfork = hardfork
this.emit('hardforkChanged', hardfork)
}
existing = true
}
}
if (!existing) {
throw new Error(`Hardfork with name ${hardfork} not supported`)
}
}
/**
* Returns the hardfork based on the block number or an optional
* total difficulty (Merge HF) provided.
*
* An optional TD takes precedence in case the corresponding HF block
* is set to `null` or otherwise needs to match (if not an error
* will be thrown).
*
* @param blockNumber
* @param td
* @returns The name of the HF
*/
getHardforkByBlockNumber(blockNumber: BNLike, td?: BNLike): string {
blockNumber = toType(blockNumber, TypeOutput.BN)
td = toType(td, TypeOutput.BN)
let hardfork = Hardfork.Chainstart
let minTdHF
let maxTdHF
let previousHF
for (const hf of this.hardforks()) {
// Skip comparison for not applied HFs
if (hf.block === null) {
if (td !== undefined && td !== null && hf.td !== undefined && hf.td !== null) {
if (td.gte(new BN(hf.td))) {
return hf.name
}
}
continue
}
if (blockNumber.gte(new BN(hf.block))) {
hardfork = hf.name as Hardfork
}
if (td && hf.td) {
if (td.gte(new BN(hf.td))) {
minTdHF = hf.name
} else {
maxTdHF = previousHF
}
}
previousHF = hf.name
}
if (td) {
let msgAdd = `block number: ${blockNumber} (-> ${hardfork}), `
if (minTdHF) {
if (!this.hardforkGteHardfork(hardfork, minTdHF)) {
const msg = 'HF determined by block number is lower than the minimum total difficulty HF'
msgAdd += `total difficulty: ${td} (-> ${minTdHF})`
throw new Error(`${msg}: ${msgAdd}`)
}
}
if (maxTdHF) {
if (!this.hardforkGteHardfork(maxTdHF, hardfork)) {
const msg = 'Maximum HF determined by total difficulty is lower than the block number HF'
msgAdd += `total difficulty: ${td} (-> ${maxTdHF})`
throw new Error(`${msg}: ${msgAdd}`)
}
}
}
return hardfork
}
/**
* Sets a new hardfork based on the block number or an optional
* total difficulty (Merge HF) provided.
*
* An optional TD takes precedence in case the corresponding HF block
* is set to `null` or otherwise needs to match (if not an error
* will be thrown).
*
* @param blockNumber
* @param td
* @returns The name of the HF set
*/
setHardforkByBlockNumber(blockNumber: BNLike, td?: BNLike): string {
const hardfork = this.getHardforkByBlockNumber(blockNumber, td)
this.setHardfork(hardfork)
return hardfork
}
/**
* Internal helper function to choose between hardfork set and hardfork provided as param
* @param hardfork Hardfork given to function as a parameter
* @returns Hardfork chosen to be used
*/
_chooseHardfork(hardfork?: string | Hardfork | null, onlySupported: boolean = true): string {
if (!hardfork) {
hardfork = this._hardfork
} else if (onlySupported && !this._isSupportedHardfork(hardfork)) {
throw new Error(`Hardfork ${hardfork} not set as supported in supportedHardforks`)
}
return hardfork
}
/**
* Internal helper function, returns the params for the given hardfork for the chain set
* @param hardfork Hardfork name
* @returns Dictionary with hardfork params
*/
_getHardfork(hardfork: string | Hardfork): any {
const hfs = this.hardforks()
for (const hf of hfs) {
if (hf['name'] === hardfork) return hf
}
throw new Error(`Hardfork ${hardfork} not defined for chain ${this.chainName()}`)
}
/**
* Internal helper function to check if a hardfork is set to be supported by the library
* @param hardfork Hardfork name
* @returns True if hardfork is supported
*/
_isSupportedHardfork(hardfork: string | Hardfork | null): boolean {
if (this._supportedHardforks.length > 0) {
for (const supportedHf of this._supportedHardforks) {
if (hardfork === supportedHf) return true
}
} else {
return true
}
return false
}
/**
* Sets the active EIPs
* @param eips
*/
setEIPs(eips: number[] = []) {
for (const eip of eips) {
if (!(eip in EIPs)) {
throw new Error(`${eip} not supported`)
}
const minHF = this.gteHardfork(EIPs[eip]['minimumHardfork'])
if (!minHF) {
throw new Error(
`${eip} cannot be activated on hardfork ${this.hardfork()}, minimumHardfork: ${minHF}`
)
}
if (EIPs[eip].requiredEIPs) {
;(EIPs[eip].requiredEIPs as number[]).forEach((elem) => {
if (!(eips.includes(elem) || this.isActivatedEIP(elem))) {
throw new Error(`${eip} requires EIP ${elem}, but is not included in the EIP list`)
}
})
}
}
this._eips = eips
}
/**
* Returns a parameter for the current chain setup
*
* If the parameter is present in an EIP, the EIP always takes precendence.
* Otherwise the parameter if taken from the latest applied HF with
* a change on the respective parameter.
*
* @param topic Parameter topic ('gasConfig', 'gasPrices', 'vm', 'pow')
* @param name Parameter name (e.g. 'minGasLimit' for 'gasConfig' topic)
* @returns The value requested or `null` if not found
*/
param(topic: string, name: string): any {
// TODO: consider the case that different active EIPs
// can change the same parameter
let value = null
for (const eip of this._eips) {
value = this.paramByEIP(topic, name, eip)
if (value !== null) {
return value
}
}
return this.paramByHardfork(topic, name, this._hardfork)
}
/**
* Returns the parameter corresponding to a hardfork
* @param topic Parameter topic ('gasConfig', 'gasPrices', 'vm', 'pow')
* @param name Parameter name (e.g. 'minGasLimit' for 'gasConfig' topic)
* @param hardfork Hardfork name
* @returns The value requested or `null` if not found
*/
paramByHardfork(topic: string, name: string, hardfork: string | Hardfork): any {
hardfork = this._chooseHardfork(hardfork)
let value = null
for (const hfChanges of HARDFORK_CHANGES) {
// EIP-referencing HF file (e.g. berlin.json)
if ('eips' in hfChanges[1]) {
const hfEIPs = hfChanges[1]['eips']
for (const eip of hfEIPs) {
const valueEIP = this.paramByEIP(topic, name, eip)
value = valueEIP !== null ? valueEIP : value
}
// Paramater-inlining HF file (e.g. istanbul.json)
} else {
if (!hfChanges[1][topic]) {
throw new Error(`Topic ${topic} not defined`)
}
if (hfChanges[1][topic][name] !== undefined) {
value = hfChanges[1][topic][name].v
}
}
if (hfChanges[0] === hardfork) break
}
return value
}
/**
* Returns a parameter corresponding to an EIP
* @param topic Parameter topic ('gasConfig', 'gasPrices', 'vm', 'pow')
* @param name Parameter name (e.g. 'minGasLimit' for 'gasConfig' topic)
* @param eip Number of the EIP
* @returns The value requested or `null` if not found
*/
paramByEIP(topic: string, name: string, eip: number): any {
if (!(eip in EIPs)) {
throw new Error(`${eip} not supported`)
}
const eipParams = EIPs[eip]
if (!(topic in eipParams)) {
throw new Error(`Topic ${topic} not defined`)
}
if (eipParams[topic][name] === undefined) {
return null
}
const value = eipParams[topic][name].v
return value
}
/**
* Returns a parameter for the hardfork active on block number
* @param topic Parameter topic
* @param name Parameter name
* @param blockNumber Block number
*/
paramByBlock(topic: string, name: string, blockNumber: BNLike): any {
const activeHfs = this.activeHardforks(blockNumber)
const hardfork = activeHfs[activeHfs.length - 1]['name']
return this.paramByHardfork(topic, name, hardfork)
}
/**
* Checks if an EIP is activated by either being included in the EIPs
* manually passed in with the {@link CommonOpts.eips} or in a
* hardfork currently being active
*
* Note: this method only works for EIPs being supported
* by the {@link CommonOpts.eips} constructor option
* @param eip
*/
isActivatedEIP(eip: number): boolean {
if (this.eips().includes(eip)) {
return true
}
for (const hfChanges of HARDFORK_CHANGES) {
const hf = hfChanges[1]
if (this.gteHardfork(hf['name']) && 'eips' in hf) {
if (hf['eips'].includes(eip)) {
return true
}
}
}
return false
}
/**
* Checks if set or provided hardfork is active on block number
* @param hardfork Hardfork name or null (for HF set)
* @param blockNumber
* @param opts Hardfork options (onlyActive unused)
* @returns True if HF is active on block number
*/
hardforkIsActiveOnBlock(
hardfork: string | Hardfork | null,
blockNumber: BNLike,
opts: hardforkOptions = {}
): boolean {
blockNumber = toType(blockNumber, TypeOutput.BN)
const onlySupported = opts.onlySupported ?? false
hardfork = this._chooseHardfork(hardfork, onlySupported)
const hfBlock = this.hardforkBlockBN(hardfork)
if (hfBlock && blockNumber.gte(hfBlock)) {
return true
}
return false
}
/**
* Alias to hardforkIsActiveOnBlock when hardfork is set
* @param blockNumber
* @param opts Hardfork options (onlyActive unused)
* @returns True if HF is active on block number
*/
activeOnBlock(blockNumber: BNLike, opts?: hardforkOptions): boolean {
return this.hardforkIsActiveOnBlock(null, blockNumber, opts)
}
/**
* Sequence based check if given or set HF1 is greater than or equal HF2
* @param hardfork1 Hardfork name or null (if set)
* @param hardfork2 Hardfork name
* @param opts Hardfork options
* @returns True if HF1 gte HF2
*/
hardforkGteHardfork(
hardfork1: string | Hardfork | null,
hardfork2: string | Hardfork,
opts: hardforkOptions = {}
): boolean {
const onlyActive = opts.onlyActive === undefined ? false : opts.onlyActive
hardfork1 = this._chooseHardfork(hardfork1, opts.onlySupported)
let hardforks
if (onlyActive) {
hardforks = this.activeHardforks(null, opts)
} else {
hardforks = this.hardforks()
}
let posHf1 = -1,
posHf2 = -1
let index = 0
for (const hf of hardforks) {
if (hf['name'] === hardfork1) posHf1 = index
if (hf['name'] === hardfork2) posHf2 = index
index += 1
}
return posHf1 >= posHf2 && posHf2 !== -1
}
/**
* Alias to hardforkGteHardfork when hardfork is set
* @param hardfork Hardfork name
* @param opts Hardfork options
* @returns True if hardfork set is greater than hardfork provided
*/
gteHardfork(hardfork: string | Hardfork, opts?: hardforkOptions): boolean {
return this.hardforkGteHardfork(null, hardfork, opts)
}
/**
* Checks if given or set hardfork is active on the chain
* @param hardfork Hardfork name, optional if HF set
* @param opts Hardfork options (onlyActive unused)
* @returns True if hardfork is active on the chain
*/
hardforkIsActiveOnChain(
hardfork?: string | Hardfork | null,
opts: hardforkOptions = {}
): boolean {
const onlySupported = opts.onlySupported ?? false
hardfork = this._chooseHardfork(hardfork, onlySupported)
for (const hf of this.hardforks()) {
if (hf['name'] === hardfork && hf['block'] !== null) return true
}
return false
}
/**
* Returns the active hardfork switches for the current chain
* @param blockNumber up to block if provided, otherwise for the whole chain
* @param opts Hardfork options (onlyActive unused)
* @return Array with hardfork arrays
*/
activeHardforks(blockNumber?: BNLike | null, opts: hardforkOptions = {}): HardforkParams[] {
const activeHardforks: HardforkParams[] = []
const hfs = this.hardforks()
for (const hf of hfs) {
if (hf['block'] === null) continue
if (blockNumber !== undefined && blockNumber !== null && blockNumber < hf['block']) break
if (opts.onlySupported && !this._isSupportedHardfork(hf['name'])) continue
activeHardforks.push(hf)
}
return activeHardforks
}
/**
* Returns the latest active hardfork name for chain or block or throws if unavailable
* @param blockNumber up to block if provided, otherwise for the whole chain
* @param opts Hardfork options (onlyActive unused)
* @return Hardfork name
*/
activeHardfork(blockNumber?: BNLike | null, opts: hardforkOptions = {}): string {
const activeHardforks = this.activeHardforks(blockNumber, opts)
if (activeHardforks.length > 0) {
return activeHardforks[activeHardforks.length - 1]['name']
} else {
throw new Error(`No (supported) active hardfork found`)
}
}
/**
* Returns the hardfork change block for hardfork provided or set
* @param hardfork Hardfork name, optional if HF set
* @returns Block number or null if unscheduled
* @deprecated Please use {@link Common.hardforkBlockBN} for large number support
*/
hardforkBlock(hardfork?: string | Hardfork): number | null {
const block = this.hardforkBlockBN(hardfork)
return toType(block, TypeOutput.Number)
}
/**
* Returns the hardfork change block for hardfork provided or set
* @param hardfork Hardfork name, optional if HF set
* @returns Block number or null if unscheduled
*/
hardforkBlockBN(hardfork?: string | Hardfork): BN | null {
hardfork = this._chooseHardfork(hardfork, false)
const block = this._getHardfork(hardfork)['block']
if (block === undefined || block === null) {
return null
}
return new BN(block)
}
/**
* Returns the hardfork change total difficulty (Merge HF) for hardfork provided or set
* @param hardfork Hardfork name, optional if HF set
* @returns Total difficulty or null if no set
*/
hardforkTD(hardfork?: string | Hardfork): BN | null {
hardfork = this._chooseHardfork(hardfork, false)
const td = this._getHardfork(hardfork)['td']
if (td === undefined || td === null) {
return null
}
return new BN(td)
}
/**
* True if block number provided is the hardfork (given or set) change block
* @param blockNumber Number of the block to check
* @param hardfork Hardfork name, optional if HF set
* @returns True if blockNumber is HF block
*/
isHardforkBlock(blockNumber: BNLike, hardfork?: string | Hardfork): boolean {
blockNumber = toType(blockNumber, TypeOutput.BN)
hardfork = this._chooseHardfork(hardfork, false)
const block = this.hardforkBlockBN(hardfork)
return block ? block.eq(blockNumber) : false
}
/**
* Returns the change block for the next hardfork after the hardfork provided or set
* @param hardfork Hardfork name, optional if HF set
* @returns Block number or null if not available
* @deprecated Please use {@link Common.nextHardforkBlockBN} for large number support
*/
nextHardforkBlock(hardfork?: string | Hardfork): number | null {
const block = this.nextHardforkBlockBN(hardfork)
return toType(block, TypeOutput.Number)
}
/**
* Returns the change block for the next hardfork after the hardfork provided or set
* @param hardfork Hardfork name, optional if HF set
* @returns Block number or null if not available
*/
nextHardforkBlockBN(hardfork?: string | Hardfork): BN | null {
hardfork = this._chooseHardfork(hardfork, false)
const hfBlock = this.hardforkBlockBN(hardfork)
if (hfBlock === null) {
return null
}
// Next fork block number or null if none available
// Logic: if accumulator is still null and on the first occurrence of
// a block greater than the current hfBlock set the accumulator,
// pass on the accumulator as the final result from this time on
const nextHfBlock = this.hardforks().reduce((acc: BN | null, hf: HardforkParams) => {
const block = new BN(hf.block!)
return block.gt(hfBlock) && acc === null ? block : acc
}, null)
return nextHfBlock
}
/**
* True if block number provided is the hardfork change block following the hardfork given or set
* @param blockNumber Number of the block to check
* @param hardfork Hardfork name, optional if HF set
* @returns True if blockNumber is HF block
*/
isNextHardforkBlock(blockNumber: BNLike, hardfork?: string | Hardfork): boolean {
blockNumber = toType(blockNumber, TypeOutput.BN)
hardfork = this._chooseHardfork(hardfork, false)
const nextHardforkBlock = this.nextHardforkBlockBN(hardfork)
return nextHardforkBlock === null ? false : nextHardforkBlock.eq(blockNumber)
}
/**
* Internal helper function to calculate a fork hash
* @param hardfork Hardfork name
* @returns Fork hash as hex string
*/
_calcForkHash(hardfork: string | Hardfork) {
const genesis = Buffer.from(this.genesis().hash.substr(2), 'hex')
let hfBuffer = Buffer.alloc(0)
let prevBlock = 0
for (const hf of this.hardforks()) {
const block = hf.block
// Skip for chainstart (0), not applied HFs (null) and
// when already applied on same block number HFs
if (block !== 0 && block !== null && block !== prevBlock) {
const hfBlockBuffer = Buffer.from(block.toString(16).padStart(16, '0'), 'hex')
hfBuffer = Buffer.concat([hfBuffer, hfBlockBuffer])
}
if (hf.name === hardfork) break
if (block !== null) {
prevBlock = block
}
}
const inputBuffer = Buffer.concat([genesis, hfBuffer])
// CRC32 delivers result as signed (negative) 32-bit integer,
// convert to hex string
const forkhash = intToBuffer(crc32Buffer(inputBuffer) >>> 0).toString('hex')
return `0x${forkhash}`
}
/**
* Returns an eth/64 compliant fork hash (EIP-2124)
* @param hardfork Hardfork name, optional if HF set
*/
forkHash(hardfork?: string | Hardfork) {
hardfork = this._chooseHardfork(hardfork, false)
const data = this._getHardfork(hardfork)
if (data['block'] === null && data['td'] === undefined) {
const msg = 'No fork hash calculation possible for future hardfork'
throw new Error(msg)
}
if (data['forkHash'] !== undefined) {
return data['forkHash']
}
return this._calcForkHash(hardfork)
}
/**
*
* @param forkHash Fork hash as a hex string
* @returns Array with hardfork data (name, block, forkHash)
*/
hardforkForForkHash(forkHash: string): any | null {
const resArray = this.hardforks().filter((hf: any) => {
return hf.forkHash === forkHash
})
return resArray.length >= 1 ? resArray[resArray.length - 1] : null
}
/**
* Returns the Genesis parameters of the current chain
* @returns Genesis dictionary
*/
genesis(): GenesisBlock {
return this._chainParams['genesis']
}
/**
* Returns the Genesis state of the current chain,
* all values are provided as hex-prefixed strings.
*/
genesisState(): GenesisState {
// Use require statements here in favor of import statements
// to load json files on demand
// (high memory usage by large mainnet.json genesis state file)
switch (this.chainName()) {
case 'mainnet':
return require('./genesisStates/mainnet.json')
case 'ropsten':
return require('./genesisStates/ropsten.json')
case 'rinkeby':
return require('./genesisStates/rinkeby.json')
case 'kovan':
return require('./genesisStates/kovan.json')
case 'goerli':
return require('./genesisStates/goerli.json')
case 'sepolia':
return require('./genesisStates/sepolia.json')
}
// Custom chains with genesis state provided
if (
this._customChains &&
this._customChains.length > 0 &&
Array.isArray(this._customChains[0])
) {
for (const chainArrayWithGenesis of this._customChains as [IChain, GenesisState][]) {
if (chainArrayWithGenesis[0].name === this.chainName()) {
return chainArrayWithGenesis[1]
}
}
}
return {}
}
/**
* Returns the hardforks for current chain
* @returns {Array} Array with arrays of hardforks
*/
hardforks(): HardforkParams[] {
return this._chainParams['hardforks']
}
/**
* Returns bootstrap nodes for the current chain
* @returns {Dictionary} Dict with bootstrap nodes
*/
bootstrapNodes(): BootstrapNode[] {
return this._chainParams['bootstrapNodes']
}
/**
* Returns DNS networks for the current chain
* @returns {String[]} Array of DNS ENR urls
*/
dnsNetworks(): string[] {
return this._chainParams['dnsNetworks']!
}
/**
* Returns the hardfork set
* @returns Hardfork name
*/
hardfork(): string | Hardfork {
return this._hardfork
}
/**
* Returns the Id of current chain
* @returns chain Id
* @deprecated Please use {@link Common.chainIdBN} for large number support
*/
chainId(): number {
return toType(this.chainIdBN(), TypeOutput.Number)
}
/**
* Returns the Id of current chain
* @returns chain Id
*/
chainIdBN(): BN {
return new BN(this._chainParams['chainId'])
}
/**
* Returns the name of current chain
* @returns chain name (lower case)
*/
chainName(): string {
return this._chainParams['name']
}
/**
* Returns the Id of current network
* @returns network Id
* @deprecated Please use {@link Common.networkIdBN} for large number support
*/
networkId(): number {
return toType(this.networkIdBN(), TypeOutput.Number)
}
/**
* Returns the Id of current network
* @returns network Id
*/
networkIdBN(): BN {
return new BN(this._chainParams['networkId'])
}
/**
* Returns the active EIPs
* @returns List of EIPs
*/
eips(): number[] {
return this._eips
}
/**
* Returns the consensus type of the network
* Possible values: "pow"|"poa"|"pos"
*
* Note: This value can update along a hardfork.
*/
consensusType(): string | ConsensusType {
const hardfork = this.hardfork()
let value
for (const hfChanges of HARDFORK_CHANGES) {
if ('consensus' in hfChanges[1]) {
value = hfChanges[1]['consensus']['type']
}
if (hfChanges[0] === hardfork) break
}
if (value) {
return value
}
return this._chainParams['consensus']!['type']
}
/**
* Returns the concrete consensus implementation
* algorithm or protocol for the network
* e.g. "ethash" for "pow" consensus type,
* "clique" for "poa" consensus type or
* "casper" for "pos" consensus type.
*
* Note: This value can update along a hardfork.
*/
consensusAlgorithm(): string | ConsensusAlgorithm {
const hardfork = this.hardfork()
let value
for (const hfChanges of HARDFORK_CHANGES) {
if ('consensus' in hfChanges[1]) {
value = hfChanges[1]['consensus']['algorithm']
}
if (hfChanges[0] === hardfork) break
}
if (value) {
return value
}
return this._chainParams['consensus']!['algorithm'] as ConsensusAlgorithm
}
/**
* Returns a dictionary with consensus configuration
* parameters based on the consensus algorithm
*
* Expected returns (parameters must be present in
* the respective chain json files):
*
* ethash: -
* clique: period, epoch
* aura: -
* casper: -
*
* Note: This value can update along a hardfork.
*/
consensusConfig(): { [key: string]: any } {
const hardfork = this.hardfork()
let value
for (const hfChanges of HARDFORK_CHANGES) {
if ('consensus' in hfChanges[1]) {
// The config parameter is named after the respective consensus algorithm
value = hfChanges[1]['consensus'][hfChanges[1]['consensus']['algorithm']]
}
if (hfChanges[0] === hardfork) break
}
if (value) {
return value
}
const consensusAlgorithm = this.consensusAlgorithm()
return this._chainParams['consensus']![consensusAlgorithm as ConsensusAlgorithm]
}
/**
* Returns a deep copy of this {@link Common} instance.
*/
copy(): Common {
const copy = Object.assign(Object.create(Object.getPrototypeOf(this)), this)
copy.removeAllListeners()
return copy
}
}
export { Common as default } from './common'
export * from './enums'
export * from './types'

@@ -1,62 +0,40 @@

import { BN, PrefixedHexString } from 'ethereumjs-util'
import { ConsensusAlgorithm, ConsensusType, Hardfork as HardforkName } from '.'
import { ConsensusAlgorithm, ConsensusType, Hardfork, Chain } from './enums'
export interface genesisStatesType {
names: {
[key: string]: string
}
[key: string]: {}
export interface ChainName {
[chainId: string]: string
}
export interface ChainsConfig {
[key: string]: ChainConfig | ChainName
}
export interface chainsType {
names: {
[key: string]: string
}
[key: string]: any
export type CliqueConfig = {
period: number
epoch: number
}
export interface Chain {
export type EthashConfig = {}
export type CasperConfig = {}
export interface ChainConfig {
name: string
chainId: number | BN
networkId: number | BN
// TODO: make mandatory in next breaking release
defaultHardfork?: string
chainId: number | bigint
networkId: number | bigint
defaultHardfork: string
comment: string
url: string
genesis: GenesisBlock
hardforks: Hardfork[]
bootstrapNodes: BootstrapNode[]
genesis: GenesisBlockConfig
hardforks: HardforkConfig[]
bootstrapNodes: BootstrapNodeConfig[]
dnsNetworks?: string[]
// TODO: make mandatory in next breaking release
consensus?: {
consensus: {
type: ConsensusType | string
algorithm: ConsensusAlgorithm | string
clique?: {
period: number
epoch: number
}
ethash?: any
casper?: any
clique?: CliqueConfig
ethash?: EthashConfig
casper?: CasperConfig
}
}
type StoragePair = [key: PrefixedHexString, value: PrefixedHexString]
export type AccountState = [
balance: PrefixedHexString,
code: PrefixedHexString,
storage: Array<StoragePair>
]
export interface GenesisState {
[key: PrefixedHexString]: PrefixedHexString | AccountState
}
export interface eipsType {
[key: number]: any
}
export interface GenesisBlock {
hash: string
timestamp: string | null
export interface GenesisBlockConfig {
timestamp?: string
gasLimit: number

@@ -66,8 +44,7 @@ difficulty: number

extraData: string
stateRoot: string
baseFeePerGas?: string
}
export interface Hardfork {
name: HardforkName | string
export interface HardforkConfig {
name: Hardfork | string
block: number | null

@@ -78,3 +55,3 @@ td?: number

export interface BootstrapNode {
export interface BootstrapNodeConfig {
ip: string

@@ -88,1 +65,54 @@ port: number | string

}
interface BaseOpts {
/**
* String identifier ('byzantium') for hardfork or {@link Hardfork} enum.
*
* Default: Hardfork.London
*/
hardfork?: string | Hardfork
/**
* Selected EIPs which can be activated, please use an array for instantiation
* (e.g. `eips: [ 2537, ]`)
*
* Currently supported:
*
* - [EIP-2537](https://eips.ethereum.org/EIPS/eip-2537) - BLS12-381 precompiles
*/
eips?: number[]
}
/**
* Options for instantiating a {@link Common} instance.
*/
export interface CommonOpts extends BaseOpts {
/**
* Chain name ('mainnet'), id (1), or {@link Chain} enum,
* either from a chain directly supported or a custom chain
* passed in via {@link CommonOpts.customChains}.
*/
chain: string | number | Chain | bigint | object
/**
* Initialize (in addition to the supported chains) with the selected
* custom chains. Custom genesis state should be passed to the Blockchain class if used.
*
* Usage (directly with the respective chain initialization via the {@link CommonOpts.chain} option):
*
* ```javascript
* import myCustomChain1 from '[PATH_TO_MY_CHAINS]/myCustomChain1.json'
* const common = new Common({ chain: 'myCustomChain1', customChains: [ myCustomChain1 ]})
* ```
*/
customChains?: ChainConfig[]
}
/**
* Options to be used with the {@link Common.custom} static constructor.
*/
export interface CustomCommonOpts extends BaseOpts {
/**
* The name (`mainnet`), id (`1`), or {@link Chain} enum of
* a standard chain used to base the custom chain params on.
*/
baseChain?: string | number | Chain | bigint
}

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