truffle
Version:
Truffle - Simple development framework for Ethereum
1,803 lines (1,486 loc) • 212 kB
JavaScript
#!/usr/bin/env node
exports.id = 6031;
exports.ids = [6031,7017];
exports.modules = {
/***/ 18967:
/***/ ((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 = 18967;
module.exports = webpackEmptyContext;
/***/ }),
/***/ 3196:
/***/ ((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 = 3196;
module.exports = webpackEmptyContext;
/***/ }),
/***/ 41912:
/***/ ((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 = 41912;
module.exports = webpackEmptyContext;
/***/ }),
/***/ 60627:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
const fse = __webpack_require__(55674);
const del = __webpack_require__(95752);
const WorkflowCompile = (__webpack_require__(37017)["default"]);
const BuildError = __webpack_require__(42863);
const { spawn } = __webpack_require__(32081);
const spawnargs = __webpack_require__(72255);
const _ = __webpack_require__(96486);
const expect = __webpack_require__(14096);
function CommandBuilder(command) {
this.command = command;
}
CommandBuilder.prototype.build = function (options, callback) {
console.log("Running `" + this.command + "`...");
const args = spawnargs(this.command);
const ps = args.shift();
const cmd = spawn(ps, args, {
detached: false,
cwd: options.working_directory,
env: _.merge(process.env, {
WORKING_DIRECTORY: options.working_directory,
BUILD_DESTINATION_DIRECTORY: options.destination_directory,
BUILD_CONTRACTS_DIRECTORY: options.contracts_build_directory
})
});
cmd.stdout.on("data", function (data) {
console.log(data.toString());
});
cmd.stderr.on("data", function (data) {
console.error(data);
});
cmd.on("close", function (code) {
let error = null;
if (code !== 0) {
error = "Command exited with code " + code;
}
callback(error);
});
};
const Build = {
clean: async function (options) {
const destination = options.build_directory;
const contracts_build_directory = options.contracts_build_directory;
// Clean first.
await del([destination + "/*", "!" + contracts_build_directory]);
fse.ensureDirSync(destination);
},
build: async function (options) {
expect.options(options, [
"build_directory",
"working_directory",
"contracts_build_directory",
"networks"
]);
const logger = options.logger || console;
let builder = options.build;
// Duplicate build directory for legacy purposes
options.destination_directory = options.build_directory;
if (builder === null || typeof builder === "undefined") {
logger.log(
"No build configuration found. Preparing to compile contracts."
);
} else if (typeof builder === "string") {
builder = new CommandBuilder(builder);
} else if (typeof builder === "function") {
// If they've only provided a build function, use that.
builder = { build: builder };
} else if (builder.build == null) {
throw new BuildError(
"Build configuration can no longer be specified as an object. Please see our documentation for an updated list of supported build configurations."
);
}
// Use our own clean method unless the builder supplies one.
let clean = this.clean;
if (builder && builder.hasOwnProperty("clean")) {
clean = builder.clean;
}
await clean(options);
// If necessary. This prevents errors due to the .sol.js files not existing.
await WorkflowCompile.compileAndSave(options);
if (builder) {
builder.build(options, function (err) {
if (typeof err === "string") {
throw new BuildError(err);
}
});
}
}
};
module.exports = Build;
/***/ }),
/***/ 23525:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
module.exports = {
run: __webpack_require__(58327),
meta: __webpack_require__(62571)
};
/***/ }),
/***/ 58327:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
module.exports = async function (options) {
const OS = __webpack_require__(22037);
const colors = __webpack_require__(83196);
const deprecationMessage = colors.yellow(
`> The build command is planned ` +
`for deprecation in version 6 of Truffle.${OS.EOL}> See ` +
`https://github.com/trufflesuite/truffle/issues/3226 for more ` +
`information.`
);
console.log(deprecationMessage);
const Config = __webpack_require__(20553);
const Build = __webpack_require__(60627);
const config = Config.detect(options);
return await Build.build(config);
};
/***/ }),
/***/ 51788:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
module.exports = {
run: __webpack_require__(7847),
meta: __webpack_require__(22674)
};
/***/ }),
/***/ 7847:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
module.exports = async function (options) {
const debug = __webpack_require__(15158)("core:commands:call");
const fs = __webpack_require__(57147);
const util = __webpack_require__(73837);
const { Environment } = __webpack_require__(76765);
const OS = __webpack_require__(22037);
const Codec = __webpack_require__(20102);
const Encoder = __webpack_require__(15967);
const Decoder = __webpack_require__(18852);
const TruffleError = __webpack_require__(73321);
const { fetchAndCompile } = __webpack_require__(5523);
const loadConfig = __webpack_require__(932);
const DebugUtils = __webpack_require__(93293);
const web3Utils = __webpack_require__(18269);
if (options.url && options.network) {
const message =
"" +
"Mutually exclusive options, --url and --network detected!" +
OS.EOL +
"Please use either --url or --network and try again." +
OS.EOL +
"See: https://trufflesuite.com/docs/truffle/reference/truffle-commands/#call" +
OS.EOL;
throw new TruffleError(message);
}
let config = loadConfig(options);
await Environment.detect(config);
const [contractNameOrAddress, functionNameOrSignature, ...args] = config._;
let functionEntry, transaction;
const fromAddress =
options.from ??
config.networks[config.network]?.from ??
Codec.Evm.Utils.ZERO_ADDRESS;
if (!web3Utils.isAddress(fromAddress)) {
throw new TruffleError(
`Error: Address ${fromAddress} is not a valid Ethereum address.` +
OS.EOL +
"Please check the address and try again."
);
}
let blockNumber = options.block ?? "latest";
if (!Number.isNaN(Number(blockNumber))) {
blockNumber = Number(blockNumber);
}
if (
!(Number.isSafeInteger(blockNumber) && blockNumber >= 0) &&
!["latest", "pending", "genesis", "earliest"].includes(blockNumber)
) {
throw new TruffleError(
"Error: Invalid block number. Block number must be nonnegative integer or one of 'latest', 'pending', 'genesis', or 'earliest'."
);
}
const { encoder, decoder } = config.fetchExternal
? await sourceFromExternal(contractNameOrAddress, config)
: await sourceFromLocal(contractNameOrAddress, config);
try {
({ abi: functionEntry, tx: transaction } = await encoder.encodeTransaction(
functionNameOrSignature,
args,
{
allowJson: true,
strictBooleans: true
}
));
} catch (error) {
const expectedErrors = [
Encoder.NoFunctionByThatNameError,
Codec.Wrap.NoOverloadsMatchedError,
Codec.Wrap.NoUniqueBestOverloadError,
Codec.Wrap.TypeMismatchError
];
debug("expectedErrors: %O", expectedErrors);
if (expectedErrors.some(errorClass => error instanceof errorClass)) {
//if it was an expected error, turn it into a TruffleError so that it
//displays nicely
throw new TruffleError("Error: " + error.message);
} else {
//unexpected error, rethrow
throw error;
}
}
if (!["pure", "view"].includes(functionEntry.stateMutability)) {
console.log(
"WARNING: Making read-only call to non-view function." +
OS.EOL +
"Any changes this function attempts to make will not be saved to the blockchain."
);
}
const adapter = new Encoder.ProviderAdapter(config.provider);
let result;
let status = undefined;
try {
result = await adapter.call(
fromAddress,
transaction.to,
transaction.data,
blockNumber
);
//note we don't set status to true... a revert need not cause an
//error, depending on client
if (typeof result !== "string") {
//if we couldn't extract a return value, something's gone badly wrong;
//let's just throw
throw new Error("Malformed response from call");
}
} catch (error) {
status = false;
result = extractResult(error);
if (result === undefined) {
//if we couldn't extract a return value, something's gone badly wrong;
//let's just rethrow the error in that case
throw error;
}
}
debug("result: %O", result);
const decodings = await decoder.decodeReturnValue(functionEntry, result, {
status
});
if (decodings.length === 0) {
throw new TruffleError("Error: Could not decode result.");
}
const decoding = decodings[0];
if (decoding.status) {
//successful return
config.logger.log(
util.inspect(new Codec.Export.ReturndataDecodingInspector(decoding), {
colors: true,
depth: null,
maxArrayLength: null,
breakLength: 79
})
);
} else {
//revert case
if (
decoding.kind === "revert" &&
Codec.AbiData.Utils.abiSignature(decoding.abi) === "Panic(uint256)"
) {
// for panics specifically, we'll want a bit more interpretation
// (shouldn't this be a proper interpretation? yes, but there's no
// time to refactor that right now)
const panicCode = decoding.arguments[0].value.value.asBN;
throw new TruffleError(
`The call resulted in a panic: ${DebugUtils.panicString(panicCode)}`
);
}
//usual revert case
throw new TruffleError(
util.inspect(new Codec.Export.ReturndataDecodingInspector(decoding), {
colors: false, //don't want colors in an error message
depth: null,
maxArrayLength: null,
breakLength: 79
})
);
}
return;
//Note: This is the end of the function. After this point is just inner
//function declarations. These declarations are made as inner functions
//so they can use the imports above.
async function sourceFromLocal(contractNameOrAddress, config) {
if (
contractNameOrAddress.startsWith("0x") &&
!web3Utils.isAddress(contractNameOrAddress)
) {
throw new TruffleError(
`Error: Address ${contractNameOrAddress} is not a valid Ethereum address.` +
OS.EOL +
"Please check the address and try again."
);
}
const contractNames = fs
.readdirSync(config.contracts_build_directory)
.filter(filename => filename.endsWith(".json"))
.map(filename => filename.slice(0, -".json".length));
const contracts = contractNames
.map(contractName => ({
[contractName]: config.resolver.require(contractName)
}))
.reduce((a, b) => ({ ...a, ...b }), {});
if (Object.keys(contracts).length === 0) {
throw new TruffleError(
"Error: No artifacts found; please run `truffle compile` first to compile your contracts."
);
}
if (contractNameOrAddress.startsWith("0x")) {
//note in this case we already performed validation above
const contractAddress = contractNameOrAddress;
const projectInfo = {
artifacts: Object.values(contracts)
};
return await getEncoderDecoderForContractAddress(
contractAddress,
projectInfo
);
} else {
// contract name case
const contractName = contractNameOrAddress;
const settings = {
provider: config.provider,
projectInfo: {
artifacts: Object.values(contracts)
}
};
const contract = contracts[contractName];
if (!contract) {
throw new TruffleError(
`Error: No artifacts found for contract named ${contractName} found. Check the name and make sure you have compiled your contracts.`
);
}
let instance;
try {
instance = await contract.deployed();
} catch (error) {
throw new TruffleError(
"Error: This contract has not been deployed to the detected network." +
OS.EOL +
"Please run `truffle migrate` to deploy the contract."
);
}
const encoder = await Encoder.forContractInstance(instance, settings);
const decoder = await Decoder.forContractInstance(instance, settings);
return { encoder, decoder };
}
}
async function sourceFromExternal(contractAddress, config) {
if (!web3Utils.isAddress(contractAddress)) {
throw new TruffleError(
`Error: Address ${contractAddress} is not a valid Ethereum address.` +
OS.EOL +
"Please check the address and try again, or remove `-x` if you are supplying a contract name."
);
}
const { compileResult } = await fetchAndCompile(contractAddress, config);
const projectInfo = {
commonCompilations: compileResult.compilations
};
return await getEncoderDecoderForContractAddress(
contractAddress,
projectInfo
);
}
async function getEncoderDecoderForContractAddress(
contractAddress,
projectInfo
) {
const projectEncoder = await Encoder.forProject({
provider: config.provider,
projectInfo
});
const encoder = await projectEncoder.forAddress(
contractAddress,
blockNumber
);
const projectDecoder = await Decoder.forProject({
provider: config.provider,
projectInfo
});
const decoder = await projectDecoder.forAddress(
contractAddress,
blockNumber
);
return { encoder, decoder };
}
};
function extractResult(error) {
//CODE DUPLICATION WARNING!!
//the following code is copied (w/slight adaptations) from contract/lib/reason.js
//it should really be factored!! but there may not be time to do that right now
if (!error || !error.data) {
return undefined;
}
// NOTE that Ganache >=2 returns the reason string when
// vmErrorsOnRPCResponse === true, which this code could
// be updated to respect (instead of computing here)
const { data } = error;
if (typeof data === "string") {
return data; // geth, Ganache >7.0.0
} else if ("result" in data) {
// there is a single result (Ganache 7.0.0)
return data.result;
} else {
// handle `evm_mine`, `miner_start`, batch payloads, and ganache 2.0
// NOTE this only works for a single failed transaction at a time.
const hash = Object.keys(data)[0];
const errorDetails = data[hash];
return errorDetails.return /* ganache 2.0 */;
}
}
/***/ }),
/***/ 14033:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
module.exports = {
run: __webpack_require__(38666),
meta: __webpack_require__(53051)
};
/***/ }),
/***/ 38666:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
const path = __webpack_require__(71017);
const fse = __webpack_require__(55674);
module.exports = async function (options) {
const TruffleError = __webpack_require__(73321);
const WorkflowCompile = (__webpack_require__(37017)["default"]);
const Config = __webpack_require__(20553);
const config = Config.detect(options);
if (config.list !== undefined) {
return await listVersions(config);
}
if (
options.saveIntermediate === true ||
(typeof options.saveIntermediate === "string" &&
options.saveIntermediate.trim() === "")
) {
// user asked to save the intermediate compilation results
// but didn't provide the file to save the results to
throw new TruffleError(
"You must provide a file to save compilation results to."
);
}
if (config._ && config._.length > 0) {
// set paths based on command-line inputs, transforming to absolute
// paths where appropriate
config.paths = config._.map(specifiedPath => {
// convert relative paths to absolute paths based on whether
// the naive absolute path exists on disk
//
// NOTE in case of collision where the specified path refers to some
// non-FS source (e.g. `truffle/Assert.sol`) and where that specified
// path corresponds to an existing file relative to the working dir.,
// this selects the latter as priority over the former.
const absolutePath = path.resolve(
config.working_directory,
specifiedPath
);
// i.e., pass the absolutePath if it's a real file, otherwise just
// pass whatever was specified.
if (fse.existsSync(absolutePath)) {
return absolutePath;
} else {
return specifiedPath;
}
});
}
const compilationOutput = await WorkflowCompile.compile(config);
if (options.saveIntermediate) {
// Get the filename the user provided to save the compilation results to
const compilationOutputFile = path.resolve(options.saveIntermediate);
await fse.writeFile(
compilationOutputFile,
JSON.stringify(compilationOutput),
{ encoding: "utf8" }
);
}
const result = await WorkflowCompile.save(config, compilationOutput);
if (config.db && config.db.enabled) {
await WorkflowCompile.assignNames(config, result);
}
};
const listVersions = async function (options) {
const { CompilerSupplier } = __webpack_require__(4273);
const { asyncTake } = __webpack_require__(84248);
const supplier = new CompilerSupplier({
solcConfig: {
...options.compilers.solc,
// HACK to force use of the VersionRange or Docker strategy
// as implemented, Docker requires a version to be specified, and so
// we can't simply remove this field entirely.
version: "0.5.16",
docker: options.list === "docker"
},
events: options.events
});
const log = options.logger.log;
options.list = options.list.length ? options.list : "releases";
const { latestRelease, releases, prereleases } = await supplier.list();
if (options.list === "latestRelease") {
log(JSON.stringify(latestRelease, null, " "));
return;
}
const allVersions = options.list === "prereleases" ? prereleases : releases;
const versions = options.all ? allVersions : asyncTake(10, allVersions);
if (options.all && options.list === "docker") {
log(
"Warning: using `--all` with `--list=docker` is very slow and makes " +
"many HTTP requests."
);
log(
"You may instead want to browse tags on the web here: " +
"https://hub.docker.com/r/ethereum/solc/tags/"
);
}
const tags = [];
// use `for await` because Docker strategy returns AsyncIterableIterators
for await (const version of versions) {
tags.push(version);
}
// Docker tags are best browsed via their own web UI
if (options.list === "docker" && !options.all) {
tags.push("See more at: hub.docker.com/r/ethereum/solc/tags/");
}
log(JSON.stringify(tags, null, " "));
return;
};
/***/ }),
/***/ 74445:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
module.exports = {
run: __webpack_require__(83523),
meta: __webpack_require__(24722)
};
/***/ }),
/***/ 83523:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
const analyticsUtils = __webpack_require__(79429);
const userLevelSettings = ["analytics"];
/**
* run config commands to get/set/list Truffle config options
* @param {Object} options
**/
module.exports = async function (options) {
const Config = __webpack_require__(20553);
const OS = __webpack_require__(22037);
const log = options.logger
? options.logger.log || options.logger.debug
: console.log;
let command;
if (options.enableAnalytics || options.disableAnalytics) {
// TODO: Deprecate the --(en|dis)able-analytics flag in favor of `set analytics true`
command = {
set: true,
userLevel: true,
key: "analytics",
value: options.enableAnalytics || false
};
const message =
`> WARNING: The --enable-analytics and ` +
`--disable-analytics flags have been deprecated.${OS.EOL}> Please ` +
`use 'truffle config set analytics <boolean>'.`;
console.warn(OS.EOL + message + OS.EOL);
} else {
command = parse(options._);
}
if (command === null) {
return await analyticsUtils.setUserConfigViaPrompt();
} else if (command.userLevel) {
switch (command.key) {
case "analytics": {
if (command.set) {
analyticsUtils.setAnalytics(command.value);
} else {
log(analyticsUtils.getAnalytics());
}
break;
}
}
return;
} else if (command.list) {
log("Truffle config values");
log(`analytics = ${analyticsUtils.getAnalytics()}`);
} else {
const config = Config.detect(options);
if (command.set) {
log("Setting project-level parameters is not supported yet.");
// TODO: add support for writing project-level settings to the truffle config file
// config[command.key] = command.value;
} else {
log(config[command.key]);
}
return;
}
};
const parse = function (args) {
if (args.length === 0) {
return null;
}
let option = args[0];
if (typeof option !== "string") {
// invalid option
throw new Error(`Invalid config option "${option}"`);
}
option = option.toLowerCase();
let set = false;
let list = false;
let key = args[1];
let value = args[2];
switch (option) {
case "get": {
set = false;
if (typeof key === "undefined" || key === null || key === "") {
// invalid key
throw new Error("Must provide a <key>");
}
break;
}
case "set": {
set = true;
if (typeof key === "undefined" || key === null || key === "") {
// invalid key
throw new Error("Must provide a <key>");
}
if (typeof value !== "string" || value === "") {
// invalid value
throw new Error("Must provide a <value-for-set>");
}
switch (value.toLowerCase()) {
case "null": {
value = null;
break;
}
case "undefined": {
value = undefined;
break;
}
case "true": {
value = true;
break;
}
case "false": {
value = false;
break;
}
default: {
// check if number, otherwise leave as string
const float = parseFloat(value);
if (!isNaN(float) && value === float.toString()) {
value = float;
}
break;
}
}
break;
}
case "list": {
list = true;
break;
}
default: {
if (
option !== "--enable-analytics" &&
option !== "--disable-analytics" &&
option !== ""
) {
// TODO: Deprecate the --(en|dis)able-analytics flag in favor for `enable analytics`
// invalid command!
throw new Error(`Invalid config option "${option}"`);
} else {
// we should not have gotten here
return null;
}
}
}
return {
set,
list,
userLevel: userLevelSettings.includes(key),
key,
value
};
};
/***/ }),
/***/ 79429:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
const Config = __webpack_require__(20553);
const inquirer = __webpack_require__(85346);
const { v4: uuid } = __webpack_require__(76351);
const analyticsInquiry = [
{
type: "list",
name: "analyticsInquiry",
message:
"Would you like to enable analytics for your Truffle projects? Doing so will allow us to make sure Truffle is working as expected and help us address any bugs more efficiently.",
choices: ["Yes, enable analytics", "No, do not enable analytics"]
}
];
const analyticsDisable = [
{
type: "confirm",
name: "analyticsDisable",
message: "Analytics are currently enabled. Would you like to disable them?",
default: false
}
];
const analyticsEnable = [
{
type: "confirm",
name: "analyticsEnable",
message: "Analytics are currently disabled. Would you like to enable them?",
default: false
}
];
module.exports = {
getUserConfig: function () {
return Config.getUserConfig();
},
/**
* set user-level unique id
*/
setUserId: function () {
if (!this.getUserConfig().get("uniqueId")) {
const userId = uuid();
this.getUserConfig().set({ uniqueId: userId });
}
},
/**
* get user-level options for analytics
* @param {Object} userConfig
* @returns {bool}
*/
getAnalytics: function () {
return this.getUserConfig().get("enableAnalytics");
},
/**
* set user-level options for analytics
* @param {bool} analyticsBool
* @param {Object} userConfig
*/
setAnalytics: function (analyticsBool) {
if (analyticsBool === true) {
this.setUserId();
console.log("Analytics enabled");
this.getUserConfig().set({
enableAnalytics: true,
analyticsSet: true,
analyticsMessageDateTime: Date.now()
});
} else if (analyticsBool === false) {
console.log("Analytics disabled");
this.getUserConfig().set({
enableAnalytics: false,
analyticsSet: true,
analyticsMessageDateTime: Date.now()
});
} else {
const message =
`Error setting config option.` +
`\n> You must set the 'analytics' option to either 'true' ` +
`or 'false'. \n> The value you provided was ${analyticsBool}.`;
throw new Error(message);
}
return true;
},
/**
* prompt user to determine values for user-level analytics config options
* @param {Object} userConfig
*/
setUserConfigViaPrompt: async function () {
if (
!this.getUserConfig().get("analyticsSet") &&
process.stdin.isTTY === true
) {
let answer = await inquirer.prompt(analyticsInquiry);
if (answer.analyticsInquiry === analyticsInquiry[0].choices[0]) {
this.setAnalytics(true);
} else {
this.setAnalytics(false);
}
} else if (
this.getUserConfig().get("analyticsSet") &&
this.getUserConfig().get("enableAnalytics") &&
process.stdin.isTTY === true
) {
let answer = await inquirer.prompt(analyticsDisable);
if (answer.analyticsDisable) {
this.setAnalytics(false);
} else {
this.setAnalytics(true);
}
} else if (
this.getUserConfig().get("analyticsSet") &&
!this.getUserConfig().get("enableAnalytics") &&
process.stdin.isTTY === true
) {
let answer = await inquirer.prompt(analyticsEnable);
if (answer.analyticsEnable) {
this.setAnalytics(true);
} else {
this.setAnalytics(false);
}
}
return true;
}
};
/***/ }),
/***/ 89923:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
module.exports = {
run: __webpack_require__(69909),
meta: __webpack_require__(21288)
};
/***/ }),
/***/ 69909:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
module.exports = async function (options) {
const OS = __webpack_require__(22037);
const { Console } = __webpack_require__(68303);
const { Environment } = __webpack_require__(76765);
const TruffleError = __webpack_require__(73321);
const loadConfig = __webpack_require__(932);
if (options.url && options.network) {
const message =
"" +
"Mutually exclusive options, --url and --network detected!" +
OS.EOL +
"Please use either --url or --network and try again." +
OS.EOL +
"See: https://trufflesuite.com/docs/truffle/reference/truffle-commands/#console" +
OS.EOL;
throw new TruffleError(message);
}
let config = loadConfig(options);
await Environment.detect(config);
const c = new Console(config.with({ noAliases: true }));
return await c.start();
};
/***/ }),
/***/ 89664:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
const path = __webpack_require__(71017);
const fse = __webpack_require__(55674);
const templates = {
test: {
filename: path.join(__dirname, "templates", "example.js"),
variable: "example"
},
contract: {
filename: path.join(__dirname, "templates", "Example.sol"),
name: "Example",
license: "MIT",
variable: "example"
},
migration: {
filename: path.join(__dirname, "templates", "migration.js")
}
};
const replaceContents = (filePath, find, replacement) => {
const data = fse.readFileSync(filePath, { encoding: "utf8" });
if (typeof find === "string") {
find = new RegExp(find, "g");
}
const result = data.replace(find, replacement);
fse.writeFileSync(filePath, result, { encoding: "utf8" });
};
const toUnderscoreFromCamel = (string) => {
string = string.replace(/([A-Z])/g, function ($1) {
return "_" + $1.toLowerCase();
});
if (string[0] === "_") {
string = string.substring(1);
}
return string;
};
// getLicense return the license property value from Truffle config first and
// in case that the file doesn't exist it will fallback to package.json
const getLicense = (options) => {
try {
const license = (__webpack_require__(20553).detect)(options).license;
if (license) {
return license;
}
} catch (err) {
console.log(err);
}
try {
return __webpack_require__(76775)(path.join(process.cwd(), "package.json")).license;
} catch {}
};
const Create = {
contract: function (directory, name, options) {
const from = templates.contract.filename;
const to = path.join(directory, name + ".sol");
if (!options.force && fse.existsSync(to)) {
throw new Error("Can not create " + name + ".sol: file exists");
}
fse.copySync(from, to);
replaceContents(to, templates.contract.name, name);
const license = getLicense(options);
if (license) {
replaceContents(to, templates.contract.license, license);
}
},
test: function (directory, name, options) {
let underscored = toUnderscoreFromCamel(name);
underscored = underscored.replace(/\./g, "_");
const from = templates.test.filename;
const to = path.join(directory, underscored + ".js");
if (!options.force && fse.existsSync(to)) {
throw new Error("Can not create " + underscored + ".js: file exists");
}
fse.copySync(from, to);
replaceContents(to, templates.contract.name, name);
replaceContents(to, templates.contract.variable, underscored);
},
migration: function (directory, name, options) {
let underscored = toUnderscoreFromCamel(name || "");
underscored = underscored.replace(/\./g, "_");
const from = templates.migration.filename;
let filename = (new Date().getTime() / 1000) | 0; // Only do seconds.
if (name != null && name !== "") {
filename += "_" + underscored;
}
filename += ".js";
const to = path.join(directory, filename);
if (!options.force && fse.existsSync(to)) {
throw new Error("Can not create " + filename + ": file exists");
}
fse.copySync(from, to);
}
};
module.exports = Create;
/***/ }),
/***/ 42957:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
module.exports = {
run: __webpack_require__(59442),
meta: __webpack_require__(46038)
};
/***/ }),
/***/ 59442:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
module.exports = async function (options) {
const Config = __webpack_require__(20553);
const ConfigurationError = __webpack_require__(48937);
const create = __webpack_require__(89664);
const config = Config.detect(options);
let type = config.type;
if (type == null && config._.length > 0) {
type = config._[0];
}
let name = config.name;
if (name == null && config._.length > 1) {
name = config._[1];
}
if (type == null) {
throw new ConfigurationError(
"Please specify the type of item to create. Example: truffle create contract MyContract"
);
}
if (name == null) {
throw new ConfigurationError(
"Please specify the name of item to create. Example: truffle create contract MyContract"
);
}
if (!/^[a-zA-Z_$][a-zA-Z_$0-9]*$/.test(name)) {
throw new ConfigurationError(
`The name ${name} is invalid. Please enter a valid name using alpha-numeric characters.`
);
}
const fn = create[type];
const destinations = {
contract: config.contracts_directory,
migration: config.migrations_directory,
test: config.test_directory
};
if (type === "all") {
for (const key of Object.keys(destinations)) {
await create[key](destinations[key], name, options);
}
return;
} else if (fn == null) {
throw new ConfigurationError(`Cannot find creation type: ${type}`);
} else {
return create[type](destinations[type], name, options);
}
};
/***/ }),
/***/ 59602:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
module.exports = {
run: __webpack_require__(44556),
meta: __webpack_require__(99608)
};
/***/ }),
/***/ 44556:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
module.exports = async function (options) {
const { detectConfigOrDefault } = __webpack_require__(54708);
const { DashboardServer } = __webpack_require__(97722);
const address = __webpack_require__(94849);
const config = detectConfigOrDefault(options);
const port = options.port || config.dashboard.port;
const host = options.host || config.dashboard.host;
const autoOpen = options.autoOpen ?? config.dashboard.autoOpen;
const verbose = options.verbose || config.dashboard.verbose;
const rpc = true;
const dashboardServerOptions = { port, host, autoOpen, verbose, rpc };
const dashboardServer = new DashboardServer(dashboardServerOptions);
await dashboardServer.start();
if (host === "0.0.0.0") {
// Regex taken from react-scripts to check that the address is a private IP, otherwise we discard it
// https://en.wikipedia.org/wiki/Private_network#Private_IPv4_address_spaces
let lanAddress =
/^10[.]|^172[.](1[6-9]|2[0-9]|3[0-1])[.]|^192[.]168[.]/.test(address.ip())
? address.ip()
: undefined;
console.log(`Truffle Dashboard running at http://localhost:${port}`);
lanAddress &&
console.log(` http://${lanAddress}:${port}`);
console.log(
`DashboardProvider RPC endpoint running at http://localhost:${port}/rpc`
);
lanAddress &&
console.log(
` http://${lanAddress}:${port}/rpc`
);
} else {
console.log(`Truffle Dashboard running at http://${host}:${port}`);
console.log(
`DashboardProvider RPC endpoint running at http://${host}:${port}/rpc`
);
}
// ensure that `await`-ing this method never resolves. (we want to keep
// the console open until it exits on its own)
return new Promise(() => {});
};
/***/ }),
/***/ 49797:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
module.exports = {
run: __webpack_require__(16487),
meta: __webpack_require__(50111)
};
/***/ }),
/***/ 16487:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
const serveCommand = __webpack_require__(43405);
const queryCommand = __webpack_require__(42089);
module.exports = async function (args) {
const [subCommand] = args._;
switch (subCommand) {
case "serve":
await serveCommand.run(args);
break;
case "query":
await queryCommand.run(args);
break;
default:
console.log(`Unknown truffle db command: ${subCommand}`);
}
};
/***/ }),
/***/ 76463:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
module.exports = {
run: __webpack_require__(30999),
meta: __webpack_require__(42285)
};
/***/ }),
/***/ 30999:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
module.exports = async function (options) {
const OS = __webpack_require__(22037);
const { promisify } = __webpack_require__(73837);
const loadConfig = __webpack_require__(932);
const { Environment } = __webpack_require__(76765);
const FromHardhat = __webpack_require__(36052);
const Codec = __webpack_require__(20102);
const TruffleError = __webpack_require__(73321);
const { CLIDebugger } = __webpack_require__(9941);
const { utils: Web3Utils } = __webpack_require__(3283);
if (options.url && options.network) {
const message =
"" +
"Mutually exclusive options, --url and --network detected!" +
OS.EOL +
"Please use either --url or --network and try again." +
OS.EOL +
"See: https://trufflesuite.com/docs/truffle/reference/truffle-commands/#debug" +
OS.EOL;
throw new TruffleError(message);
}
if (options.registry && options.noEns) {
throw new TruffleError(
"The --no-ens options and --registry options are mutually exclusive; please remove one and try again."
);
}
if (options.registry) {
if (!Web3Utils.isAddress(options.registry)) {
throw new TruffleError(
"The specified registry is not a valid address. It may have an incorrect checksum or be otherwise invalid."
);
}
}
let config;
let compilations;
try {
config = loadConfig(options);
} catch (configError) {
// if we can't load config, check to see if this is a hardhat project
try {
await FromHardhat.expectHardhat();
config = await FromHardhat.prepareConfig();
config.merge(options);
compilations = Codec.Compilations.Utils.shimCompilations(
await FromHardhat.prepareCompilations()
);
} catch (hardhatError) {
// if it's not a hardhat project, throw the original error
// otherwise, throw whatever error we got when process hardhat
const error =
hardhatError instanceof FromHardhat.NotHardhatError
? configError
: hardhatError;
throw error;
}
}
await Environment.detect(config);
const txHash = config._[0]; //may be undefined
if (config.fetchExternal && txHash === undefined) {
throw new Error(
"Fetch-external mode requires a specific transaction to debug"
);
}
if (config.compileTests) {
config.compileAll = true;
}
if (config.compileAll && config.compileNone) {
throw new Error("Incompatible options passed regarding what to compile");
}
const interpreter = await new CLIDebugger(config, {
txHash,
compilations
}).run();
return await promisify(interpreter.start.bind(interpreter))();
};
/***/ }),
/***/ 8230:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
module.exports = {
run: __webpack_require__(1527),
meta: __webpack_require__(5561)
};
/***/ }),
/***/ 1527:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
const runMigrate = __webpack_require__(52423);
module.exports = runMigrate;
/***/ }),
/***/ 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);
};
/***/ }),
/***/ 41400:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
module.exports = {
run: __webpack_require__(76306),
meta: __webpack_require__(81483)
};
/***/ }),
/***/ 76306:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
module.exports = async function (options) {
const Config = __webpack_require__(20553);
const WorkflowCompile = (__webpack_require__(37017)["default"]);
const ConfigurationError = __webpack_require__(48937);
const exec = (__webpack_require__(35422).exec);
const { Environment } = __webpack_require__(76765);
const path = __webpack_require__(71017);
const OS = __webpack_require__(22037);
const { promisify } = __webpack_require__(73837);
const config = Config.detect(options);
let file = options.file;
if (file == null && options._.length > 0) {
file = options._[0];
}
if (file == null) {
throw new ConfigurationError(
"Please specify a file, passing the path of the script you'd like the run. Note that all scripts *must* call process.exit() when finished."
);
}
if (path.isAbsolute(file) === false) {
file = path.join(process.cwd(), file);
}
await Environment.detect(config);
if (config.networkHint !== false) {
config.logger.log("Using network '" + config.network + "'." + OS.EOL);
}
// `--compile`
let compilationOutput;
if (options.c || options.compile) {
compilationOutput = await WorkflowCompile.compile(config);
}
// save artifacts if compilation took place
if (compilationOutput) {
await WorkflowCompile.save(config, compilationOutput);
}
return await promisify(exec)(config.with({ file }));
};
/***/ }),
/***/ 63979:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
module.exports = async function (selectedCommand, subCommand, options) {
const commands = __webpack_require__(91559);
const globalCommandOptions = __webpack_require__(67023);
const TruffleError = __webpack_require__(73321);
let commandHelp, commandDescription;
const inputStrings = process.argv.slice(2);
const chosenCommand = commands[selectedCommand].meta;
if (subCommand) {
if (!chosenCommand.subCommands || !chosenCommand.subCommands[subCommand]) {
throw new TruffleError(
`"truffle ${inputStrings.join(" ")}" is an invalid command`
);
}
commandHelp = chosenCommand.subCommands[subCommand].help;
commandDescription = chosenCommand.subCommands[subCommand].description;
} else {
commandHelp = chosenCommand.help;
commandDescription = chosenCommand.description;
}
if (typeof commandHelp === "function") {
commandHelp = await commandHelp(options);
}
const allowedGlobalOptions = commandHelp.allowedGlobalOptions
.filter(tag => tag in globalCommandOptions)
.map(tag => globalCommandOptions[tag]);
const validOptionsUsage = allowedGlobalOptions
.map(({ option }) => `[${option}]`)
.join(" ");
const commandHelpUsage = commandHelp.usage + " " + validOptionsUsage;
console.log(`\n Usage: ${commandHelpUsage}`);
console.log(` Description: ${commandDescription}`);
if (commandHelp.options.length > 0) {
const allValidOptions = [...commandHelp.options, ...allowedGlobalOptions];
console.log(` Options: `);
for (const option of allValidOptions) {
if (option.hidden) {
continue;
}
console.log(` ${option.option}`);
console.log(` ${option.description}`);
}
}
console.log("");
};
/***/ }),
/***/ 9546:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
module.exports = async function (options) {
const displayCommandHelp = __webpack_require__(63979);
const commands = __webpack_require__(91559);
if (options._.length === 0) {
await displayCommandHelp("help", options);
return;
}
const selectedCommand = options._[0];
const subCommand = options._[1];
if (commands[selectedCommand]) {
await displayCommandHelp(selectedCommand, subCommand, options);
return;
} else {
console.log(`\n Cannot find the given command '${selectedCommand}'`);
console.log(" Please ensure your command is one of the following: ");
Object.keys(commands)
.sort()
.forEach(command => console.log(` ${command}`));
console.log("");
return;
}
};
/***/ }),
/***/ 91559:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
module.exports = {
build: __webpack_require__(23525),
call: __webpack_require__(51788),
compile: __webpack_require__(14033),
config: __webpack_require__(74445),
console: __webpack_require__(89923),
create: __webpack_require__(42957),
dashboard: __webpack_require__(59602),
db: __webpack_require__(49797),
debug: __webpack_require__(76463),
deploy: __webpack_require__(8230),
develop: __webpack_require__(55114),
exec: __webpack_require__(41400),
help: __webpack_require__(67340),
init: __webpack_require__(29287),
install: __webpack_require__(70447),
migrate: __webpack_require__(1827),
networks: __webpack_require__(99706),
obtain: __webpack_require__(53017),
opcode: __webpack_require__(48829),
preserve: __webpack_require__(96112),
publish: __webpack_require__(88023),
run: __webpack_require__(90512),
test: __webpack_require__(86067),
unbox: __webpack_require__(72995),
version: __webpack_require__(69037),
watch: __webpack_require__(36563)
};
/***/ }),
/***/ 44062:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
const path = __webpack_require__(71017);
const fse = __webpack_require__(55674);
const { promptOverwrites } = __webpack_require__(69751);
const copyFiles = async (destination, options) => {
fse.ensureDirSync(destination);
const { force, logger, events } = options;
const sourcePath = path.join(__dirname, "initSource");
const projectFiles = fse.readdirSync(sourcePath).filter(
filename => !filename.endsWith(".eslintrc.json") //exclude .eslintrc.json
);
const destinationContents = fse.readdirSync(destination);
const newContents = projectFiles.filter(
filename => !destinationContents.includes(filename)
);
const contentCollisions = projectFiles.filter(filename =>
destinationContents.includes(filename)
);
let shouldCopy;
if (force) {
shouldCopy = projectFiles;
} else {
const overwriteContents = await promptOverwrites(contentCollisions, logger);
shouldCopy = [...newContents, ...overwriteContents];
}
await events.emit("init:copyingProjectFiles", {
destinationPath: destination,
});
for (const file of shouldCopy) {
fse.copySync(path.join(sourcePath, file), path.join(destination, file));
}
};
module.exports = { copyFiles };
/***/ }),
/***/ 29287:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
module.exports = {
run: __webpack_require__(97509),
meta: __webpack_require__(83193)
};
/***/ }),
/***/ 69751:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
const fse = __webpack_require__(55674);
const inquirer = __webpack_require__(85346);
const promptOverwrites = async (contentCollisions, logger = console) => {
const overwriteContents = [];
for (const file of contentCollisions) {
logger.log(`${file} already exists in this directory...`);
c