truffle
Version:
Truffle - Simple development framework for Ethereum
1,542 lines (1,335 loc) • 61.2 kB
JavaScript
#!/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
/***/ }),
/***/ 8230:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
module.exports = {
run: __webpack_require__(1527),
meta: __webpack_require__(5561)
};
/***/ }),
/***/ 5561:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
const migrate = __webpack_require__(1827);
module.exports = {
command: "deploy",
description: "(alias for migrate)",
builder: migrate.builder,
help: {
usage:
"truffle deploy [--reset] [-f <number>] [--compile-all] [--verbose-rpc]",
options: migrate.meta.help.options,
allowedGlobalOptions: ["network", "config"]
}
};
/***/ }),
/***/ 1527:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
const runMigrate = __webpack_require__(52423);
module.exports = runMigrate;
/***/ }),
/***/ 83292:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
const Ganache = __webpack_require__(11651);
module.exports = function (config, options) {
//note: this is a list of chain IDs but we're still using
//network ID. This should be fixed later.
const supportedChainIds = Ganache.__experimental_info().fork.knownChainIds;
let dryRunOnly, skipDryRun;
const networkSettingsInConfig = config.networks[config.network];
if (networkSettingsInConfig) {
dryRunOnly =
options.dryRun === true ||
networkSettingsInConfig.dryRun === true ||
networkSettingsInConfig["dry-run"] === true;
skipDryRun =
options.skipDryRun === true ||
networkSettingsInConfig.skipDryRun === true ||
networkSettingsInConfig["skip-dry-run"] === true;
} else {
dryRunOnly = options.dryRun === true;
skipDryRun = options.skipDryRun === true;
}
const production =
supportedChainIds.includes(parseInt(config.network_id)) ||
config.production;
const dryRunAndMigrations = production && !skipDryRun;
return { dryRunOnly, dryRunAndMigrations };
};
/***/ }),
/***/ 1827:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
module.exports = {
run: __webpack_require__(52423),
meta: __webpack_require__(88226),
runMigrations: __webpack_require__(96146),
setUpDryRunEnvironmentThenRunMigrations: __webpack_require__(43687),
determineDryRunSettings: __webpack_require__(83292),
prepareConfigForRealMigrations: __webpack_require__(97374)
};
/***/ }),
/***/ 88226:
/***/ ((module) => {
module.exports = {
command: "migrate",
description: "Run migrations to deploy contracts",
builder: {
"reset": {
type: "boolean",
default: false
},
"compile-all": {
describe: "Recompile all contracts",
type: "boolean",
default: false
},
"compile-none": {
describe: "Do not compile contracts",
type: "boolean",
default: false
},
"--verbose-rpc": {
describe: "Log communication between Truffle and the Ethereum client.",
type: "boolean",
default: false
},
"dry-run": {
describe: "Run migrations against an in-memory fork, for testing",
type: "boolean",
default: false
},
"skip-dry-run": {
describe: "Skip the test or 'dry run' migrations",
type: "boolean",
default: false
},
"f": {
describe: "Specify a migration number to run from",
type: "number"
},
"to": {
describe: "Specify a migration number to run to",
type: "number"
},
"interactive": {
describe: "Manually authorize deployments after seeing a preview",
type: "boolean",
default: false
},
"describe-json": {
describe: "Adds extra verbosity to the status of an ongoing migration",
type: "boolean",
default: false
},
"save": {
describe: "Specify whether the migration will save on chain",
type: "boolean",
default: true,
hidden: true
}
},
help: {
usage:
"truffle migrate [--reset] [--f <number>] [--to <number>]\n" +
" " + // spacing to align with previous line
"[--compile-all] [--compile-none] [--verbose-rpc] [--interactive]\n" +
" " + // spacing to align with previous line
"[--skip-dry-run] [--describe-json] [--dry-run]",
options: [
{
option: "--reset",
description:
"Run all migrations from the beginning, instead of running from the last " +
"completed migration."
},
{
option: "--f <number>",
description:
"Run contracts from a specific migration. The number refers to the prefix of " +
"the migration file."
},
{
option: "--to <number>",
description:
"Run contracts to a specific migration. The number refers to the prefix of the migration file."
},
{
option: "--compile-all",
description:
"Compile all contracts instead of intelligently choosing which contracts need to " +
"be compiled."
},
{
option: "--compile-none",
description: "Do not compile any contracts before migrating."
},
{
option: "--verbose-rpc",
description:
"Log communication between Truffle and the Ethereum client."
},
{
option: "--interactive",
description:
"Prompt to confirm that the user wants to proceed after the dry run."
},
{
option: "--dry-run",
description: "Only perform a test or 'dry run' migration."
},
{
option: "--skip-dry-run",
description: "Do not run a test or 'dry run' migration."
},
{
option: "--describe-json",
description:
"Adds extra verbosity to the status of an ongoing migration"
},
{
option: "--save",
description: "Specify whether the migration will save on chain",
hidden: true
}
],
allowedGlobalOptions: ["network", "config", "quiet"]
}
};
/***/ }),
/***/ 97374:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
module.exports = async function (buildDir, options) {
const Artifactor = __webpack_require__(29463);
const { Resolver } = __webpack_require__(48511);
const Migrate = (__webpack_require__(22478)["default"]);
const { Environment } = __webpack_require__(76765);
const Config = __webpack_require__(20553);
let accept = true;
if (options.interactive) {
accept = await Migrate.promptToAcceptDryRun();
}
if (accept) {
const config = Config.detect(options);
config.contracts_build_directory = buildDir;
config.artifactor = new Artifactor(buildDir);
config.resolver = new Resolver(config);
try {
await Environment.detect(config);
} catch (error) {
throw new Error(error);
}
config.dryRun = false;
return {
preparedConfig: config,
proceed: true
};
} else {
return { proceed: false };
}
};
/***/ }),
/***/ 52423:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
module.exports = async function (options) {
const WorkflowCompile = (__webpack_require__(37017)["default"]);
const { Environment } = __webpack_require__(76765);
const Config = __webpack_require__(20553);
const determineDryRunSettings = __webpack_require__(83292);
const prepareConfigForRealMigrations = __webpack_require__(97374);
const runMigrations = __webpack_require__(96146);
const setUpDryRunEnvironmentThenRunMigrations = __webpack_require__(43687);
const tmp = __webpack_require__(36276);
tmp.setGracefulCleanup();
const config = Config.detect(options);
if (config.compileNone || config["compile-none"]) {
config.compiler = "none";
}
const result = await WorkflowCompile.compileAndSave(config);
await WorkflowCompile.assignNames(config, result);
await Environment.detect(config);
const { dryRunOnly, dryRunAndMigrations } = determineDryRunSettings(
config,
options
);
if (dryRunOnly) {
config.dryRun = true;
await setUpDryRunEnvironmentThenRunMigrations(config);
} else if (dryRunAndMigrations) {
const currentBuild = config.contracts_build_directory;
config.dryRun = true;
await setUpDryRunEnvironmentThenRunMigrations(config);
const { preparedConfig, proceed } = await prepareConfigForRealMigrations(
currentBuild,
options
);
if (proceed) await runMigrations(preparedConfig);
} else {
await runMigrations(config);
}
};
/***/ }),
/***/ 96146:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
const { createReadStream } = __webpack_require__(57147);
const { readdir } = __webpack_require__(73292);
const path = __webpack_require__(71017);
const JSONStream = __webpack_require__(31327);
const Migrate = (__webpack_require__(22478)["default"]);
const TruffleError = __webpack_require__(73321);
const os = __webpack_require__(22037);
const debug = __webpack_require__(15158)("migrate:run");
// Search for Push1 (60) to Push(32) 7F + console.log
// 60 ---- 7F C O N S O L E . L O G
const consoleLogRex = /[67][0-9a-f]636F6e736F6c652e6c6f67/i;
async function usesConsoleLog(artifactJson) {
const debugLog = debug.extend("test");
debugLog("Artifact: %o", artifactJson);
//create a parser to get the value of jsonpath .deployedBytecode
const parser = JSONStream.parse(["deployedBytecode"]);
const stream = createReadStream(artifactJson).pipe(parser);
return new Promise((resolve, reject) => {
stream.on("data", data => {
//JSONParse will emit the entire string/value
//so initiate stream cleanup here
stream.destroy();
const usesConsoleLog = consoleLogRex.test(data);
debugLog("usesConsoleLog:", usesConsoleLog);
resolve(usesConsoleLog);
});
stream.on("error", err => {
stream.destroy();
debugLog("onError: %o", err);
reject(err);
});
});
}
async function findArtifactsThatUseConsoleLog(buildDir) {
const debugLog = debug.extend("dirty-files");
const filenames = await readdir(buildDir);
const artifacts = [];
await Promise.allSettled(
filenames.map(async filename => {
if (filename.endsWith(".json")) {
try {
const itLogs = await usesConsoleLog(path.join(buildDir, filename));
if (itLogs) {
artifacts.push(filename);
}
} catch (e) {
debugLog("Promise failure: %o", e.message);
}
}
})
);
return artifacts;
}
module.exports = async function (config) {
const debugLog = debug.extend("guard");
// only check if deploying on MAINNET
// NOTE: this includes Ethereum Classic as well as Ethereum as they're only
// distinguishable by checking their chainIds, 2 and 1 respectively.
if (config.network_id === 1) {
debugLog("solidityLog guard for mainnet");
try {
const buildDir = config.contracts_build_directory;
const loggingArtifacts = await findArtifactsThatUseConsoleLog(buildDir);
debugLog(`${loggingArtifacts.length} consoleLog artifacts detected`);
debugLog(
"config.solidityLog.preventConsoleLogMigration: " +
config.solidityLog.preventConsoleLogMigration
);
if (loggingArtifacts.length) {
console.warn(
`${os.EOL}Solidity console.log detected in the following assets:`
);
console.warn(loggingArtifacts.join(", "));
console.warn();
if (config.solidityLog.preventConsoleLogMigration) {
throw new TruffleError(
"You are trying to deploy contracts that use console.log." +
os.EOL +
"Please fix, or disable this check by setting solidityLog.preventConsoleLogMigration to false" +
os.EOL
);
}
}
} catch (err) {
if (err instanceof TruffleError) throw err;
debugLog("Unexpected error %o:", err);
// Something went wrong while inspecting for console log.
// Log warning and skip the remaining logic in this branch
console.warn();
console.warn(
"Failed to detect Solidity console.log usage:" + os.EOL + err
);
}
}
if (config.f) {
return await Migrate.runFrom(config.f, config);
} else {
const needsMigrating = await Migrate.needsMigrating(config);
if (needsMigrating) {
return await Migrate.run(config);
} else {
config.logger.log("Network up to date.");
}
}
};
/***/ }),
/***/ 43687:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
const { Environment } = __webpack_require__(76765);
const Artifactor = __webpack_require__(29463);
const { Resolver } = __webpack_require__(48511);
const fse = __webpack_require__(55674);
const tmp = __webpack_require__(36276);
tmp.setGracefulCleanup();
const runMigrations = __webpack_require__(96146);
module.exports = async function (config) {
await Environment.fork(config, {
logging: {
quiet: true
},
// we need to tell Ganache to not unlock any accounts so that only
// user's accounts are unlocked since this will be a dry run
wallet: {
totalAccounts: 0
}
});
// Copy artifacts to a temporary directory
const temporaryDirectory = tmp.dirSync({
unsafeCleanup: true,
prefix: "migrate-dry-run-"
}).name;
fse.copySync(config.contracts_build_directory, temporaryDirectory);
config.contracts_build_directory = temporaryDirectory;
// Note: Create a new artifactor and resolver with the updated config.
// This is because the contracts_build_directory changed.
// Ideally we could architect them to be reactive of the config changes.
config.artifactor = new Artifactor(temporaryDirectory);
config.resolver = new Resolver(config);
return await runMigrations(config);
};
/***/ }),
/***/ 86927:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
const { IPC } = __webpack_require__(39813);
const path = __webpack_require__(71017);
const { spawn } = __webpack_require__(32081);
const debug = __webpack_require__(15158);
const chalk = __webpack_require__(34061);
const Develop = {
start: async function (ipcNetwork, ganacheOptions = {}) {
let chainPath;
// The path to the dev env process depends on whether or not
// we're running in the bundled version. If not, use chain.js
// directly, otherwise let the bundle point at the bundled version.
if (true) {
// Remember: In the bundled version, __dirname refers to the
// build directory where cli.bundled.js and cli.chain.js live.
chainPath = path.join(__dirname, "chain.bundled.js");
} else {}
const logger = ganacheOptions.logger || console;
//check that genesis-time config option passed through the
//truffle-config.js file is a valid time.
if (ganacheOptions.time && isNaN(Date.parse(ganacheOptions.time))) {
ganacheOptions.time = Date.now();
logger.log(
"\x1b[31m%s\x1b[0m",
"Invalid Date passed to genesis-time, using current Date instead",
"\x1b[0m"
);
}
const stringifiedOptions = JSON.stringify(ganacheOptions);
const optionsBuffer = Buffer.from(stringifiedOptions);
const base64OptionsString = optionsBuffer.toString("base64");
return spawn("node", [chainPath, ipcNetwork, base64OptionsString], {
detached: true,
stdio: "ignore"
});
},
/**
* Connect to an existing Ganache server or start a new one.
* @param {object} options
* @param {object} options.ipcOptions - options for IPC connection
* @param {boolean} options.ipcOptions.log - whether to log IPC messages. Defaults to false.
* @param {string} options.ipcOptions.network - network name. Defaults to "develop".
* @param {boolean} options.ipcOptions.retry - whether to retry connection. Defaults to false.
* @param {string} options.solidityLogDisplayPrefix - prefix to display before solidity log messages. Defaults to "".
* @returns {Promise<(): void>} - IPC disconnection function.
*/
connect: function ({ ipcOptions, solidityLogDisplayPrefix }) {
const debugServer = debug("develop:ipc:server");
const debugClient = debug("develop:ipc:client");
const debugRPC = debug("develop:ganache");
const ganacheColor = {
hex: "#ffaf5f", // ganache's color in hex
xterm: 215 // Xterm's number equivalent
};
debugRPC.color = ganacheColor.xterm;
ipcOptions.retry = ipcOptions.retry || false;
ipcOptions.log = ipcOptions.log || false;
ipcOptions.network = ipcOptions.network || "develop";
solidityLogDisplayPrefix = solidityLogDisplayPrefix || "";
var ipcNetwork = ipcOptions.network;
var ipc = new IPC();
ipc.config.appspace = "truffle.";
// set connectPath explicitly
var dirname = ipc.config.socketRoot;
var basename = `${ipc.config.appspace}${ipcNetwork}`;
var connectPath = path.join(dirname, basename);
var loggers = {};
ipc.config.silent = !debugClient.enabled;
ipc.config.logger = debugClient;
const sanitizeAndCallFn =
fn =>
(...args) => {
// HACK-y: replace `{}` that is getting logged instead of ""
if (
args.length === 1 &&
typeof args[0] === "object" &&
Object.keys(args[0]).length === 0
) {
args[0] = "";
}
fn.apply(undefined, args);
};
if (debugServer.enabled) {
loggers.ipc = debugServer;
}
// create a logger to present Ganache's console log messages
const createSolidityLogger = prefix => {
return maybeMultipleLines =>
maybeMultipleLines.split("\n").forEach(
// decorate each line's prefix.
line => console.log(chalk.hex(ganacheColor.hex)(` ${prefix}`), line)
);
};
// enable output/logger for solidity console.log
loggers.solidity = sanitizeAndCallFn(
createSolidityLogger(solidityLogDisplayPrefix)
);
if (ipcOptions.log) {
debugRPC.enabled = true;
loggers.ganache = sanitizeAndCallFn(debugRPC);
}
if (!ipcOptions.retry) {
ipc.config.maxRetries = 0;
}
var disconnect = function () {
ipc.disconnect(ipcNetwork);
};
return new Promise((resolve, reject) => {
ipc.connectTo(ipcNetwork, connectPath, function () {
ipc.of[ipcNetwork].on("destroy", function () {
reject(new Error("IPC connection destroyed"));
});
ipc.of[ipcNetwork].on("truffle.ready", function () {
resolve(disconnect);
});
Object.keys(loggers).forEach(function (key) {
var log = loggers[key];
if (log) {
var message = `truffle.${key}.log`;
ipc.of[ipcNetwork].on(message, log);
}
});
});
});
},
/**
* Connect to a managed Ganache service. This will connect to an existing
* Ganache service if one exists, or, create a new one to connect to.
*
* @param {Object} ipcOptions - IPC connection options.
* @param {string} ipcOptions.network - the network name.
* @param {Object} ganacheOptions - Ganache options if service is necessary.
* @param {string} solidityLogDisplayPrefix - solidity log messages prefix.
* @returns {Promise<Object>} - object with `disconnect` function and
* `started` boolean. The `disconnect` function is used to disconnect
* from the Ganache service. The `started` boolean is true if a new
* Ganache service was started, false otherwise.
*/
connectOrStart: async function (
ipcOptions,
ganacheOptions,
solidityLogDisplayPrefix = ""
) {
ipcOptions.retry = false;
const ipcNetwork = ipcOptions.network || "develop";
let started = false;
let disconnect;
try {
disconnect = await this.connect({ ipcOptions, solidityLogDisplayPrefix });
} catch (_error) {
await this.start(ipcNetwork, ganacheOptions);
ipcOptions.retry = true;
disconnect = await this.connect({ ipcOptions, solidityLogDisplayPrefix });
started = true;
} finally {
return {
disconnect,
started
};
}
}
};
module.exports = Develop;
/***/ }),
/***/ 53234:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
const Web3 = __webpack_require__(3283);
const { createInterfaceAdapter } = __webpack_require__(36339);
const expect = __webpack_require__(14096);
const TruffleError = __webpack_require__(73321);
const { Resolver } = __webpack_require__(48511);
const Artifactor = __webpack_require__(29463);
const Ganache = __webpack_require__(11651);
const Provider = __webpack_require__(509);
const Environment = {
// It's important config is a Config object and not a vanilla object
detect: async function (config) {
expect.options(config, ["networks"]);
helpers.setUpConfig(config);
helpers.validateNetworkConfig(config);
const interfaceAdapter = createInterfaceAdapter({
provider: config.provider,
networkType: config.network_config.type
});
await Provider.testConnection(config);
await helpers.detectAndSetNetworkId(config, interfaceAdapter);
await helpers.setFromOnConfig(config, interfaceAdapter);
},
// Ensure you call Environment.detect() first.
fork: async function (config, ganacheOptions) {
expect.options(config, ["from", "provider", "networks", "network"]);
const interfaceAdapter = createInterfaceAdapter({
provider: config.provider,
networkType: config.network_config.type
});
let accounts;
try {
accounts = await 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 block = await interfaceAdapter.getBlock("latest");
const upstreamNetwork = config.network;
const upstreamConfig = config.networks[upstreamNetwork];
const forkedNetwork = config.network + "-fork";
ganacheOptions = {
...ganacheOptions,
fork: config.provider,
miner: {
...ganacheOptions.miner,
blockGasLimit: block.gasLimit
}
};
if (accounts.length > 0) ganacheOptions.unlocked_accounts = accounts;
config.networks[forkedNetwork] = {
network_id: config.network_id,
provider: Ganache.provider(ganacheOptions),
from: config.from,
gas: upstreamConfig.gas,
gasPrice: upstreamConfig.gasPrice
};
config.network = forkedNetwork;
},
develop: async (config, ganacheOptions) => {
expect.options(config, ["networks"]);
const network = config.network || "develop";
const url = `http://${ganacheOptions.host}:${ganacheOptions.port}/`;
config.networks[network] = {
...config.networks[network],
network_id: ganacheOptions.network_id,
provider: function () {
return new Web3.providers.HttpProvider(url, { keepAlive: false });
}
};
config.network = network;
return await Environment.detect(config);
}
};
const helpers = {
setFromOnConfig: async (config, interfaceAdapter) => {
if (config.from) return;
try {
const accounts = await interfaceAdapter.getAccounts();
config.networks[config.network].from = accounts[0];
} catch {
// don't prevent Truffle from working if user doesn't provide some way
// to sign transactions (e.g. no reason to disallow debugging)
}
},
detectAndSetNetworkId: async (config, interfaceAdapter) => {
const configNetworkId = config.networks[config.network].network_id;
const providerNetworkId = await interfaceAdapter.getNetworkId();
if (configNetworkId !== "*") {
// Ensure the network id matches the one in the config for safety
if (providerNetworkId.toString() !== configNetworkId.toString()) {
const error =
`The network id specified in the truffle config ` +
`(${configNetworkId}) does not match the one returned by the network ` +
`(${providerNetworkId}). Ensure that both the network and the ` +
`provider are properly configured.`;
throw new Error(error);
}
} else {
// We have a "*" network. Get the current network and replace it with the real one.
// TODO: Should we replace this with the blockchain uri?
config.networks[config.network].network_id = providerNetworkId;
}
},
validateNetworkConfig: config => {
const networkConfig = config.network_config;
if (!networkConfig) {
throw new TruffleError(
`Unknown network "${config.network}` +
`". See your Truffle configuration file for available networks.`
);
}
const configNetworkId = config.network_config.network_id;
if (configNetworkId == null) {
throw new Error(
`You must specify a network_id in your '` +
`${config.network}' configuration in order to use this network.`
);
}
},
setUpConfig: config => {
if (!config.resolver) {
config.resolver = new Resolver(config);
}
if (!config.artifactor) {
config.artifactor = new Artifactor(config.contracts_build_directory);
}
if (!config.network) {
if (config.networks["development"]) {
config.network = "development";
} else {
config.network = "ganache";
config.networks[config.network] = {
host: "127.0.0.1",
port: 7545,
network_id: 5777
};
}
}
const currentNetworkSettings = config.networks[config.network];
if (
currentNetworkSettings &&
currentNetworkSettings.ens &&
currentNetworkSettings.ens.registry
) {
config.ens.registryAddress = currentNetworkSettings.ens.registry.address;
}
}
};
module.exports = Environment;
/***/ }),
/***/ 76765:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
const Environment = __webpack_require__(53234);
const Develop = __webpack_require__(86927);
module.exports = { Environment, Develop };
/***/ }),
/***/ 48511:
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
"use strict";
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.Resolver = void 0;
const resolver_1 = __webpack_require__(43563);
Object.defineProperty(exports, "Resolver", ({ enumerable: true, get: function () { return resolver_1.Resolver; } }));
exports["default"] = resolver_1.Resolver;
//# sourceMappingURL=index.js.map
/***/ }),
/***/ 70972:
/***/ ((module) => {
"use strict";
module.exports = require("@truffle/db-loader");
/***/ }),
/***/ 11651:
/***/ ((module) => {
"use strict";
module.exports = require("ganache");
/***/ }),
/***/ 44516:
/***/ ((module) => {
"use strict";
module.exports = require("original-require");
/***/ }),
/***/ 39491:
/***/ ((module) => {
"use strict";
module.exports = require("assert");
/***/ }),
/***/ 50852:
/***/ ((module) => {
"use strict";
module.exports = require("async_hooks");
/***/ }),
/***/ 14300:
/***/ ((module) => {
"use strict";
module.exports = require("buffer");
/***/ }),
/***/ 32081:
/***/ ((module) => {
"use strict";
module.exports = require("child_process");
/***/ }),
/***/ 22057:
/***/ ((module) => {
"use strict";
module.exports = require("constants");
/***/ }),
/***/ 6113:
/***/ ((module) => {
"use strict";
module.exports = require("crypto");
/***/ }),
/***/ 71891:
/***/ ((module) => {
"use strict";
module.exports = require("dgram");
/***/ }),
/***/ 82361:
/***/ ((module) => {
"use strict";
module.exports = require("events");
/***/ }),
/***/ 57147:
/***/ ((module) => {
"use strict";
module.exports = require("fs");
/***/ }),
/***/ 73292:
/***/ ((module) => {
"use strict";
module.exports = require("fs/promises");
/***/ }),
/***/ 13685:
/***/ ((module) => {
"use strict";
module.exports = require("http");
/***/ }),
/***/ 95687:
/***/ ((module) => {
"use strict";
mod