UNPKG

truffle

Version:

Truffle - Simple development framework for Ethereum

1,456 lines (1,305 loc) 63.6 kB
#!/usr/bin/env node /******/ (() => { // webpackBootstrap /******/ var __webpack_modules__ = ({ /***/ 92936: /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ getAddress: () => (/* binding */ getAddress), /* harmony export */ getContractAddress: () => (/* binding */ getContractAddress), /* harmony export */ getCreate2Address: () => (/* binding */ getCreate2Address), /* harmony export */ getIcapAddress: () => (/* binding */ getIcapAddress), /* harmony export */ isAddress: () => (/* binding */ isAddress) /* harmony export */ }); /* harmony import */ var _ethersproject_bytes__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(46366); /* harmony import */ var _ethersproject_bignumber__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(2593); /* harmony import */ var _ethersproject_keccak256__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(38197); /* harmony import */ var _ethersproject_rlp__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(50284); /* harmony import */ var _ethersproject_logger__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(66167); /* harmony import */ var _version__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(6915); const logger = new _ethersproject_logger__WEBPACK_IMPORTED_MODULE_0__/* .Logger */ .Yd(_version__WEBPACK_IMPORTED_MODULE_1__/* .version */ .i); function getChecksumAddress(address) { if (!(0,_ethersproject_bytes__WEBPACK_IMPORTED_MODULE_2__/* .isHexString */ .A7)(address, 20)) { logger.throwArgumentError("invalid address", "address", address); } address = address.toLowerCase(); const chars = address.substring(2).split(""); const expanded = new Uint8Array(40); for (let i = 0; i < 40; i++) { expanded[i] = chars[i].charCodeAt(0); } const hashed = (0,_ethersproject_bytes__WEBPACK_IMPORTED_MODULE_2__/* .arrayify */ .lE)((0,_ethersproject_keccak256__WEBPACK_IMPORTED_MODULE_3__/* .keccak256 */ .w)(expanded)); for (let i = 0; i < 40; i += 2) { if ((hashed[i >> 1] >> 4) >= 8) { chars[i] = chars[i].toUpperCase(); } if ((hashed[i >> 1] & 0x0f) >= 8) { chars[i + 1] = chars[i + 1].toUpperCase(); } } return "0x" + chars.join(""); } // Shims for environments that are missing some required constants and functions const MAX_SAFE_INTEGER = 0x1fffffffffffff; function log10(x) { if (Math.log10) { return Math.log10(x); } return Math.log(x) / Math.LN10; } // See: https://en.wikipedia.org/wiki/International_Bank_Account_Number // Create lookup table const ibanLookup = {}; for (let i = 0; i < 10; i++) { ibanLookup[String(i)] = String(i); } for (let i = 0; i < 26; i++) { ibanLookup[String.fromCharCode(65 + i)] = String(10 + i); } // How many decimal digits can we process? (for 64-bit float, this is 15) const safeDigits = Math.floor(log10(MAX_SAFE_INTEGER)); function ibanChecksum(address) { address = address.toUpperCase(); address = address.substring(4) + address.substring(0, 2) + "00"; let expanded = address.split("").map((c) => { return ibanLookup[c]; }).join(""); // Javascript can handle integers safely up to 15 (decimal) digits while (expanded.length >= safeDigits) { let block = expanded.substring(0, safeDigits); expanded = parseInt(block, 10) % 97 + expanded.substring(block.length); } let checksum = String(98 - (parseInt(expanded, 10) % 97)); while (checksum.length < 2) { checksum = "0" + checksum; } return checksum; } ; function getAddress(address) { let result = null; if (typeof (address) !== "string") { logger.throwArgumentError("invalid address", "address", address); } if (address.match(/^(0x)?[0-9a-fA-F]{40}$/)) { // Missing the 0x prefix if (address.substring(0, 2) !== "0x") { address = "0x" + address; } result = getChecksumAddress(address); // It is a checksummed address with a bad checksum if (address.match(/([A-F].*[a-f])|([a-f].*[A-F])/) && result !== address) { logger.throwArgumentError("bad address checksum", "address", address); } // Maybe ICAP? (we only support direct mode) } else if (address.match(/^XE[0-9]{2}[0-9A-Za-z]{30,31}$/)) { // It is an ICAP address with a bad checksum if (address.substring(2, 4) !== ibanChecksum(address)) { logger.throwArgumentError("bad icap checksum", "address", address); } result = (0,_ethersproject_bignumber__WEBPACK_IMPORTED_MODULE_4__/* ._base36To16 */ .g$)(address.substring(4)); while (result.length < 40) { result = "0" + result; } result = getChecksumAddress("0x" + result); } else { logger.throwArgumentError("invalid address", "address", address); } return result; } function isAddress(address) { try { getAddress(address); return true; } catch (error) { } return false; } function getIcapAddress(address) { let base36 = (0,_ethersproject_bignumber__WEBPACK_IMPORTED_MODULE_4__/* ._base16To36 */ .t2)(getAddress(address).substring(2)).toUpperCase(); while (base36.length < 30) { base36 = "0" + base36; } return "XE" + ibanChecksum("XE00" + base36) + base36; } // http://ethereum.stackexchange.com/questions/760/how-is-the-address-of-an-ethereum-contract-computed function getContractAddress(transaction) { let from = null; try { from = getAddress(transaction.from); } catch (error) { logger.throwArgumentError("missing from address", "transaction", transaction); } const nonce = (0,_ethersproject_bytes__WEBPACK_IMPORTED_MODULE_2__/* .stripZeros */ .G1)((0,_ethersproject_bytes__WEBPACK_IMPORTED_MODULE_2__/* .arrayify */ .lE)(_ethersproject_bignumber__WEBPACK_IMPORTED_MODULE_4__/* .BigNumber */ .O$.from(transaction.nonce).toHexString())); return getAddress((0,_ethersproject_bytes__WEBPACK_IMPORTED_MODULE_2__/* .hexDataSlice */ .p3)((0,_ethersproject_keccak256__WEBPACK_IMPORTED_MODULE_3__/* .keccak256 */ .w)((0,_ethersproject_rlp__WEBPACK_IMPORTED_MODULE_5__.encode)([from, nonce])), 12)); } function getCreate2Address(from, salt, initCodeHash) { if ((0,_ethersproject_bytes__WEBPACK_IMPORTED_MODULE_2__/* .hexDataLength */ .E1)(salt) !== 32) { logger.throwArgumentError("salt must be 32 bytes", "salt", salt); } if ((0,_ethersproject_bytes__WEBPACK_IMPORTED_MODULE_2__/* .hexDataLength */ .E1)(initCodeHash) !== 32) { logger.throwArgumentError("initCodeHash must be 32 bytes", "initCodeHash", initCodeHash); } return getAddress((0,_ethersproject_bytes__WEBPACK_IMPORTED_MODULE_2__/* .hexDataSlice */ .p3)((0,_ethersproject_keccak256__WEBPACK_IMPORTED_MODULE_3__/* .keccak256 */ .w)((0,_ethersproject_bytes__WEBPACK_IMPORTED_MODULE_2__/* .concat */ .zo)(["0xff", getAddress(from), salt, initCodeHash])), 12)); } //# sourceMappingURL=index.js.map /***/ }), /***/ 20335: /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ Ox: () => (/* binding */ parseFixed), /* harmony export */ S5: () => (/* binding */ formatFixed), /* harmony export */ xs: () => (/* binding */ FixedNumber) /* harmony export */ }); /* unused harmony export FixedFormat */ /* harmony import */ var _ethersproject_bytes__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(46366); /* harmony import */ var _ethersproject_logger__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(66167); /* harmony import */ var _version__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(48794); /* harmony import */ var _bignumber__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(2593); const logger = new _ethersproject_logger__WEBPACK_IMPORTED_MODULE_0__/* .Logger */ .Yd(_version__WEBPACK_IMPORTED_MODULE_1__/* .version */ .i); const _constructorGuard = {}; const Zero = _bignumber__WEBPACK_IMPORTED_MODULE_2__/* .BigNumber */ .O$.from(0); const NegativeOne = _bignumber__WEBPACK_IMPORTED_MODULE_2__/* .BigNumber */ .O$.from(-1); function throwFault(message, fault, operation, value) { const params = { fault: fault, operation: operation }; if (value !== undefined) { params.value = value; } return logger.throwError(message, _ethersproject_logger__WEBPACK_IMPORTED_MODULE_0__/* .Logger */ .Yd.errors.NUMERIC_FAULT, params); } // Constant to pull zeros from for multipliers let zeros = "0"; while (zeros.length < 256) { zeros += zeros; } // Returns a string "1" followed by decimal "0"s function getMultiplier(decimals) { if (typeof (decimals) !== "number") { try { decimals = _bignumber__WEBPACK_IMPORTED_MODULE_2__/* .BigNumber */ .O$.from(decimals).toNumber(); } catch (e) { } } if (typeof (decimals) === "number" && decimals >= 0 && decimals <= 256 && !(decimals % 1)) { return ("1" + zeros.substring(0, decimals)); } return logger.throwArgumentError("invalid decimal size", "decimals", decimals); } function formatFixed(value, decimals) { if (decimals == null) { decimals = 0; } const multiplier = getMultiplier(decimals); // Make sure wei is a big number (convert as necessary) value = _bignumber__WEBPACK_IMPORTED_MODULE_2__/* .BigNumber */ .O$.from(value); const negative = value.lt(Zero); if (negative) { value = value.mul(NegativeOne); } let fraction = value.mod(multiplier).toString(); while (fraction.length < multiplier.length - 1) { fraction = "0" + fraction; } // Strip training 0 fraction = fraction.match(/^([0-9]*[1-9]|0)(0*)/)[1]; const whole = value.div(multiplier).toString(); if (multiplier.length === 1) { value = whole; } else { value = whole + "." + fraction; } if (negative) { value = "-" + value; } return value; } function parseFixed(value, decimals) { if (decimals == null) { decimals = 0; } const multiplier = getMultiplier(decimals); if (typeof (value) !== "string" || !value.match(/^-?[0-9.]+$/)) { logger.throwArgumentError("invalid decimal value", "value", value); } // Is it negative? const negative = (value.substring(0, 1) === "-"); if (negative) { value = value.substring(1); } if (value === ".") { logger.throwArgumentError("missing value", "value", value); } // Split it into a whole and fractional part const comps = value.split("."); if (comps.length > 2) { logger.throwArgumentError("too many decimal points", "value", value); } let whole = comps[0], fraction = comps[1]; if (!whole) { whole = "0"; } if (!fraction) { fraction = "0"; } // Trim trailing zeros while (fraction[fraction.length - 1] === "0") { fraction = fraction.substring(0, fraction.length - 1); } // Check the fraction doesn't exceed our decimals size if (fraction.length > multiplier.length - 1) { throwFault("fractional component exceeds decimals", "underflow", "parseFixed"); } // If decimals is 0, we have an empty string for fraction if (fraction === "") { fraction = "0"; } // Fully pad the string with zeros to get to wei while (fraction.length < multiplier.length - 1) { fraction += "0"; } const wholeValue = _bignumber__WEBPACK_IMPORTED_MODULE_2__/* .BigNumber */ .O$.from(whole); const fractionValue = _bignumber__WEBPACK_IMPORTED_MODULE_2__/* .BigNumber */ .O$.from(fraction); let wei = (wholeValue.mul(multiplier)).add(fractionValue); if (negative) { wei = wei.mul(NegativeOne); } return wei; } class FixedFormat { constructor(constructorGuard, signed, width, decimals) { if (constructorGuard !== _constructorGuard) { logger.throwError("cannot use FixedFormat constructor; use FixedFormat.from", _ethersproject_logger__WEBPACK_IMPORTED_MODULE_0__/* .Logger */ .Yd.errors.UNSUPPORTED_OPERATION, { operation: "new FixedFormat" }); } this.signed = signed; this.width = width; this.decimals = decimals; this.name = (signed ? "" : "u") + "fixed" + String(width) + "x" + String(decimals); this._multiplier = getMultiplier(decimals); Object.freeze(this); } static from(value) { if (value instanceof FixedFormat) { return value; } if (typeof (value) === "number") { value = `fixed128x${value}`; } let signed = true; let width = 128; let decimals = 18; if (typeof (value) === "string") { if (value === "fixed") { // defaults... } else if (value === "ufixed") { signed = false; } else { const match = value.match(/^(u?)fixed([0-9]+)x([0-9]+)$/); if (!match) { logger.throwArgumentError("invalid fixed format", "format", value); } signed = (match[1] !== "u"); width = parseInt(match[2]); decimals = parseInt(match[3]); } } else if (value) { const check = (key, type, defaultValue) => { if (value[key] == null) { return defaultValue; } if (typeof (value[key]) !== type) { logger.throwArgumentError("invalid fixed format (" + key + " not " + type + ")", "format." + key, value[key]); } return value[key]; }; signed = check("signed", "boolean", signed); width = check("width", "number", width); decimals = check("decimals", "number", decimals); } if (width % 8) { logger.throwArgumentError("invalid fixed format width (not byte aligned)", "format.width", width); } if (decimals > 80) { logger.throwArgumentError("invalid fixed format (decimals too large)", "format.decimals", decimals); } return new FixedFormat(_constructorGuard, signed, width, decimals); } } class FixedNumber { constructor(constructorGuard, hex, value, format) { if (constructorGuard !== _constructorGuard) { logger.throwError("cannot use FixedNumber constructor; use FixedNumber.from", _ethersproject_logger__WEBPACK_IMPORTED_MODULE_0__/* .Logger */ .Yd.errors.UNSUPPORTED_OPERATION, { operation: "new FixedFormat" }); } this.format = format; this._hex = hex; this._value = value; this._isFixedNumber = true; Object.freeze(this); } _checkFormat(other) { if (this.format.name !== other.format.name) { logger.throwArgumentError("incompatible format; use fixedNumber.toFormat", "other", other); } } addUnsafe(other) { this._checkFormat(other); const a = parseFixed(this._value, this.format.decimals); const b = parseFixed(other._value, other.format.decimals); return FixedNumber.fromValue(a.add(b), this.format.decimals, this.format); } subUnsafe(other) { this._checkFormat(other); const a = parseFixed(this._value, this.format.decimals); const b = parseFixed(other._value, other.format.decimals); return FixedNumber.fromValue(a.sub(b), this.format.decimals, this.format); } mulUnsafe(other) { this._checkFormat(other); const a = parseFixed(this._value, this.format.decimals); const b = parseFixed(other._value, other.format.decimals); return FixedNumber.fromValue(a.mul(b).div(this.format._multiplier), this.format.decimals, this.format); } divUnsafe(other) { this._checkFormat(other); const a = parseFixed(this._value, this.format.decimals); const b = parseFixed(other._value, other.format.decimals); return FixedNumber.fromValue(a.mul(this.format._multiplier).div(b), this.format.decimals, this.format); } floor() { const comps = this.toString().split("."); if (comps.length === 1) { comps.push("0"); } let result = FixedNumber.from(comps[0], this.format); const hasFraction = !comps[1].match(/^(0*)$/); if (this.isNegative() && hasFraction) { result = result.subUnsafe(ONE.toFormat(result.format)); } return result; } ceiling() { const comps = this.toString().split("."); if (comps.length === 1) { comps.push("0"); } let result = FixedNumber.from(comps[0], this.format); const hasFraction = !comps[1].match(/^(0*)$/); if (!this.isNegative() && hasFraction) { result = result.addUnsafe(ONE.toFormat(result.format)); } return result; } // @TODO: Support other rounding algorithms round(decimals) { if (decimals == null) { decimals = 0; } // If we are already in range, we're done const comps = this.toString().split("."); if (comps.length === 1) { comps.push("0"); } if (decimals < 0 || decimals > 80 || (decimals % 1)) { logger.throwArgumentError("invalid decimal count", "decimals", decimals); } if (comps[1].length <= decimals) { return this; } const factor = FixedNumber.from("1" + zeros.substring(0, decimals), this.format); const bump = BUMP.toFormat(this.format); return this.mulUnsafe(factor).addUnsafe(bump).floor().divUnsafe(factor); } isZero() { return (this._value === "0.0" || this._value === "0"); } isNegative() { return (this._value[0] === "-"); } toString() { return this._value; } toHexString(width) { if (width == null) { return this._hex; } if (width % 8) { logger.throwArgumentError("invalid byte width", "width", width); } const hex = _bignumber__WEBPACK_IMPORTED_MODULE_2__/* .BigNumber */ .O$.from(this._hex).fromTwos(this.format.width).toTwos(width).toHexString(); return (0,_ethersproject_bytes__WEBPACK_IMPORTED_MODULE_3__/* .hexZeroPad */ .$m)(hex, width / 8); } toUnsafeFloat() { return parseFloat(this.toString()); } toFormat(format) { return FixedNumber.fromString(this._value, format); } static fromValue(value, decimals, format) { // If decimals looks more like a format, and there is no format, shift the parameters if (format == null && decimals != null && !(0,_bignumber__WEBPACK_IMPORTED_MODULE_2__/* .isBigNumberish */ .Zm)(decimals)) { format = decimals; decimals = null; } if (decimals == null) { decimals = 0; } if (format == null) { format = "fixed"; } return FixedNumber.fromString(formatFixed(value, decimals), FixedFormat.from(format)); } static fromString(value, format) { if (format == null) { format = "fixed"; } const fixedFormat = FixedFormat.from(format); const numeric = parseFixed(value, fixedFormat.decimals); if (!fixedFormat.signed && numeric.lt(Zero)) { throwFault("unsigned value cannot be negative", "overflow", "value", value); } let hex = null; if (fixedFormat.signed) { hex = numeric.toTwos(fixedFormat.width).toHexString(); } else { hex = numeric.toHexString(); hex = (0,_ethersproject_bytes__WEBPACK_IMPORTED_MODULE_3__/* .hexZeroPad */ .$m)(hex, fixedFormat.width / 8); } const decimal = formatFixed(numeric, fixedFormat.decimals); return new FixedNumber(_constructorGuard, hex, decimal, fixedFormat); } static fromBytes(value, format) { if (format == null) { format = "fixed"; } const fixedFormat = FixedFormat.from(format); if ((0,_ethersproject_bytes__WEBPACK_IMPORTED_MODULE_3__/* .arrayify */ .lE)(value).length > fixedFormat.width / 8) { throw new Error("overflow"); } let numeric = _bignumber__WEBPACK_IMPORTED_MODULE_2__/* .BigNumber */ .O$.from(value); if (fixedFormat.signed) { numeric = numeric.fromTwos(fixedFormat.width); } const hex = numeric.toTwos((fixedFormat.signed ? 0 : 1) + fixedFormat.width).toHexString(); const decimal = formatFixed(numeric, fixedFormat.decimals); return new FixedNumber(_constructorGuard, hex, decimal, fixedFormat); } static from(value, format) { if (typeof (value) === "string") { return FixedNumber.fromString(value, format); } if ((0,_ethersproject_bytes__WEBPACK_IMPORTED_MODULE_3__/* .isBytes */ ._t)(value)) { return FixedNumber.fromBytes(value, format); } try { return FixedNumber.fromValue(value, 0, format); } catch (error) { // Allow NUMERIC_FAULT to bubble up if (error.code !== _ethersproject_logger__WEBPACK_IMPORTED_MODULE_0__/* .Logger */ .Yd.errors.INVALID_ARGUMENT) { throw error; } } return logger.throwArgumentError("invalid FixedNumber value", "value", value); } static isFixedNumber(value) { return !!(value && value._isFixedNumber); } } const ONE = FixedNumber.from(1); const BUMP = FixedNumber.from("0.5"); //# sourceMappingURL=fixednumber.js.map /***/ }), /***/ 55114: /***/ ((module, __unused_webpack_exports, __webpack_require__) => { module.exports = { run: __webpack_require__(27970), meta: __webpack_require__(14957) }; /***/ }), /***/ 27970: /***/ ((module, __unused_webpack_exports, __webpack_require__) => { const emoji = __webpack_require__(58445); const mnemonicInfo = __webpack_require__(25603); const { configureManagedGanache, getFirstDefinedValue } = __webpack_require__(84973); const runConsole = async (config, ganacheOptions) => { const { Console } = __webpack_require__(68303); const { Environment } = __webpack_require__(76765); await Environment.develop(config, ganacheOptions); const c = new Console(config.with({ noAliases: true })); c.on("exit", () => process.exit()); return await c.start(); }; module.exports = async options => { const { Develop } = __webpack_require__(76765); const Config = __webpack_require__(20553); const config = Config.detect(options); const customConfig = config.networks.develop || {}; const numberOfAccounts = getFirstDefinedValue( customConfig.accounts, customConfig.total_accounts, 10 // Use as default number of accounts ); const { mnemonic, accounts, privateKeys } = mnemonicInfo.getAccountsInfo(numberOfAccounts); const onMissing = () => "**"; const warning = ":warning: Important :warning: : " + "This mnemonic was created for you by Truffle. It is not secure.\n" + "Ensure you do not use it on production blockchains, or else you risk losing funds."; const ipcOptions = {}; if (options.log) { ipcOptions.log = options.log; } const ganacheOptions = configureManagedGanache( config, customConfig, mnemonic ); const { started } = await Develop.connectOrStart( ipcOptions, ganacheOptions, config?.solidityLog?.displayPrefix ?? "" ); const url = `http://${ganacheOptions.host}:${ganacheOptions.port}/`; if (started) { config.logger.log(`Truffle Develop started at ${url}`); config.logger.log(); config.logger.log(`Accounts:`); accounts.forEach((acct, idx) => config.logger.log(`(${idx}) ${acct}`)); config.logger.log(); config.logger.log(`Private Keys:`); privateKeys.forEach((key, idx) => config.logger.log(`(${idx}) ${key}`)); config.logger.log(); config.logger.log(`Mnemonic: ${mnemonic}`); config.logger.log(); config.logger.log(emoji.emojify(warning, onMissing)); config.logger.log(); } else { config.logger.log( `Connected to existing Truffle Develop session at ${url}` ); config.logger.log(); } if (options.log) { // leave the process open so that logging can take place return new Promise(() => {}); } return await runConsole(config, ganacheOptions); }; /***/ }), /***/ 84973: /***/ ((module) => { function resolveNetworkId(network_id) { // Use default network_id if "*" is defined in config if (network_id === "*") { return Date.now(); } const parsedNetworkId = parseInt(network_id, 10); if (isNaN(parsedNetworkId)) { const error = `The network id specified in the truffle config ` + `(${network_id}) is not valid. Please properly configure the network id as an integer value.`; throw new Error(error); } return parsedNetworkId; } // This function returns the first defined argument value const getFirstDefinedValue = (...values) => values.find(value => value !== undefined); function configureManagedGanache(config, networkConfig, mnemonic) { const host = getFirstDefinedValue( networkConfig.host, "127.0.0.1" // Use as default host ); const port = getFirstDefinedValue( networkConfig.port, 9545 // Use as default port ); const network_id = getFirstDefinedValue( networkConfig.network_id, 5777 // Use as default network_id ); const resolvedNetworkId = resolveNetworkId(network_id); const total_accounts = getFirstDefinedValue( networkConfig.accounts, networkConfig.total_accounts, 10 // Use as default number of accounts ); const default_balance_ether = getFirstDefinedValue( networkConfig.defaultEtherBalance, networkConfig.default_balance_ether, 100 // Use as default ether balance for each account ); const blockTime = getFirstDefinedValue( networkConfig.blockTime, 0 // Use as default block time ); const gasLimit = getFirstDefinedValue( networkConfig.gasLimit, 0x6691b7 // Use as default gasLimit ); const gasPrice = getFirstDefinedValue( networkConfig.gasPrice, 0x77359400 // Use default gas price 2000000000 wei ); const genesisTime = getFirstDefinedValue( // Higher precedence is given to the networkConfig.time or networkConfig.genesis_time networkConfig.time, networkConfig.genesis_time, config.time, config.genesis_time ); const fork = networkConfig.fork; const hardfork = networkConfig.hardfork; const ganacheOptions = { host, port, network_id: resolvedNetworkId, total_accounts, default_balance_ether, blockTime, fork, hardfork, mnemonic, gasLimit, gasPrice, time: genesisTime, miner: { instamine: "eager" } }; return ganacheOptions; } module.exports = { configureManagedGanache, getFirstDefinedValue }; /***/ }), /***/ 68303: /***/ ((module, __unused_webpack_exports, __webpack_require__) => { const repl = __webpack_require__(38102); const provision = __webpack_require__(7702); const { Web3Shim, createInterfaceAdapter } = __webpack_require__(36339); const contract = __webpack_require__(78883); const os = __webpack_require__(22037); const vm = __webpack_require__(26144); const expect = __webpack_require__(14096); const TruffleError = __webpack_require__(73321); const fse = __webpack_require__(55674); const path = __webpack_require__(71017); const EventEmitter = __webpack_require__(82361); const { spawn } = __webpack_require__(32081); const Require = __webpack_require__(35422); const debug = __webpack_require__(15158)("console"); const { parseQuotesAndEscapes } = __webpack_require__(34763); const { excludedTruffleConsoleCommands, validTruffleConsoleCommands } = __webpack_require__(91874); // Create an expression that returns a string when evaluated // by the REPL const makeIIFE = str => `(() => "${str}")()`; const processInput = input => { const words = input.trim().split(/\s+/); // empty input if (words.length === 0) return input; // maybe truffle command if (words[0].toLowerCase() === "truffle") { const cmd = words[1]; if (cmd === undefined) { return makeIIFE( `ℹ️ : 'Missing truffle command. Please include a valid truffle command.` ); } const normalizedCommand = cmd.toLowerCase(); const isExcludedInREPL = excludedTruffleConsoleCommands.includes(normalizedCommand); if (isExcludedInREPL) { return makeIIFE( `ℹ️ : '${words[0]} ${cmd}' is not allowed in Console environment.` ); } if (!validTruffleConsoleCommands.includes(normalizedCommand)) { return makeIIFE( `ℹ️ : '${words[0]} ${cmd}' is not a valid truffle command.` ); } return words.slice(1).join(" "); } // an expression return input.trim(); }; class Console extends EventEmitter { constructor(options) { super(); EventEmitter.call(this); expect.options(options, [ "working_directory", "contracts_directory", "contracts_build_directory", "migrations_directory", "networks", "network", "network_id", "provider", "resolver", "build_directory" ]); this.options = options; this.repl = null; // we need to keep track of name conflicts that occur between contracts and // repl context objects so as not to overwrite them - this is to prevent // overwriting Node native objects like Buffer, number, etc. this.replGlobals = new Set(); this.knownReplNameConflicts = new Set(); this.newReplNameConflicts = new Set(); this.interfaceAdapter = createInterfaceAdapter({ provider: options.provider, networkType: options.networks[options.network].type }); this.web3 = new Web3Shim({ provider: options.provider, networkType: options.networks[options.network].type }); } recordNameConflicts(abstractions) { for (const abstraction of abstractions) { const name = abstraction.contract_name; if ( !this.knownReplNameConflicts.has(name) && this.replGlobals.has(name) ) { this.newReplNameConflicts.add(name); this.knownReplNameConflicts.add(name); } } } async start() { try { // start the repl with an empty prompt and show a proper one when // the repl has set up its context and is ready to accept input this.repl = repl.start({ prompt: "", eval: this.interpret.bind(this) }); // Get and set Truffle and User Globals const truffleAndUserGlobals = await this.calculateTruffleAndUserGlobals(); Object.entries(truffleAndUserGlobals).forEach(([key, value]) => { this.repl.context[key] = value; }); // record name conflicts to avoid clobbering globals with contracts this.replGlobals = new Set( Object.getOwnPropertyNames(this.repl.context.global) ); // repl is ready - set and display prompt this.repl.setPrompt("truffle(" + this.options.network + ")> "); // hydrate the environment with the user's contracts this.provision(); // provision first before displaying prompt so that if // there is a warning the user will end up at the prompt this.repl.displayPrompt(); this.repl.on("exit", () => { process.exit(); }); // ensure that `await`-ing this method never resolves. (we want to keep // the console open until it exits on its own) return new Promise(() => {}); } catch (error) { this.options.logger.log( "Unexpected error setting up the environment or provisioning " + "contracts while instantiating the console." ); this.options.logger.log(error.stack || error.message || error); } } getUserDefinedGlobals({ accounts, interfaceAdapter, web3 }) { // exit if feature should be disabled if (this.options["require-none"]) return; // exit if no hydrate options are set if ( (!this.options.console || !this.options.console.require) && !this.options.require && !this.options.r ) return; const addToContext = (context, userData, namespace) => { for (const key in userData) { if (namespace) { if (typeof context[namespace] === "undefined") { context[namespace] = {}; } context[namespace][key] = userData[key]; } else { context[key] = userData[key]; } } }; const errorMessage = "You must specify the console.require property as " + "either a string or an array. If you specify an array, its members " + "must be paths or objects containing at least a `path` property."; const requireValue = this.options.r || this.options.require || this.options.console.require; // Require allows us to inject Truffle variables into the script's scope const requireOptions = { context: { accounts, interfaceAdapter, web3 } }; const userGlobals = {}; if (typeof requireValue === "string") { requireOptions.file = requireValue; addToContext(userGlobals, Require.file(requireOptions)); } else if (Array.isArray(requireValue)) { this.options.console.require.forEach(item => { if (typeof item === "string") { requireOptions.file = item; addToContext(userGlobals, Require.file(requireOptions)); } else if (typeof item === "object" && item.path) { requireOptions.file = item.path; addToContext(userGlobals, Require.file(requireOptions), item.as); } else { throw new Error(errorMessage); } }); } else { throw new Error(errorMessage); } return userGlobals; } async calculateTruffleAndUserGlobals() { let accounts; try { accounts = await this.interfaceAdapter.getAccounts(); } catch { // don't prevent Truffle from working if user doesn't provide some way // to sign transactions (e.g. no reason to disallow debugging) accounts = []; } const userGlobals = this.getUserDefinedGlobals({ web3: this.web3, interfaceAdapter: this.interfaceAdapter, accounts }); const truffleGlobals = { web3: this.web3, interfaceAdapter: this.interfaceAdapter, accounts, artifacts: this.options.resolver }; // we insert user variables first so as to not clobber Truffle's return { ...userGlobals, ...truffleGlobals }; } provision() { let files = []; let jsonBlobs = []; try { files = fse.readdirSync(this.options.contracts_build_directory); } catch (error) { // Error reading the build directory? Must mean it doesn't exist or we don't have access to it. // Couldn't provision the contracts if we wanted. It's possible we're hiding very rare FS // errors, but that's better than showing the user error messages that will be "build folder // doesn't exist" 99.9% of the time. } files.forEach(file => { // filter out non artifacts if (!file.endsWith(".json")) return; try { const body = fse.readFileSync( path.join(this.options.contracts_build_directory, file), "utf8" ); const json = JSON.parse(body); // Artifacts may not contain metadata. For example, early Solidity versions as well as // Vyper contracts do not include metadata. Just push them to json blobs. if (json.metadata === undefined) { jsonBlobs.push(json); } else { // filter out Truffle's console.log. We don't want users to interact with in the REPL. // user contracts named console.log will be imported, and a warning will be issued. const metadata = JSON.parse(json.metadata); const sources = Object.keys(metadata.sources); if ( sources.length > 1 || (sources.length === 1 && !sources.some(source => { return ( source === "truffle/console.sol" || source === "truffle/Console.sol" ); })) ) { jsonBlobs.push(json); } } } catch (error) { throw new Error(`Error parsing or reading ${file}: ${error.message}`); } }); const abstractions = jsonBlobs.map(json => { const abstraction = contract(json); provision(abstraction, this.options); return abstraction; }); this.recordNameConflicts(abstractions); this.resetContractsInConsoleContext(abstractions); return abstractions; } resetContractsInConsoleContext(abstractions) { abstractions = abstractions || []; const contextVars = {}; abstractions.forEach(abstraction => { const name = abstraction.contract_name; // don't overwrite Node's native objects - only load contracts // into the repl context when no conflict exists if (!this.knownReplNameConflicts.has(name)) { contextVars[name] = abstraction; } }); if (this.newReplNameConflicts.size > 0) { const contractNames = [...this.newReplNameConflicts.keys()]; this.newReplNameConflicts.clear(); console.log( `\n > Warning: One or more of your contract(s) has a name conflict ` + `with something in the current repl context and was not loaded by ` + `default. \n > You can use 'artifacts.require("<artifactName>")' ` + `to obtain a reference to your contract(s). \n > Truffle recommends ` + `that you rename your contract to avoid problems. \n > The following ` + `name conflicts exist: ${contractNames.join(", ")}.\n` ); } // make sure the repl gets the new contracts in its context Object.keys(contextVars || {}).forEach(key => { this.repl.context[key] = contextVars[key]; }); } async runSpawn(inputStrings, options) { let childPath; /* eslint-disable no-undef */ if (true) { childPath = path.join(__dirname, "consoleChild.bundled.js"); } else {} const spawnOptions = { stdio: "pipe" }; const settings = ["config", "network", "url"] .filter(setting => options[setting]) .map(setting => `--${setting} ${options[setting]}`) .join(" "); const spawnInput = `${settings} -- ${inputStrings}`; const spawnedProcess = spawn( "node", ["--no-deprecation", childPath, spawnInput], spawnOptions ); // Theoretically stderr can contain multiple errors. // So let's just print it instead of throwing through // the error handling mechanism. Bad call? Who knows... // better be safe and buffer stderr so that it doesn't // interrupt stdout, and present it as a complete // string at the end of the spawned process. let bufferedError = ""; spawnedProcess.stderr.on("data", data => { bufferedError += data.toString(); }); spawnedProcess.stdout.on("data", data => { // convert buffer to string data = data.toString(); // workaround: remove extra newline in `truffle develop` console // truffle test, for some reason, appends a newline to the data // it emits here. if (data.endsWith(os.EOL)) data = data.slice(0, -os.EOL.length); console.log(data); }); return new Promise((resolve, reject) => { spawnedProcess.on("close", code => { // dump bufferedError debug(bufferedError); if (!code) { // re-provision to ensure any changes are available in the repl this.provision(); //display prompt when child repl process is finished this.repl.displayPrompt(); return void resolve(); } reject(code); }); }); } async interpret(input, context, filename, callback) { const processedInput = processInput(input); if (validTruffleConsoleCommands.includes(processedInput.split(/\s+/)[0])) { try { parseQuotesAndEscapes(processedInput); //we're just doing this to see //if it errors. unfortunately we need to throw out the result and recompute //it afterward (but the input string is probably short so it's OK). await this.runSpawn(processedInput, this.options); } catch (error) { // Perform error handling ourselves. if (error instanceof TruffleError) { console.log(error.message); } else { // Bubble up all other unexpected errors. console.log(error.stack || error.toString()); } return callback(); } // Reprovision after each command as it may change contracts. try { this.provision(); return callback(); } catch (error) { // Don't pass abstractions to the callback if they're there or else // they'll get printed in the repl. return callback(error); } } // Much of the following code is from here, though spruced up: // https://github.com/nfcampos/await-outside /* - allow whitespace before everything else - optionally capture `var| let |const <varname> = ` - varname only matches if it starts with a-Z or _ or $ and if contains only those chars or numbers - this is overly restrictive but is easier to maintain - capture `await <anything that follows it>` */ let includesAwait = /^\s*((?:(?:var|const|let)\s+)?[a-zA-Z_$][0-9a-zA-Z_$]*\s*=\s*)?(\(?\s*await[\s\S]*)/; const match = processedInput.match(includesAwait); let source = processedInput; let assignment = null; // If our code includes an await, add special processing to ensure it's evaluated properly. if (match) { let assign = match[1]; const expression = match[2] && match[2].endsWith(";") ? // strip off trailing ";" to prevent the expression below from erroring match[2].slice(0, -1) : match[2]; const RESULT = "__await_outside_result"; // Wrap the await inside an async function. // Strange indentation keeps column offset correct in stack traces source = `(async function() { try {${ assign ? `global.${RESULT} =` : "return" } ( ${expression.trim()} ); } catch(e) {global.ERROR = e; throw e; } }())`; assignment = assign ? `${assign.trim()} global.${RESULT}; void delete global.${RESULT};` : null; //finally, if the assignment did not use var, const, or let, make sure to //return the result afterward if (assign) { const bareAssignmentMatch = assign.match( /^\s*([a-zA-Z_$][0-9a-zA-Z_$]*)\s*=\s*/ ); if (bareAssignmentMatch) { const varName = bareAssignmentMatch[1]; assignment += varName; } } } const runScript = script => { const options = { displayErrors: false, breakOnSigint: true, filename: filename }; vm.createContext(context); return script.runInContext(context, options); }; let script; try { const options = { lineOffset: -1 }; script = vm.createScript(source, options); } catch (error) { // If syntax error, or similar, bail. return callback(error); } // Ensure our script returns a promise whether we're using an // async function or not. If our script is an async function, // this will ensure the console waits until that await is finished. Promise.resolve(runScript(script)) .then(value => { // If there's an assignment to run, run that. if (assignment) return runScript(vm.createScript(assignment)); return value; }) .then(value => { // All good? Return the value (e.g., eval'd script or assignment) callback(null, value); }) .catch(callback); } } module.exports = { Console }; /***/ }), /***/ 25603: /***/ ((module, __unused_webpack_exports, __webpack_require__) => { /** * @module mnemonic; * @requires module:@truffle/config * @requires module:seedrandom * @requires module:ethereum-cryptography * @requires module:@truffle/hdwallet * @requires module:crypto */ const Config = __webpack_require__(20553); const defaultUserConfig = Config.getUserConfig(); const { entropyToMnemonic, mnemonicToSeedSync } = __webpack_require__(89211); const { wordlist } = __webpack_require__(48732); const crypto = __webpack_require__(6113); const { createAccountGeneratorFromSeedAndPath, uncompressedPublicKeyToAddress } = __webpack_require__(75262); const mnemonic = { /** * gets user-level mnemonic from user config, and if missing generates a new mnemonic * @returns {String} mnemonic */ getOrGenerateMnemonic: function () { let mnemonic; const userMnemonicExists = defaultUserConfig.get("mnemonic"); if (!userMnemonicExists) { mnemonic = entropyToMnemonic(crypto.randomBytes(16), wordlist); defaultUserConfig.set({ mnemonic: mnemonic }); } else { mnemonic = userMnemonicExists; } return mnemonic; }, /** * gets accounts object using mnemonic * @param {String} * @returns {Object} mnemonicObject */ getAccountsInfo: function (numAddresses) { let mnemonic = this.getOrGenerateMnemonic(); let accounts = []; let privateKeys = []; let walletHdpath = "m/44'/60'/0'/0".split("/"); let hdwallet = createAccountGeneratorFromSeedAndPath( Buffer.from(mnemonicToSeedSync(mnemonic)), walletHdpath ); let addressIndex = 0; for (let i = addressIndex; i < addressIndex + numAddresses; i++) { let wallet = hdwallet(i); let addr = `0x${Buffer.from( uncompressedPublicKeyToAddress(wallet.publicKey) ).toString("hex")}`; let privKey = wallet.privateKey.toString("hex"); accounts.push(addr); privateKeys.push(privKey); } return { mnemonic, accounts, privateKeys }; } }; module.exports = mnemonic; /***/ }), /***/ 75262: /***/ (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.uncompressedPublicKeyToAddress = exports.createAccountGeneratorFromSeedAndPath = void 0; const keccak_1 = __webpack_require__(95901); const crypto_1 = __webpack_require__(6113); const secp256k1_1 = __importDefault(__webpack_require__(7972)); const HARDENED_OFFSET = 0x80000000; const MASTER_SECRET = Buffer.from("Bitcoin seed", "utf8"); function createAccountGeneratorFromSeedAndPath(seedBuffer, hdPath) { const parent = createAccountFromSeed(seedBuffer); const path = deriveFromPath(hdPath, parent); return (index) => { return deriveFromIndex(index, path); }; } exports.createAccountGeneratorFromSeedAndPath = createAccountGeneratorFromSeedAndPath; const uncompressedPublicKeyToAddress = (uncompressedPublicKey) => { const address = Buffer.from(secp256k1_1.default.publicKeyConvert(uncompressedPublicKey, false)); // first byte is discarded const hash = (0, keccak_1.keccak256)(address.slice(1)); return hash.slice(-20); // address is the last 20 }; exports.uncompressedPublicKeyToAddress = uncompressedPublicKeyToAddress; function createAccountFromSeed(seedBuffer) { const I = (0, crypto_1.createHmac)("sha512", MASTER_SECRET).update(seedBuffer).digest(); const privateKey = I.slice(0, 32); const chainCode = I.slice(32); const publicKey = makePublicKey(privateKey); return { privateKey, chainCode, publicKey }; } function deriveFromPath(fullPath, child) { fullPath.forEach(function (c, i) { if (i === 0) { if (!/^[mM]{1}/.test(c)) { throw new Error('Path must start with "m" or "M"'); } return; } const hardened = c.length > 1 && c[c.length - 1] === "'"; let childIndex = parseInt(c, 10); if (childIndex >= HARDENED_OFFSET) throw new Error("Invalid index"); if (hardened) childIndex += HARDENED_OFFSET; child = deriveChild(childIndex, hardened, child.privateKey, child.publicKey, child.chainCode); }); return child; } function deriveFromIndex(index, child) { if (index >= HARDENED_OFFSET) throw new Error("Invalid index"); return deriveChild(index, false, child.privateKey, child.publicKey, child.chainCode); } function makePublicKey(privateKey) { return secp256k1_1.default.publicKeyCreate(privateKey); } /** * A buffer of size 4 that can be reused as long as all changes are consumed * within the same event loop. */ const SHARED_BUFFER_4 = Buffer.allocUnsafe(4); function deriveChild(index, isHardened, privateKey, publicKey, chainCode) { const indexBuffer = SHARED_BUFFER_4; indexBuffer.writeUInt32BE(index, 0); let data; const privateKeyLength = privateKey.length; if (isHardened) { // Hardened child // privateKeyLength + 1 (BUFFER_ZERO.length) + 4 (indexBuffer.length) const dataLength = privateKeyLength + 1 + 4; data = Buffer.concat([Buffer.allocUnsafe(1).fill(0), privateKey, indexBuffer], dataLength); } else { //