@ethereumjs/common
Advanced tools
Comparing version 2.6.5 to 3.0.0-beta.1
@@ -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 |
1042
dist/index.js
"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'), |
1241
src/index.ts
@@ -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' |
132
src/types.ts
@@ -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
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
245781
125
6728
1
318
1
+ Added@ethereumjs/util@8.0.0-beta.1(transitive)
+ Added@noble/hashes@1.2.0(transitive)
+ Added@noble/secp256k1@1.7.1(transitive)
+ Added@scure/base@1.1.9(transitive)
+ Added@scure/bip32@1.1.5(transitive)
+ Added@scure/bip39@1.1.1(transitive)
+ Addedethereum-cryptography@1.2.0(transitive)
+ Addedrlp@4.0.0-beta.1(transitive)
- Removedethereumjs-util@^7.1.5
- Removed@types/bn.js@5.1.6(transitive)
- Removed@types/node@22.9.0(transitive)
- Removed@types/pbkdf2@3.1.2(transitive)
- Removed@types/secp256k1@4.0.6(transitive)
- Removedbase-x@3.0.10(transitive)
- Removedblakejs@1.2.1(transitive)
- Removedbn.js@4.12.15.2.1(transitive)
- Removedbrorand@1.1.0(transitive)
- Removedbrowserify-aes@1.2.0(transitive)
- Removedbs58@4.0.1(transitive)
- Removedbs58check@2.1.2(transitive)
- Removedbuffer-xor@1.0.3(transitive)
- Removedcipher-base@1.0.4(transitive)
- Removedcreate-hash@1.2.0(transitive)
- Removedcreate-hmac@1.1.7(transitive)
- Removedelliptic@6.6.1(transitive)
- Removedethereum-cryptography@0.1.3(transitive)
- Removedethereumjs-util@7.1.5(transitive)
- Removedevp_bytestokey@1.0.3(transitive)
- Removedhash-base@3.1.0(transitive)
- Removedhash.js@1.1.7(transitive)
- Removedhmac-drbg@1.0.1(transitive)
- Removedinherits@2.0.4(transitive)
- Removedkeccak@3.0.4(transitive)
- Removedmd5.js@1.3.5(transitive)
- Removedminimalistic-assert@1.0.1(transitive)
- Removedminimalistic-crypto-utils@1.0.1(transitive)
- Removednode-addon-api@2.0.25.1.0(transitive)
- Removednode-gyp-build@4.8.3(transitive)
- Removedpbkdf2@3.1.2(transitive)
- Removedrandombytes@2.1.0(transitive)
- Removedreadable-stream@3.6.2(transitive)
- Removedripemd160@2.0.2(transitive)
- Removedrlp@2.2.7(transitive)
- Removedsafe-buffer@5.2.1(transitive)
- Removedscrypt-js@3.0.1(transitive)
- Removedsecp256k1@4.0.4(transitive)
- Removedsetimmediate@1.0.5(transitive)
- Removedsha.js@2.4.11(transitive)
- Removedstring_decoder@1.3.0(transitive)
- Removedundici-types@6.19.8(transitive)
- Removedutil-deprecate@1.0.2(transitive)