truffle
Version:
Truffle - Simple development framework for Ethereum
1,766 lines (1,556 loc) • 94.3 kB
JavaScript
#!/usr/bin/env node
exports.id = 4986;
exports.ids = [4986];
exports.modules = {
/***/ 27073:
/***/ ((module) => {
function webpackEmptyContext(req) {
var e = new Error("Cannot find module '" + req + "'");
e.code = 'MODULE_NOT_FOUND';
throw e;
}
webpackEmptyContext.keys = () => ([]);
webpackEmptyContext.resolve = webpackEmptyContext;
webpackEmptyContext.id = 27073;
module.exports = webpackEmptyContext;
/***/ }),
/***/ 34763:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
const { bundled, core } = (__webpack_require__(64146).info)();
const OS = __webpack_require__(22037);
const analytics = __webpack_require__(95614);
const { extractFlags } = __webpack_require__(54708); // contains utility methods
const globalCommandOptions = __webpack_require__(67023);
const debugModule = __webpack_require__(15158);
const debug = debugModule("core:command:run");
const {
validTruffleCommands,
validTruffleConsoleCommands
} = __webpack_require__(91874);
const Web3 = __webpack_require__(3283);
const TruffleError = __webpack_require__(73321);
const defaultHost = "127.0.0.1";
const managedGanacheDefaultPort = 9545;
const managedGanacheDefaultNetworkId = 5777;
const managedDashboardDefaultPort = 24012;
//takes a string and splits it into arguments, shell-style, while
//taking account of quotes and escapes; the escape character can be
//customized (you can also pass in more than one valid escape character)
function parseQuotesAndEscapes(args, escapeCharacters = "\\") {
const quoteCharacters = "\"'"; //note we will handle the two quote types differently
let argArray = [];
let currentArg = "";
let currentQuote = undefined;
let currentEscape = undefined;
let whitespace = true; //are we currently on whitespace? start this as true to allow whitespace at beginning
for (const char of args) {
if (currentEscape !== undefined) {
//escaped character
//note that inside quotes, we don't allow escaping everything;
//outside quotes, we allow escaping anything
if (currentQuote === '"') {
//inside a double-quote case
if (char === currentQuote) {
currentArg += char; //an escaped quote
} else {
//attempted to escape something not the current quote;
//don't treat it as an escape, include the escape char as well
currentArg += currentEscape + char;
}
} else {
//outside a quote case
//(note there's no single-quote case because we can't reach here
//in that case; currentEscape can't get set inside single quotes)
currentArg += char; //just the escaped character
}
currentEscape = undefined;
whitespace = false; //(this is not strictly necessary, but for clarity)
} else if (escapeCharacters.includes(char) && currentQuote !== "'") {
//(unescaped) escape character
//(again, inside single quotes, there is no escaping, so we just treat
//as ordinary character in that case)
currentEscape = char;
whitespace = false;
} else if (currentQuote !== undefined) {
//quoted character (excluding escape/escaped chars)
if (currentQuote === char) {
//closing quote
currentQuote = undefined;
} else {
//ordinary quoted character, including quote of non-matching type
currentArg += char;
}
whitespace = false; //again not necessary, included for clarity
} else if (quoteCharacters.includes(char)) {
//(unescaped) opening quote (closing quotes & quoted quotes handled above)
currentQuote = char;
whitespace = false;
} else if (char.match(/\s/)) {
//(unescaped) whitespace
if (!whitespace) {
//if we're already on whitespace, we don't need
//to do anything, this is just more whitespace.
//if however we're transitioning to whitespace, that means we need
//to split arguments here.
argArray.push(currentArg);
currentArg = "";
whitespace = true;
}
} else {
//default case -- ordinary character
currentArg += char;
whitespace = false;
}
}
//having reached the end of the string, let's check for unterminated quotes & such
if (currentQuote !== undefined) {
throw new TruffleError(`Error: quote with ${currentQuote} not terminated`);
}
if (currentEscape !== undefined) {
throw new TruffleError(
`Error: line ended with escape character ${currentEscape}`
);
}
//now, we push our final argument,
//assuming of course that it's nonempty
if (currentArg !== "") {
argArray.push(currentArg);
}
return argArray;
}
// this function takes an object with an array of input strings, an options
// object, and a boolean determining whether we allow inexact matches for
// command names - it returns an object with the command name, the run method,
// and the command's meta object containing help and command description
const getCommand = ({ inputStrings, options, noAliases }) => {
if (inputStrings.length === 0) {
return null;
}
const firstInputString = inputStrings[0];
let chosenCommand = null;
// If the command wasn't specified directly, go through a process
// for inferring the command.
if (firstInputString === "-v" || firstInputString === "--version") {
chosenCommand = "version";
} else if (validTruffleCommands.includes(firstInputString)) {
chosenCommand = firstInputString;
} else if (noAliases !== true) {
let currentLength = 1;
const availableCommandNames = validTruffleCommands;
// Loop through each letter of the input until we find a command
// that uniquely matches.
while (currentLength <= firstInputString.length) {
// Gather all possible commands that match with the current length
const possibleCommands = availableCommandNames.filter(possibleCommand => {
return (
possibleCommand.substring(0, currentLength) ===
firstInputString.substring(0, currentLength)
);
});
// Did we find only one command that matches? If so, use that one.
if (possibleCommands.length === 1) {
chosenCommand = possibleCommands[0];
// if they miskey a command we need to make sure it is correct so that
// yargs can parse it correctly later
inputStrings.shift();
inputStrings.unshift(chosenCommand);
break;
}
currentLength += 1;
}
}
if (chosenCommand === null) {
return null;
}
// determine whether Truffle is being run from the bundle or from ./cli.js
// and require commands accordingly
let command;
if (true) {
const path = __webpack_require__(71017);
const filePath = path.join(__dirname, `${chosenCommand}.bundled.js`);
// we need to use this library to bypass webpack's require which can't
// access the user's filesystem
const originalRequire = __webpack_require__(44516);
command = originalRequire(filePath);
} else {}
// several commands have a help property that is a function
if (typeof command.meta.help === "function") {
command.meta.help = command.meta.help(options);
}
return {
name: chosenCommand,
run: command.run,
meta: command.meta
};
};
// takes an object containing the command (name, run method, and meta object),
// the array of strings that were input, and an options object - it sanitizes
// the input options, merges it with the input options, and returns the result
const prepareOptions = ({ command, inputStrings, options }) => {
const yargs = __webpack_require__(64968)();
yargs
.command(__webpack_require__(36219)(`./${command.name}/meta`))
//Turn off yargs' default behavior when handling `truffle --version` & `truffle <cmd> --help`
.version(false)
.help(false);
const commandOptions = yargs.parse(inputStrings);
// remove the task name itself put there by yargs
if (commandOptions._) commandOptions._.shift();
// some options might throw if options is a Config object
// if so, let's ignore those values
const clone = {};
Object.keys(options).forEach(key => {
try {
clone[key] = options[key];
} catch {
// do nothing with values that throw
}
});
// method `extractFlags(args)` : Extracts the `--option` & `-option` flags from arguments
let inputOptions = extractFlags(inputStrings);
//prevent invalid option warning for `truffle -v` & `truffle --version`
if (command.name === "version") {
inputOptions = inputOptions.filter(
opt => opt !== "-v" && opt !== "--version"
);
}
// adding allowed global options as enumerated in each command
const allowedGlobalOptions = command.meta.help.allowedGlobalOptions
.filter(tag => tag in globalCommandOptions)
.map(tag => globalCommandOptions[tag]);
const allValidOptions = [
...command.meta.help.options,
...allowedGlobalOptions
];
const validOptions = allValidOptions.reduce((a, item) => {
// we split the options off from the arguments
// and then we split to handle options of the form --<something>|-<s>
let options = item.option.split(" ")[0].split("|");
return [
...a,
...options.filter(
option => option.startsWith("--") || option.startsWith("-")
)
];
}, []);
let invalidOptions = inputOptions.filter(opt => !validOptions.includes(opt));
// TODO: Remove exception for 'truffle run' when plugin options support added.
if (invalidOptions.length > 0 && command.name !== "run") {
if (options.logger) {
const log = options.logger.log || options.logger.debug;
log(
"> Warning: possible unsupported (undocumented in help) command line option(s): " +
invalidOptions
);
}
}
return {
...clone,
...commandOptions
};
};
const runCommand = async function (command, options) {
try {
// migrate Truffle data to the new location if necessary
const configMigration = __webpack_require__(99043);
await configMigration.migrateTruffleDataIfNecessary();
} catch (error) {
debug("Truffle data migration failed: %o", error);
}
analytics.send({
command: command.name ? command.name : "other",
args: options._,
version: bundled || "(unbundled) " + core
});
const unhandledRejections = new Map();
process.on("unhandledRejection", (reason, promise) => {
unhandledRejections.set(promise, reason);
});
process.on("rejectionHandled", promise => {
unhandledRejections.delete(promise);
});
process.on("exit", _ => {
const log = options.logger
? options.logger.log || options.logger.debug
: console.log;
if (unhandledRejections.size) {
log("UnhandledRejections detected");
unhandledRejections.forEach((reason, promise) => {
log(promise, reason);
});
}
});
return await command.run(options);
};
/**
* Display general help for Truffle commands
* @param {Object} options - options object
* @param {Boolean} options.isREPL - whether or not the help is being displayed in a REPL
* @returns {void}
*/
const displayGeneralHelp = options => {
const yargs = __webpack_require__(64968)();
const isREPL = options?.isREPL ?? false; //default to not displaying REPL commands
const commands = isREPL ? validTruffleConsoleCommands : validTruffleCommands;
commands.forEach(command => {
// Exclude "install" and "publish" commands from the generated help list
// because they have been deprecated/removed.
if (command !== "install" && command !== "publish") {
yargs.command(__webpack_require__(36219)(`./${command}/meta`));
}
});
yargs
.scriptName("truffle")
.usage(
"Truffle v" +
(bundled || core) +
" - a development framework for Ethereum" +
OS.EOL +
OS.EOL +
"Usage: truffle <command> [options]"
)
.epilog("See more at https://trufflesuite.com/docs/" +
OS.EOL +
"For Ethereum JSON-RPC documentation see https://ganache.dev")
// showHelp prints using console.error, this won't log in a
// child process - "log" forces it to use console.log instead
.showHelp("log");
};
/**
* This is a function to configure the url from the user specified network settings in the config.
* @param {TruffleConfig} customConfig - Default config with user specified settings.
* @param {boolean} isDashboardNetwork - Check if the network is dashboard or not.
* @returns a string with the configured url
*/
const getConfiguredNetworkUrl = function (customConfig, isDashboardNetwork) {
const defaultPort = isDashboardNetwork
? managedDashboardDefaultPort
: managedGanacheDefaultPort;
const configuredNetworkOptions = {
host: customConfig.host || defaultHost,
port: customConfig.port || defaultPort
};
const urlSuffix = isDashboardNetwork ? "/rpc" : "";
return `http://${configuredNetworkOptions.host}:${configuredNetworkOptions.port}${urlSuffix}`;
};
/**
* This is a function to derive the config environment from the user specified settings.
* @param {TruffleConfig} detectedConfig - Default config with user specified settings.
* @param {string} network - Network name specified with the `--network` option.
* @param {string} url - URL specified with the `--url` option.
* @returns a TruffleConfig object with the user specified settings in the config
*/
const deriveConfigEnvironment = function (detectedConfig, network, url) {
let configuredNetwork;
const configDefinesProvider =
detectedConfig.networks[network] &&
detectedConfig.networks[network].provider;
if (configDefinesProvider) {
// Use "provider" specified in the config to connect to the network
// along with the other network properties
configuredNetwork = {
network_id: "*",
...detectedConfig.networks[network]
};
} else if (url) {
// Use "url" to configure network (implies not "develop" and not "dashboard")
configuredNetwork = {
network_id: "*",
url,
provider: function () {
return new Web3.providers.HttpProvider(url, {
keepAlive: false
});
}
};
} else {
// Otherwise derive network settings
const customConfig = detectedConfig.networks[network] || {};
const isDashboardNetwork = network === "dashboard";
const configuredNetworkUrl = getConfiguredNetworkUrl(
customConfig,
isDashboardNetwork
);
const defaultNetworkId = isDashboardNetwork
? "*"
: managedGanacheDefaultNetworkId;
configuredNetwork = {
network_id: customConfig.network_id || defaultNetworkId,
provider: function () {
return new Web3.providers.HttpProvider(configuredNetworkUrl, {
keepAlive: false
});
},
// customConfig will spread only when it is defined and ignored when undefined
...customConfig
};
}
detectedConfig.networks[network] = {
...configuredNetwork
};
return detectedConfig;
};
module.exports = {
displayGeneralHelp,
parseQuotesAndEscapes,
getCommand,
prepareOptions,
runCommand,
getConfiguredNetworkUrl,
deriveConfigEnvironment
};
/***/ }),
/***/ 62571:
/***/ ((module) => {
module.exports = {
command: "build",
description: "Execute build pipeline (if configuration present)",
builder: {},
help: {
usage: "truffle build",
options: [],
allowedGlobalOptions: []
}
};
/***/ }),
/***/ 22674:
/***/ ((module) => {
module.exports = {
command: "call",
description: "Call read-only contract function with arguments",
builder: {
"url": {
describe: "Connect to a specified provider given via URL",
type: "string"
},
"network": {
describe: "The network name to connect to as specified in the config",
type: "string"
},
"from": {
describe: "The address to perform the call from",
type: "string"
},
"_": {
type: "string"
},
"fetch-external": {
describe: "Fetch referenced verified contracts as needed",
alias: "x",
type: "boolean",
default: false
},
"block-number": {
describe: "Specify the block for the function to be called in.",
alias: "b",
type: "string",
default: "latest"
}
},
help: {
usage:
"truffle call <contract-address>|<contract-name> <function-name>|<function-signature>\n" +
" " + // spacing to align with previous line
"<arg1> ... <argN> [--fetch-external|-x] [--network <network>|--url <provider_url>]\n" +
" " + // spacing to align with previous line
"[--block-number|-b <block_number>]",
options: [
{
option: "<contract-name>",
description: "The name of the contract to be called."
},
{
option: "<contract-address>",
description: "The address of the contract to be called."
},
{
option: "<function-name>",
description: "The name of the function to be called."
},
{
option: "<function-signature>",
description:
"The full function ABI signature (not selector) to be called."
},
{
option: "<arg1> ... <argN>",
description: "List of arguments to be passed to the function."
},
{
option: "--fetch-external|-x",
description:
"Allows Truffle to fetch verified source for the contract being called;\n" +
" note this is useful only when the contract is supplied by address."
},
{
option: "--url",
description:
"Connects to a specified provider given via URL, ignoring networks in config."
},
{
option: "--network",
description:
"The network to connect to, as specified in the Truffle config."
},
{
option: "--block-number|-b",
description: "Specifies the block for the function to be called in."
}
],
allowedGlobalOptions: ["from", "config"]
}
};
/***/ }),
/***/ 91874:
/***/ ((module) => {
const validTruffleCommands = [
"build",
"call",
"compile",
"config",
"console",
"create",
"dashboard",
"db",
"debug",
"deploy",
"develop",
"exec",
"help",
"init",
"install", // removed/deprecated
"migrate",
"networks",
"obtain",
"opcode",
"preserve",
"publish", // removed/deprecated
"run",
"test",
"unbox",
"version",
"watch"
];
//List of truffle commands that are excluded from the console REPLS.
const excludedTruffleConsoleCommands = [
"console",
"dashboard",
"db",
"develop",
"init",
"watch"
];
const validTruffleConsoleCommands = validTruffleCommands.filter(
command => !excludedTruffleConsoleCommands.includes(command)
);
module.exports = {
excludedTruffleConsoleCommands,
validTruffleCommands,
validTruffleConsoleCommands
};
/***/ }),
/***/ 53051:
/***/ ((module) => {
module.exports = {
command: "compile",
description: "Compile contract source files",
builder: {
all: {
type: "boolean",
default: false
},
compiler: {
type: "string",
default: null
},
list: {
type: "string"
},
help: {
type: "boolean",
default: "false"
}
},
help: {
usage:
"truffle compile [<source1> <source2>...] [--list <filter>] [--all] [--quiet]",
options: [
{
option: "--all",
description:
"Compile all contracts instead of only the contracts changed since last compile."
},
{
option: "--list <filter>",
description:
"List all recent stable releases from solc-bin. If filter is specified then it will display only " +
"that\n type of release or docker tags. The filter parameter must be one of the following: " +
"prereleases,\n releases, latestRelease or docker."
},
{
option: "--compiler <compiler-name>",
description:
"Specify a single compiler to use (e.g. `--compiler=solc`). Specify `none` to skip compilation."
},
{
option: "--save-intermediate <output-file>",
hidden: true,
description:
"Save the raw compiler results into <output-file>, overwriting any existing content."
}
],
allowedGlobalOptions: ["config", "quiet"]
}
};
/***/ }),
/***/ 24722:
/***/ ((module) => {
module.exports = {
command: "config",
description: "Set user-level configuration options",
help: {
usage:
"truffle config [--enable-analytics|--disable-analytics] [<list>] [[<get|set> <key>] [<value-for-set>]]",
options: [
{
option: "--enable-analytics",
description: "Enable Truffle to send usage data to Google Analytics."
},
{
option: "--disable-analytics",
description:
"Disable Truffle's ability to send usage data to Google Analytics."
},
{
option: "get",
description: "Get a Truffle config option value."
},
{
option: "set",
description: "Set a Truffle config option value."
},
{
option: "list",
description: "List all Truffle config values."
}
],
allowedGlobalOptions: []
},
builder: {
_: {
type: "string"
}
}
};
/***/ }),
/***/ 21288:
/***/ ((module) => {
module.exports = {
command: "console",
description:
"Run a console with contract abstractions and commands available",
builder: {
url: {
describe: "Use specified URL for provider",
type: "string"
}
},
help: {
usage:
"truffle console [--verbose-rpc] [--require|-r <file>] [--network <network>|--url <provider_url>]",
options: [
{
option: "--url",
description:
"Creates a provider using the given url and connects to the network. This can be used outside of a Truffle project."
},
{
option: "--network",
description:
"The network to connect to, as specified in the Truffle config."
},
{
option: "--verbose-rpc",
description:
"Log communication between Truffle and the Ethereum client."
},
{
option: "--require|-r <file>",
description:
"Preload console environment from required JavaScript " +
"file. The default export must be an object with named keys that " +
"will be used\n to populate the console environment."
},
{
option: "--require-none",
description:
"Do not load any user-defined JavaScript into the " +
"console environment. This option takes precedence over --require, " +
"-r, and\n values provided for console.require " +
"in your project's truffle-config.js."
}
],
// The 'network' option is excluded from here and added manually above as a workaround to combine its usage
// instructions with url to show that they are mutually exclusive.
allowedGlobalOptions: ["config"]
}
};
/***/ }),
/***/ 46038:
/***/ ((module) => {
module.exports = {
command: "create",
description: "Helper to create new contracts, migrations and tests",
builder: {
all: {
type: "boolean",
default: false
},
force: {
type: "boolean",
default: false
}
},
help: {
usage: "truffle create <artifact_type> <ArtifactName>",
options: [
{
option: "<artifact_type>",
description:
"Create a new artifact where artifact_type is one of the following: " +
"contract, migration,\n test or all. The new artifact is created " +
"along with one (or all) of the following\n files: `contracts/ArtifactName.sol`, " +
"`migrations/####_artifact_name.js` or\n `tests/artifact_name.js`. (required)"
},
{
option: "<ArtifactName>",
description: "Name of new artifact. (required)"
}
],
allowedGlobalOptions: []
}
};
/***/ }),
/***/ 99608:
/***/ ((module) => {
module.exports = {
command: "dashboard",
description:
"Start Truffle Dashboard to sign development transactions using browser wallet",
builder: {
"port": {
describe: "Specify the port to start the dashboard and RPC endpoint on",
type: "number"
},
"host": {
describe: "Specify the host to start the dashboard and RPC endpoint on",
type: "string"
},
"no-auto-open": {
describe: "Disable opening dashboard in default browser on start",
type: "boolean"
},
"verbose": {
describe: "Display debug logs for the dashboard server and message bus",
type: "boolean"
}
},
help: {
usage: "truffle dashboard [--port <number>] [--host <string>] [--verbose]",
options: [
{
option: "--port <number>",
description: "Start the dashboard and RPC endpoint on a specific port."
},
{
option: "--host <string>",
description: "Start the dashboard and RPC endpoint on a specific host."
},
{
option: "--no-auto-open",
description: "Disable opening dashboard in default browser on start"
},
{
option: "--verbose",
description:
"Log debug information from the Dashboard server and message bus."
}
],
allowedGlobalOptions: []
}
};
/***/ }),
/***/ 42089:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
module.exports = {
run: __webpack_require__(50823),
meta: __webpack_require__(79062)
};
/***/ }),
/***/ 79062:
/***/ ((module) => {
module.exports = {
command: "query",
description: "Query @truffle/db",
builder: {},
help: {
usage: "truffle db query <query>",
options: [],
allowedGlobalOptions: []
}
};
/***/ }),
/***/ 50823:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
/* This command does starts an express derived server that invokes
* `process.exit()` on SIGINT. As a result there is no need to invoke
* truffle's own `process.exit()` which is triggered by invoking the `done`
* callback.
*
* Todo: blacklist this command for REPLs
*/
module.exports = async function (argv) {
const Config = __webpack_require__(20553);
const { getTruffleDb } = __webpack_require__(70972);
const Db = getTruffleDb();
if (Db === null) {
throw new Error(
"There was a problem importing Truffle Db. Ensure that you have " +
"@truffle/db installed."
);
}
const { connect } = Db;
const config = Config.detect(argv);
const [_, query] = config._;
if (!query) {
throw new Error(
"Query not provided. Please run `truffle db query <query>`"
);
}
const db = connect(config.db);
const result = await db.execute(query, {});
console.log(JSON.stringify(result, null, 2));
};
/***/ }),
/***/ 43405:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
module.exports = {
run: __webpack_require__(12233),
meta: __webpack_require__(11297)
};
/***/ }),
/***/ 11297:
/***/ ((module) => {
module.exports = {
command: "serve",
description: "Start Truffle's GraphQL UI playground",
builder: {},
help: {
usage: "truffle db serve",
options: [],
allowedGlobalOptions: []
}
};
/***/ }),
/***/ 12233:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
/* This command does starts an express derived server that invokes
* `process.exit()` on SIGINT. As a result there is no need to invoke
* truffle's own `process.exit()` which is triggered by invoking the `done`
* callback.
*
* Todo: blacklist this command for REPLs
*/
module.exports = async function (argv) {
const Config = __webpack_require__(20553);
const { getTruffleDb } = __webpack_require__(70972);
const Db = getTruffleDb();
if (Db === null) {
throw new Error(
"There was a problem importing Truffle Db. Ensure that you have " +
"@truffle/db installed."
);
}
const { serve } = Db;
const config = Config.detect(argv);
const port = (config.db && config.db.port) || 4444;
const host = (config.db && config.db.host) || "127.0.0.1";
const { url } = await serve(config.db).listen({ host, port });
console.log(`🚀 Playground listening at ${url}`);
console.log(`ℹ Press Ctrl-C to exit`);
await new Promise(() => {});
};
/***/ }),
/***/ 50111:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
const OS = __webpack_require__(22037);
const serveCommand = __webpack_require__(43405);
const queryCommand = __webpack_require__(42089);
const usage =
"truffle db <sub-command> [options]" +
OS.EOL +
" Available sub-commands: " +
OS.EOL +
" serve \tStart the GraphQL server" +
OS.EOL +
" query \tQuery @truffle/db";
module.exports = {
command: "db",
description: "Database interface commands",
builder: function (yargs) {
return yargs
.command({
...serveCommand.run,
...serveCommand.meta
})
.command({
...queryCommand.run,
...queryCommand.meta
})
.demandCommand();
},
subCommands: {
serve: serveCommand.meta,
query: queryCommand.meta
},
help: {
usage,
options: [],
allowedGlobalOptions: []
}
};
/***/ }),
/***/ 42285:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
const OS = __webpack_require__(22037);
module.exports = {
command: "debug",
description: "Interactively debug any transaction on the blockchain",
builder: {
"url": {
describe: "Use specified URL for provider",
type: "string"
},
"_": {
type: "string"
},
"fetch-external": {
describe: "Allow debugging of external contracts",
alias: "x",
type: "boolean",
default: false
},
"compile-tests": {
describe: "Allow debugging of Solidity test contracts",
type: "boolean",
default: false
},
"compile-all": {
describe: "Force debugger to compile all contracts for extra safety",
type: "boolean",
default: false
},
"compile-none": {
describe: "Force debugger to skip compilation (dangerous!)",
type: "boolean",
default: false
},
"no-ens": {
describe: "Turns off ens reverse resolution",
type: "boolean",
default: false
},
"registry": {
describe: "Allows setting a custom address for the ENS registry",
type: "string"
}
},
help: {
usage:
"truffle debug [<transaction_hash>] [--fetch-external|-x]" +
OS.EOL +
" [--network <network>|--url <provider_url>]" +
OS.EOL +
" [--no-ens|--registry <registry_address>]" +
OS.EOL +
" [--compile-tests|--compile-all|--compile-none]",
options: [
{
option: "<transaction_hash>",
description:
"Transaction ID to use for debugging. Mandatory if --fetch-external is passed."
},
{
option: "--fetch-external|-x",
description:
"Allows debugging of external contracts with verified sources."
},
{
option: "--network",
description:
"The network to connect to, as specified in the Truffle config."
},
{
option: "--url",
description:
"Connects to a specified provider given via URL, ignoring networks in config. This option allows using the debugger outside of a Truffle project."
},
{
option: "--no-ens",
description: "Disables ENS reverse resolution when decoding addresses."
},
{
option: "--registry",
description:
"Allows setting a custom registry for performing reverse ENS resolution, or setting such a registry at all on lesser-known networks."
},
{
option: "--compile-tests",
description:
"Allows debugging of Solidity test contracts from the test directory. Implies --compile-all."
},
{
option: "--compile-all",
description:
"Forces the debugger to recompile all contracts even if it detects that it can use the artifacts."
},
{
option: "--compile-none",
description:
"Forces the debugger to use artifacts even if it detects a problem. Dangerous; may cause errors."
}
],
allowedGlobalOptions: ["config"]
//although network is an allowed global option, it isn't listed here because listing it here would cause
//it to be tacked on to the end of usage, which would prevent us from doing the thing above where we
//combine its usage instructions with url to show that they're mutually exclusive. so as a workaround
//we've excluded network from here, and added it manually above.
}
};
/***/ }),
/***/ 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"]
}
};
/***/ }),
/***/ 14957:
/***/ ((module) => {
module.exports = {
command: "develop",
description: "Open a console with a local development blockchain",
builder: {
log: {
type: "boolean",
default: false
}
},
help: {
usage: "truffle develop [--log] [--require|-r <file>]",
options: [
{
option: `--log`,
description:
`Start/Connect to a Truffle develop session and log all ` +
`rpc activity. You will\n need to open a ` +
`different Truffle develop or console session to interact via the repl.`
},
{
option: "--require|-r <file>",
description:
"Preload console environment from required JavaScript " +
"file. The default export must be an object with named keys that " +
"will be used\n to populate the console environment."
},
{
option: "--require-none",
description:
"Do not load any user-defined JavaScript into the " +
"console environment. This option takes precedence over --require, " +
"-r, and\n values provided for console.require " +
"in your project's truffle-config.js."
}
],
allowedGlobalOptions: ["config"]
}
};
/***/ }),
/***/ 81483:
/***/ ((module) => {
module.exports = {
command: "exec",
description: "Execute a JS module within this Truffle environment",
builder: {
file: {
type: "string"
},
c: {
type: "boolean",
default: false
},
compile: {
type: "boolean",
default: false
}
},
help: {
usage: "truffle exec <script.js> [--compile]",
options: [
{
option: "<script.js>",
description:
"JavaScript file to be executed. Can include path information if the script" +
" does not exist in the current\n directory. (required)"
},
{
option: "--compile",
description: "Compile contracts before executing the script."
}
],
allowedGlobalOptions: ["network", "config"]
}
};
/***/ }),
/***/ 34914:
/***/ ((module) => {
module.exports = {
command: "help",
description:
"List all commands or provide information about a specific command",
help: {
usage: "truffle help [<command> [<subCommand>]]",
options: [
{
option: "<command>",
description: "Name of the command to display information for."
}
],
allowedGlobalOptions: []
},
builder: {}
};
/***/ }),
/***/ 83193:
/***/ ((module) => {
module.exports = {
command: "init",
description: "Initialize new and empty Ethereum project",
builder: {},
help: {
usage: "truffle init [--force]",
options: [
{
option: "--force",
description:
"Initialize project in the current directory regardless of its " +
"state. Be careful, this\n will potentially overwrite files " +
"that exist in the directory."
}
],
allowedGlobalOptions: []
}
};
/***/ }),
/***/ 72545:
/***/ ((module) => {
module.exports = {
command: "install",
description:
"ethpm has moved on faster than truffle's integration. " +
"\n This feature has been broken for some time, so we've disabled it. " +
"\n Please refer to https://github.com/trufflesuite/truffle/discussions/5293",
builder: {},
help: {
usage: "truffle install has been removed.",
options: [],
allowedGlobalOptions: []
}
};
/***/ }),
/***/ 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 t