truffle
Version:
Truffle - Simple development framework for Ethereum
1,313 lines (1,292 loc) • 4.63 MB
JavaScript
#!/usr/bin/env node
exports.id = 9129;
exports.ids = [9129];
exports.modules = {
/***/ 88864:
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.chains = exports._getInitializedChains = void 0;
const mainnet_json_1 = __importDefault(__webpack_require__(43323));
const ropsten_json_1 = __importDefault(__webpack_require__(52823));
const rinkeby_json_1 = __importDefault(__webpack_require__(36987));
const kovan_json_1 = __importDefault(__webpack_require__(16128));
const goerli_json_1 = __importDefault(__webpack_require__(47295));
/**
* @hidden
*/
function _getInitializedChains(customChains) {
const names = {
'1': 'mainnet',
'3': 'ropsten',
'4': 'rinkeby',
'42': 'kovan',
'5': 'goerli',
};
const chains = {
mainnet: mainnet_json_1.default,
ropsten: ropsten_json_1.default,
rinkeby: rinkeby_json_1.default,
kovan: kovan_json_1.default,
goerli: goerli_json_1.default,
};
if (customChains) {
for (const chain of customChains) {
const name = chain.name;
names[chain.chainId.toString()] = name;
chains[name] = chain;
}
}
chains['names'] = names;
return chains;
}
exports._getInitializedChains = _getInitializedChains;
/**
* @deprecated this constant will be internalized (removed)
* on next major version update
*/
exports.chains = _getInitializedChains();
//# sourceMappingURL=index.js.map
/***/ }),
/***/ 97438:
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
"use strict";
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.EIPs = void 0;
exports.EIPs = {
1559: __webpack_require__(41187),
2315: __webpack_require__(22643),
2537: __webpack_require__(77158),
2565: __webpack_require__(8499),
2718: __webpack_require__(76796),
2929: __webpack_require__(18345),
2930: __webpack_require__(18185),
3198: __webpack_require__(40445),
3529: __webpack_require__(16102),
3541: __webpack_require__(22867),
3554: __webpack_require__(98691),
3675: __webpack_require__(21794),
};
//# sourceMappingURL=index.js.map
/***/ }),
/***/ 37240:
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
"use strict";
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.hardforks = void 0;
exports.hardforks = [
['chainstart', __webpack_require__(28158)],
['homestead', __webpack_require__(45516)],
['dao', __webpack_require__(36888)],
['tangerineWhistle', __webpack_require__(94350)],
['spuriousDragon', __webpack_require__(82146)],
['byzantium', __webpack_require__(3099)],
['constantinople', __webpack_require__(3068)],
['petersburg', __webpack_require__(13385)],
['istanbul', __webpack_require__(10208)],
['muirGlacier', __webpack_require__(90050)],
['berlin', __webpack_require__(15880)],
['london', __webpack_require__(73352)],
['shanghai', __webpack_require__(30369)],
['merge', __webpack_require__(977)],
];
//# sourceMappingURL=index.js.map
/***/ }),
/***/ 27783:
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
"use strict";
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.ConsensusAlgorithm = exports.ConsensusType = exports.Hardfork = exports.Chain = exports.CustomChain = void 0;
const events_1 = __webpack_require__(82361);
const crc_32_1 = __webpack_require__(34606);
const ethereumjs_util_1 = __webpack_require__(82265);
const chains_1 = __webpack_require__(88864);
const hardforks_1 = __webpack_require__(37240);
const eips_1 = __webpack_require__(97438);
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";
})(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 = 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["Shanghai"] = "shanghai";
Hardfork["Merge"] = "merge";
})(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,
});
}
if (chainParamsOrName === CustomChain.PolygonMumbai) {
return Common.custom({
name: CustomChain.PolygonMumbai,
chainId: 80001,
networkId: 80001,
});
}
if (chainParamsOrName === CustomChain.ArbitrumRinkebyTestnet) {
return Common.custom({
name: CustomChain.ArbitrumRinkebyTestnet,
chainId: 421611,
networkId: 421611,
});
}
if (chainParamsOrName === CustomChain.xDaiChain) {
return Common.custom({
name: CustomChain.xDaiChain,
chainId: 100,
networkId: 100,
});
}
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 = td ? (0, ethereumjs_util_1.toType)(td, ethereumjs_util_1.TypeOutput.BN) : undefined;
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 && hf.td) {
if (td.gten(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.gten(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) {
// eslint-disable-next-line prettier/prettier
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 block ? (0, ethereumjs_util_1.toType)(block, ethereumjs_util_1.TypeOutput.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) {
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 block === null ? null : (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) {
const msg = 'No fork hash calculation possible for non-applied or 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,
* both account addresses and values are provided
* as hex-prefixed strings
*
* @returns {Array} Genesis state
*/
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 __webpack_require__(90368);
case 'ropsten':
return __webpack_require__(91775);
case 'rinkeby':
return __webpack_require__(8124);
case 'kovan':
return __webpack_require__(34636);
case 'goerli':
return __webpack_require__(69436);
}
// 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() {
return Object.assign(Object.create(Object.getPrototypeOf(this)), this);
}
}
exports["default"] = Common;
//# sourceMappingURL=index.js.map
/***/ }),
/***/ 40840:
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.isZeroAddress = exports.zeroAddress = exports.importPublic = exports.privateToAddress = exports.privateToPublic = exports.publicToAddress = exports.pubToAddress = exports.isValidPublic = exports.isValidPrivate = exports.generateAddress2 = exports.generateAddress = exports.isValidChecksumAddress = exports.toChecksumAddress = exports.isValidAddress = exports.Account = void 0;
const assert_1 = __importDefault(__webpack_require__(39491));
const externals_1 = __webpack_require__(96812);
const secp256k1_1 = __webpack_require__(95053);
const internal_1 = __webpack_require__(82965);
const constants_1 = __webpack_require__(76336);
const bytes_1 = __webpack_require__(48184);
const hash_1 = __webpack_require__(26531);
const helpers_1 = __webpack_require__(76555);
const types_1 = __webpack_require__(85622);
class Account {
/**
* This constructor assigns and validates the values.
* Use the static factory methods to assist in creating an Account from varying data types.
*/
constructor(nonce = new externals_1.BN(0), balance = new externals_1.BN(0), stateRoot = constants_1.KECCAK256_RLP, codeHash = constants_1.KECCAK256_NULL) {
this.nonce = nonce;
this.balance = balance;
this.stateRoot = stateRoot;
this.codeHash = codeHash;
this._validate();
}
static fromAccountData(accountData) {
const { nonce, balance, stateRoot, codeHash } = accountData;
return new Account(nonce ? new externals_1.BN((0, bytes_1.toBuffer)(nonce)) : undefined, balance ? new externals_1.BN((0, bytes_1.toBuffer)(balance)) : undefined, stateRoot ? (0, bytes_1.toBuffer)(stateRoot) : undefined, codeHash ? (0, bytes_1.toBuffer)(codeHash) : undefined);
}
static fromRlpSerializedAccount(serialized) {
const values = externals_1.rlp.decode(serialized);
if (!Array.isArray(values)) {
throw new Error('Invalid serialized account input. Must be array');
}
return this.fromValuesArray(values);
}
static fromValuesArray(values) {
const [nonce, balance, stateRoot, codeHash] = values;
return new Account(new externals_1.BN(nonce), new externals_1.BN(balance), stateRoot, codeHash);
}
_validate() {
if (this.nonce.lt(new externals_1.BN(0))) {
throw new Error('nonce must be greater than zero');
}
if (this.balance.lt(new externals_1.BN(0))) {
throw new Error('balance must be greater than zero');
}
if (this.stateRoot.length !== 32) {
throw new Error('stateRoot must have a length of 32');
}
if (this.codeHash.length !== 32) {
throw new Error('codeHash must have a length of 32');
}
}
/**
* Returns a Buffer Array of the raw Buffers for the account, in order.
*/
raw() {
return [
(0, types_1.bnToUnpaddedBuffer)(this.nonce),
(0, types_1.bnToUnpaddedBuffer)(this.balance),
this.stateRoot,
this.codeHash,
];
}
/**
* Returns the RLP serialization of the account as a `Buffer`.
*/
serialize() {
return externals_1.rlp.encode(this.raw());
}
/**
* Returns a `Boolean` determining if the account is a contract.
*/
isContract() {
return !this.codeHash.equals(constants_1.KECCAK256_NULL);
}
/**
* Returns a `Boolean` determining if the account is empty complying to the definition of
* account emptiness in [EIP-161](https://eips.ethereum.org/EIPS/eip-161):
* "An account is considered empty when it has no code and zero nonce and zero balance."
*/
isEmpty() {
return this.balance.isZero() && this.nonce.isZero() && this.codeHash.equals(constants_1.KECCAK256_NULL);
}
}
exports.Account = Account;
/**
* Checks if the address is a valid. Accepts checksummed addresses too.
*/
const isValidAddress = function (hexAddress) {
try {
(0, helpers_1.assertIsString)(hexAddress);
}
catch (e) {
return false;
}
return /^0x[0-9a-fA-F]{40}$/.test(hexAddress);
};
exports.isValidAddress = isValidAddress;
/**
* Returns a checksummed address.
*
* If an eip1191ChainId is provided, the chainId will be included in the checksum calculation. This
* has the effect of checksummed addresses for one chain having invalid checksums for others.
* For more details see [EIP-1191](https://eips.ethereum.org/EIPS/eip-1191).
*
* WARNING: Checksums with and without the chainId will differ and the EIP-1191 checksum is not
* backwards compatible to the original widely adopted checksum format standard introduced in
* [EIP-55](https://eips.ethereum.org/EIPS/eip-55), so this will break in existing applications.
* Usage of this EIP is therefore discouraged unless you have a very targeted use case.
*/
const toChecksumAddress = function (hexAddress, eip1191ChainId) {
(0, helpers_1.assertIsHexString)(hexAddress);
const address = (0, internal_1.stripHexPrefix)(hexAddress).toLowerCase();
let prefix = '';
if (eip1191ChainId) {
const chainId = (0, types_1.toType)(eip1191ChainId, types_1.TypeOutput.BN);
prefix = chainId.toString() + '0x';
}
const hash = (0, hash_1.keccakFromString)(prefix + address).toString('hex');
let ret = '0x';
for (let i = 0; i < address.length; i++) {
if (parseInt(hash[i], 16) >= 8) {
ret += address[i].toUpperCase();
}
else {
ret += address[i];
}
}
return ret;
};
exports.toChecksumAddress = toChecksumAddress;
/**
* Checks if the address is a valid checksummed address.
*
* See toChecksumAddress' documentation for details about the eip1191ChainId parameter.
*/
const isValidChecksumAddress = function (hexAddress, eip1191ChainId) {
return (0, exports.isValidAddress)(hexAddress) && (0, exports.toChecksumAddress)(hexAddress, eip1191ChainId) === hexAddress;
};
exports.isValidChecksumAddress = isValidChecksumAddress;
/**
* Generates an address of a newly created contract.
* @param from The address which is creating this new address
* @param nonce The nonce of the from account
*/
const generateAddress = function (from, nonce) {
(0, helpers_1.assertIsBuffer)(from);
(0, helpers_1.assertIsBuffer)(nonce);
const nonceBN = new externals_1.BN(nonce);
if (nonceBN.isZero()) {
// in RLP we want to encode null in the case of zero nonce
// read the RLP documentation for an answer if you dare
return (0, hash_1.rlphash)([from, null]).slice(-20);
}
// Only take the lower 160bits of the hash
return (0, hash_1.rlphash)([from, Buffer.from(nonceBN.toArray())]).slice(-20);
};
exports.generateAddress = generateAddress;
/**
* Generates an address for a contract created using CREATE2.
* @param from The address which is creating this new address
* @param salt A salt
* @param initCode The init code of the contract being created
*/
const generateAddress2 = function (from, salt, initCode) {
(0, helpers_1.assertIsBuffer)(from);
(0, helpers_1.assertIsBuffer)(salt);
(0, helpers_1.assertIsBuffer)(initCode);
(0, assert_1.default)(from.length === 20);
(0, assert_1.default)(salt.length === 32);
const address = (0, hash_1.keccak256)(Buffer.concat([Buffer.from('ff', 'hex'), from, salt, (0, hash_1.keccak256)(initCode)]));
return address.slice(-20);
};
exports.generateAddress2 = generateAddress2;
/**
* Checks if the private key satisfies the rules of the curve secp256k1.
*/
const isValidPrivate = function (privateKey) {
return (0, secp256k1_1.privateKeyVerify)(privateKey);
};
exports.isValidPrivate = isValidPrivate;
/**
* Checks if the public key satisfies the rules of the curve secp256k1
* and the requirements of Ethereum.
* @param publicKey The two points of an uncompressed key, unless sanitize is enabled
* @param sanitize Accept public keys in other formats
*/
const isValidPublic = function (publicKey, sanitize = false) {
(0, helpers_1.assertIsBuffer)(publicKey);
if (publicKey.length === 64) {
// Convert to SEC1 for secp256k1