UNPKG

truffle

Version:

Truffle - Simple development framework for Ethereum

1,448 lines (1,291 loc) 830 kB
#!/usr/bin/env node exports.id = 2478; exports.ids = [2478]; exports.modules = { /***/ 71861: /***/ ((module, __unused_webpack_exports, __webpack_require__) => { const debug = __webpack_require__(15158)("deployer:ens"); const { getEnsAddress, default: ENSJS } = __webpack_require__(26143); const contract = __webpack_require__(78883); const { sha3 } = __webpack_require__(18269); const { hash } = __webpack_require__(59873); class ENS { constructor({ provider, networkId, ens }) { this.networkId = networkId; this.provider = provider; this.devRegistry = null; // we need a reference to the ens field to update it for @truffle/contract this.ens = ens; } determineENSRegistryAddress() { if (this.ens.registryAddress) { return this.ens.registryAddress; } else if (this.ensjs) { return this.ensjs.ens.address; } else { const message = `Truffle could not locate the address of the ENS ` + `registry for the network you are using. You must either be on a` + `known network or a development blockchain.`; throw new Error(message); } } async deployNewDevENSRegistry(from) { const ENSRegistryArtifact = __webpack_require__(56442); const ENSRegistry = contract(ENSRegistryArtifact); ENSRegistry.setProvider(this.provider); const ensRegistry = await ENSRegistry.new({ from }); this.ens.registryAddress = ensRegistry.address; this.devRegistry = ensRegistry; this.setENSJS(); await this.deployNewDevReverseRegistrar(from); return ensRegistry; } //this method should only be called when using a dev registry! //do not call it otherwise! async deployNewDevReverseRegistrar(from) { const registryAddress = this.determineENSRegistryAddress(); debug("from: %s", from); debug("registryAddress: %s", registryAddress); const ReverseRegistrarArtifact = __webpack_require__(85574); const ReverseRegistrar = contract(ReverseRegistrarArtifact); ReverseRegistrar.setProvider(this.provider); //note: the resolver address we're supposed to pass in to the constructor //is supposed to be the "default resolver"; I'm not sure what that means, //but I figure using the resolver for "addr.reverse" ought to suffice, //right? So let's set up a resolver for it. //but in order to set its resolver, we first have to set its owner. await this.setNameOwner({ from, name: "addr.reverse" }); //now we can actually set the resolver const { resolverAddress } = await this.ensureResolverExists({ from, name: "addr.reverse" }); debug("resolver set: %s", resolverAddress); //...but wait! we need it to be owned by the registry (or 0), not by us. //(otherwise the deployment will revert.) so, let's hand over ownership to //the registry. await this.updateNameOwner({ from, newOwner: registryAddress, name: "addr.reverse" }); //now we can do the deployment! const reverseRegistrar = await ReverseRegistrar.new( registryAddress, resolverAddress, { from } ); //except, we're not done... we need to transfer ownership from the registry //to the reverse registrar. //(if there were a previous reverse registrar, this would happen automatically, //but there wasn't, so it doesn't.) await this.updateNameOwner({ from, newOwner: reverseRegistrar.address, name: "addr.reverse" }); //and we're done! } async ensureResolverExists({ from, name }) { // See if the resolver is set, if not then set it const resolverAddress = await this.ensjs.name(name).getResolver(); // names with no set resolver have 0x0 returned if (resolverAddress !== "0x0000000000000000000000000000000000000000") { const resolvedAddress = await this.ensjs.name(name).getAddress("ETH"); return { resolvedAddress, resolverAddress }; } // deploy a resolver if one isn't set const PublicResolverArtifact = __webpack_require__(32927); const PublicResolver = contract(PublicResolverArtifact); PublicResolver.setProvider(this.provider); let registryAddress = this.determineENSRegistryAddress(); const publicResolver = await PublicResolver.new(registryAddress, { from }); await this.ensjs.name(name).setResolver(publicResolver.address, { from }); return { resolvedAddress: null, resolverAddress: publicResolver.address }; } async setAddress(name, addressOrContract, { from }) { this.validateSetAddressInputs({ addressOrContract, name, from }); const address = this.parseAddress(addressOrContract); try { this.setENSJS(); } catch (error) { if (error.message.includes("error instantiating the ENS")) { await this.deployNewDevENSRegistry(from); this.setENSJS(); } } // In the case where there is a registry deployed by the user, // set permissions so that the resolver can be set by the user if (this.devRegistry) await this.setNameOwner({ from, name }); // Find the owner of the name and compare it to the "from" field const nameOwner = await this.ensjs.name(name).getOwner(); if (nameOwner !== from) { const message = `The default address or address provided in the "from" ` + `field for registering does not own the specified ENS name. The ` + `"from" field address must match the owner of the name.` + `\n> Failed to register ENS name ${name}` + `\n> Address in "from" field - ${from}` + `\n> Current owner of '${name}' - ${nameOwner}`; throw new Error(message); } const { resolvedAddress } = await this.ensureResolverExists({ from, name }); // If the resolver points to a different address or is not set, // then set it to the specified address if (resolvedAddress !== address) { await this.ensjs.name(name).setAddress("ETH", address); } } async setNameOwner({ name, from }) { const nameLabels = name.split(".").reverse(); // Set top-level name let builtName = nameLabels[0]; await this.devRegistry.setSubnodeOwner("0x0", sha3(builtName), from, { from }); // If name is only one label, stop here if (nameLabels.length === 1) return; for (const label of nameLabels.slice(1)) { await this.devRegistry.setSubnodeOwner( hash(builtName), sha3(label), from, { from } ); builtName = label.concat(`.${builtName}`); } } //this method assumes that from owns the parent! //it won't work otherwise! async updateNameOwner({ name, from, newOwner }) { //this method does *not* walk the tree. //it only updates this individual entry. let label, suffix; const dotIndex = name.indexOf("."); //find the first dot if (dotIndex !== -1) { label = name.slice(0, dotIndex); //everything before the dot suffix = name.slice(dotIndex + 1); //everything after the dot } else { label = name; suffix = ""; } await this.devRegistry.setSubnodeOwner( suffix !== "" ? hash(suffix) : "0x0", sha3(label), newOwner, { from } ); } parseAddress(addressOrContract) { if (typeof addressOrContract === "string") return addressOrContract; try { return addressOrContract.address; } catch (error) { const message = `You have not entered a valid address or contract ` + `object with an address property. Please ensure that you enter a ` + `valid address or pass in a valid artifact.`; throw new Error(message); } } validateSetAddressInputs({ addressOrContract, name, from }) { if ( !addressOrContract || !name || !from || (typeof addressOrContract !== "string" && typeof addressOrContract !== "object") || typeof name !== "string" || typeof from !== "string" ) { const message = `The 'address', 'name', or 'from' parameter is invalid for ` + `the call to the setAddress function. Please ensure that you are ` + `passing valid values. The received input values were the ` + `following:\n - address: ${addressOrContract}\n - name: ${name}\n - from: ` + `${from}\n`; throw new Error(message); } } setENSJS() { let ensAddress; try { ensAddress = this.ens.registryAddress || getEnsAddress(this.networkId); this.ensjs = new ENSJS({ provider: this.provider, ensAddress }); } catch (error) { const message = `There was an error instantiating the ENS library. ` + `Please ensure you have the correct ENS registry address. Truffle` + `is currently using ${ensAddress}.`; throw new Error(`${message} - ${error.message}`); } } } module.exports = ENS; /***/ }), /***/ 669: /***/ ((module, __unused_webpack_exports, __webpack_require__) => { const expect = __webpack_require__(14096); const DeferredChain = __webpack_require__(17162); const Deployment = __webpack_require__(91432); const link = __webpack_require__(13690); const create = __webpack_require__(63218); const ENS = __webpack_require__(71861); class Deployer extends Deployment { constructor(options) { expect.options(options, ["provider", "networks", "network", "network_id"]); super(options); this.options = options; this.chain = new DeferredChain(); this.network = options.network; this.networks = options.networks; this.network_id = options.network_id; this.provider = options.provider; this.known_contracts = {}; if (options.ens && options.ens.enabled) { //HACK: use getter to get what we want and put it where we want options.ens.registryAddress = options.ensRegistry.address; this.ens = new ENS({ provider: options.provider, networkId: options.network_id, ens: options.ens }); } (options.contracts || []).forEach( contract => (this.known_contracts[contract.contract_name] = contract) ); } // Note: In all code below we overwrite this.chain every time .then() is used // in order to ensure proper error processing. start() { return this.chain.start(); } link(library, destinations) { return this.queueOrExec(link(library, destinations, this)); } deploy() { const args = Array.prototype.slice.call(arguments); const contract = args.shift(); return this.queueOrExec(this.executeDeployment(contract, args, this)); } new() { const args = Array.prototype.slice.call(arguments); const contract = args.shift(); return this.queueOrExec(create(contract, args, this)); } then(fn) { return this.queueOrExec(function () { return fn(this); }); } queueOrExec(fn) { return this.chain.started == true ? new Promise(accept => accept()).then(fn) : this.chain.then(fn); } finish() { this.close(); } } module.exports = Deployer; /***/ }), /***/ 13690: /***/ ((module, __unused_webpack_exports, __webpack_require__) => { var Linker = __webpack_require__(6227); module.exports = function(library, destinations, deployer) { return async function() { await Linker.link(library, destinations, deployer); }; }; /***/ }), /***/ 63218: /***/ ((module) => { module.exports = function (contract, args, deployer) { return async function () { if (deployer.options.events) { await deployer.options.events.emit("deployment:newContract", { contract }); } return contract.new.apply(contract, args); }; }; /***/ }), /***/ 17162: /***/ ((module) => { function DeferredChain() { var self = this; this.chain = new Promise(function (accept, reject) { self._accept = accept; self._reject = reject; }); this.await = new Promise(function () { self._done = arguments[0]; self._error = arguments[1]; }); this.started = false; } DeferredChain.prototype.then = function (fn) { var self = this; this.chain = this.chain.then(function () { var args = Array.prototype.slice.call(arguments); return fn.apply(null, args); }); this.chain = this.chain.catch(function (e) { self._error(e); throw e; }); return this; }; DeferredChain.prototype.catch = function (fn) { this.chain = this.chain.catch(function () { var args = Array.prototype.slice.call(arguments); return fn.apply(null, args); }); return this; }; DeferredChain.prototype.start = function () { this.started = true; this.chain = this.chain.then(this._done); this._accept(); return this.await; }; module.exports = DeferredChain; /***/ }), /***/ 91432: /***/ ((module, __unused_webpack_exports, __webpack_require__) => { const debug = __webpack_require__(15158)("deployer:deployment"); // eslint-disable-line no-unused-vars const sanitizeMessage = __webpack_require__(84331); /** * @class Deployment */ class Deployment { /** * constructor * @param {Number} confirmations confirmations needed to resolve an instance */ constructor(options) { const networkConfig = options.networks[options.network] || {}; this.confirmations = options.confirmations || 0; this.timeoutBlocks = options.timeoutBlocks || 0; this.pollingInterval = networkConfig.deploymentPollingInterval || 4000; this.promiEventEmitters = []; this.confirmationsMap = {}; this.blockPoll; this.options = options; } async emit(name, data) { if (this.options && this.options.events) { return await this.options.events.emit(name, data); } } /** * Helper to parse a deploy statement's overwrite option * @private * @param {Array} args arguments passed to deploy * @param {Boolean} isDeployed is contract deployed? * @return {Boolean} true if overwrite is ok */ _canOverwrite(args, isDeployed) { const lastArg = args[args.length - 1]; const isObject = typeof lastArg === "object"; const overwrite = isObject && isDeployed && lastArg.overwrite === false; return !overwrite; } /** * Gets arbitrary values from constructor params, if they exist. * @private * @param {Array} args constructor params * @return {Any|Undefined} gas value */ _extractFromArgs(args, key) { let value; args.forEach(arg => { const hasKey = !Array.isArray(arg) && typeof arg === "object" && Object.keys(arg).includes(key); if (hasKey) value = arg[key]; }); return value; } /** * Emits a `block` event on each new block heard. This polling is * meant to be cancelled immediately on resolution of the * contract instance or on error. (See stopBlockPolling) * @private * @param {Object} interfaceAdapter */ async _startBlockPolling(interfaceAdapter) { const self = this; const startTime = new Date().getTime(); let secondsWaited = 0; let blocksWaited = 0; let currentBlock = await interfaceAdapter.getBlockNumber(); self.blockPoll = setInterval(async () => { const newBlock = await interfaceAdapter.getBlockNumber(); blocksWaited = newBlock - currentBlock + blocksWaited; currentBlock = newBlock; secondsWaited = Math.floor((new Date().getTime() - startTime) / 1000); const data = { blockNumber: newBlock, blocksWaited: blocksWaited, secondsWaited: secondsWaited }; await self.emit("deployment:block", data); }, self.pollingInterval); } /** * Clears the interval timer initiated by `startBlockPolling * @private */ _stopBlockPolling() { clearInterval(this.blockPoll); } /** * Waits `n` blocks after a tx is mined, firing a pseudo * 'confirmation' event for each one. * @private * @param {Number} blocksToWait * @param {Object} receipt * @param {Object} interfaceAdapter * @return {Promise} Resolves after `blockToWait` blocks */ async _waitBlocks(blocksToWait, state, interfaceAdapter) { const self = this; let currentBlock = await interfaceAdapter.getBlockNumber(); return new Promise(accept => { let blocksHeard = 0; const poll = setInterval(async () => { const newBlock = await interfaceAdapter.getBlockNumber(); if (newBlock > currentBlock) { blocksHeard = newBlock - currentBlock + blocksHeard; currentBlock = newBlock; const data = { contractName: state.contractName, receipt: state.receipt, num: blocksHeard, block: currentBlock }; await self.emit("deployment:confirmation", data); } if (blocksHeard >= blocksToWait) { clearInterval(poll); accept(); } }, self.pollingInterval); }); } /** * Sanity checks catch-all: * Are we connected? * Is contract deployable? * @private * @param {Object} contract TruffleContract * @return {Promise} throws on error */ async _preFlightCheck(contract) { // Check that contract is not array if (Array.isArray(contract)) { const data = { type: "noBatches", contract }; const message = await this.emit("deployment:error", data); throw new Error(sanitizeMessage(message)); } // Check bytecode if (contract.bytecode === "0x") { const data = { type: "noBytecode", contract }; const message = await this.emit("deployment:error", data); throw new Error(sanitizeMessage(message)); } // Check network await contract.detectNetwork(); } // ----------------- Confirmations Handling (temporarily disabled) ------------------------------- /** * There are outstanding issues at both geth (with websockets) & web3 (with confirmation handling @@ -247,27 +221,6 @@ class Deployment { }); } /** * Handler for contract's `confirmation` event. Rebroadcasts as a deployer event * and maintains a table of txHashes & their current confirmation number. This * table gets polled if the user needs to wait a few blocks before getting * an instance back. * @private * @param {Object} parent Deployment instance. Local `this` belongs to promievent * @param {Number} num Confirmation number * @param {Object} receipt transaction receipt */ async _confirmationCb(parent, state, num, receipt) { const eventArgs = { contractName: state.contractName, num: num, receipt: receipt }; parent.confirmationsMap[receipt.transactionHash] = num; await parent.emitter.emit("confirmation", eventArgs); } // ----------------- Confirmations Handling (temporarily disabled) ------------------------------- /** * There are outstanding issues at both geth (with websockets) & web3 (with confirmation handling * over RPC) that impair the confirmations handlers' reliability. In the interim we're using * simple block polling instead. (See also _confirmationCb ) * * Queries the confirmations mapping periodically to see if we have * heard enough confirmations for a given tx to allow `deploy` to complete. * Resolves when this is true. * * @private * @param {String} hash contract creation tx hash * @return {Promise} */ async _waitForConfirmations(hash) { let interval; const self = this; return new Promise(accept => { interval = setInterval(() => { if (self.confirmationsMap[hash] >= self.confirmations) { clearInterval(interval); accept(); } }, self.pollingInterval); }); } // ------------------------------------ Methods -------------------------------------------------- /** * * @param {Object} contract Contract abstraction * @param {Array} args Constructor arguments * @return {Promise} Resolves an instance */ executeDeployment(contract, args) { const self = this; return async function () { await self._preFlightCheck(contract); let instance; let eventArgs; let shouldDeploy = true; let state = { contractName: contract.contractName }; const isDeployed = contract.isDeployed(); const newArgs = await Promise.all(args); const currentBlock = await contract.interfaceAdapter.getBlock("latest"); // Last arg can be an object that tells us not to overwrite. if (newArgs.length > 0) { shouldDeploy = self._canOverwrite(newArgs, isDeployed); } // Case: deploy: if (shouldDeploy) { /* Set timeout override. If this value is zero, @truffle/contract will defer to web3's defaults: - 50 blocks (websockets) OR 50 * 15sec (http) */ contract.timeoutBlocks = self.timeoutBlocks; eventArgs = { state: state, contract: contract, deployed: isDeployed, blockLimit: currentBlock.gasLimit, gas: self._extractFromArgs(newArgs, "gas") || contract.defaults().gas, gasPrice: self._extractFromArgs(newArgs, "gasPrice") || contract.defaults().gasPrice, from: self._extractFromArgs(newArgs, "from") || contract.defaults().from }; // Get an estimate for previews / detect constructor revert // NB: web3 does not strip the revert msg here like it does for `deploy` try { eventArgs.estimate = await contract.new.estimateGas.apply( contract, newArgs ); } catch (err) { eventArgs.estimateError = err; } // Emit `deployment:start` & send transaction await self.emit("deployment:start", eventArgs); const promiEvent = contract.new.apply(contract, newArgs); // Track emitters for cleanup on exit self.promiEventEmitters.push(promiEvent); // Subscribe to contract events / rebroadcast them to any reporters promiEvent .on("transactionHash", async hash => { const data = { contractName: state.contractName, transactionHash: hash }; await self.emit("deployment:txHash", data); }) .on("receipt", receipt => { // We want this receipt available for the post-deploy event // so gas reporting is at hand there. state.receipt = receipt; }); await self._startBlockPolling(contract.interfaceAdapter); // Get instance (or error) try { instance = await promiEvent; self._stopBlockPolling(); } catch (err) { self._stopBlockPolling(); eventArgs.error = err.error || err; const message = await self.emit("deployment:failed", eventArgs); self.close(); throw new Error(sanitizeMessage(message)); } // Case: already deployed } else { instance = await contract.deployed(); } // Emit `postDeploy` eventArgs = { contract: contract, instance: instance, deployed: shouldDeploy, receipt: state.receipt }; await self.emit("deployment:succeed", eventArgs); // Wait for `n` blocks if (self.confirmations !== 0 && shouldDeploy) { await self._waitBlocks( self.confirmations, state, contract.interfaceAdapter ); } // Finish: Ensure the address and tx-hash are set on the contract. contract.address = instance.address; contract.transactionHash = instance.transactionHash; return instance; }; } /** * Cleans up promiEvents' emitter listeners */ close() { this.promiEventEmitters.forEach(item => { item.removeAllListeners(); }); } } module.exports = Deployment; /***/ }), /***/ 6227: /***/ ((module, __unused_webpack_exports, __webpack_require__) => { const sanitizeMessage = __webpack_require__(84331); module.exports = { link: async function (library, destinations, deployer) { let eventArgs; let libraryName = library.contractName; if (libraryName == null && library.constructor) { //allow for the possibility that library is an instance rather //than a class libraryName = library.constructor.contractName; } // Validate name (it might still be undefined) if (libraryName == null) { eventArgs = { type: "noLibName" }; let message; if (deployer.options && deployer.options.events) { message = await deployer.options.events.emit( "deployment:error", eventArgs ); } throw new Error(sanitizeMessage(message)); } // Validate address: don't want to use .address directly because it will throw. let hasAddress; typeof library.isDeployed === "function" ? (hasAddress = library.isDeployed()) : (hasAddress = library.address != null); if (!hasAddress) { eventArgs = { type: "noLibAddress", contract: library }; let message; if (deployer.options && deployer.options.events) { message = await deployer.options.events.emit( "deployment:error", eventArgs ); } throw new Error(sanitizeMessage(message)); } // Link all destinations if (!Array.isArray(destinations)) { destinations = [destinations]; } for (let destination of destinations) { // Don't link if result will have no effect. const alreadyLinked = destination.links[libraryName] === library.address; const noLinkage = !destination.unlinked_binary.includes(libraryName); if (alreadyLinked || noLinkage) continue; eventArgs = { libraryName, libraryAddress: library.address, contractName: destination.contractName, contractAddress: destination.contractAddress }; if (deployer.options && deployer.options.events) { await deployer.options.events.emit("deployment:linking", eventArgs); } destination.link(library); } } }; /***/ }), /***/ 84331: /***/ ((module, __unused_webpack_exports, __webpack_require__) => { const debug = __webpack_require__(15158)("deployer:sanitizeMessage"); module.exports = message => { if (Array.isArray(message)) { // for some reason, message is returned as an array padded with many // empty arrays - should investigate this further later debug("processing the following message - %o", message); return message[0]; } return message; }; /***/ }), /***/ 83474: /***/ (function(__unused_webpack_module, exports, __webpack_require__) { "use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.Migration = void 0; const path = __importStar(__webpack_require__(71017)); const deployer_1 = __importDefault(__webpack_require__(669)); const Require = __importStar(__webpack_require__(35422)); const interface_adapter_1 = __webpack_require__(36339); const ResolverIntercept_1 = __webpack_require__(40960); const db_loader_1 = __webpack_require__(70972); const emitEvent_1 = __webpack_require__(92931); class Migration { constructor(file, config) { this.file = path.resolve(file); this.number = parseInt(path.basename(file)); this.isFirst = false; this.isLast = false; this.dryRun = config.dryRun; this.interactive = config.interactive; this.config = config; } // ------------------------------------- Private ------------------------------------------------- /** * Loads & validates migration, then runs it. * @param {Object} options config and command-line * @param {Object} context web3 & interfaceAdapter * @param {Object} deployer truffle module * @param {Object} resolver truffle module */ _load(options, context, deployer, resolver) { return __awaiter(this, void 0, void 0, function* () { // Load assets and run `execute` const accounts = yield context.interfaceAdapter.getAccounts(); const requireOptions = { file: this.file, context: context, resolver: resolver, args: [deployer] }; // in the above options, resolver is actually an instance of // ResolverIntercept - adding that type to @truffle/require causes a // circular dependency - for now we'll just do a ts-ignore // @ts-ignore const fn = Require.file(requireOptions); const unRunnable = !fn || !fn.length || fn.length == 0; if (unRunnable) { const msg = `Migration ${this.file} invalid or does not take any parameters`; throw new Error(msg); } // `migrateFn` might be sync or async. We negotiate that difference in // `execute` through the deployer API. const migrateFn = fn(deployer, options.network, accounts); yield this._deploy(options, context, deployer, resolver, migrateFn); }); } /** * Initiates deployer sequence, then manages migrations info * publication to chain / artifact saving. * @param {Object} options config and command-line * @param {Object} context web3 & interfaceAdapter * @param {Object} deployer truffle module * @param {Object} resolver truffle module * @param {[type]} migrateFn module.exports of a migrations.js */ _deploy(options, context, deployer, resolver, migrateFn) { return __awaiter(this, void 0, void 0, function* () { try { yield deployer.start(); // Allow migrations method to be async and // deploy to use await if (migrateFn && migrateFn.then !== undefined) { // @ts-ignore yield deployer.then(() => migrateFn); } // Migrate without saving if (options.save === false) return; let Migrations; // Attempt to write migrations record to chain try { Migrations = resolver.require("Migrations"); } catch (error) { // do nothing, Migrations contract optional } if (Migrations && Migrations.isDeployed()) { const message = `Saving migration to chain.`; if (!this.dryRun) { const data = { message: message }; yield (0, emitEvent_1.emitEvent)(options, "migrate:settingCompletedMigrations:start", data); } const migrations = yield Migrations.deployed(); const receipt = yield migrations.setCompleted(this.number); if (!this.dryRun) { const data = { receipt: receipt, message: message }; yield (0, emitEvent_1.emitEvent)(options, "migrate:settingCompletedMigrations:succeed", data); } } const eventArgs = { isLast: this.isLast, interfaceAdapter: context.interfaceAdapter }; yield (0, emitEvent_1.emitEvent)(options, "migrate:migration:succeed", eventArgs); let artifacts = resolver .contracts() .map((abstraction) => abstraction._json); if (this.config.db && this.config.db.enabled && artifacts.length > 0) { // currently if Truffle Db fails to load, getTruffleDb returns `null` const Db = (0, db_loader_1.getTruffleDb)(); if (Db) { const db = Db.connect(this.config.db); const project = yield Db.Project.initialize({ db, project: { directory: this.config.working_directory } }); const result = yield project .connect({ provider: this.config.provider }) .loadMigrate({ network: { name: this.config.network }, artifacts }); ({ artifacts } = result); yield project.assignNames({ assignments: { networks: [result.network] } }); } } // Save artifacts to local filesystem yield options.artifactor.saveAll(artifacts); deployer.finish(); // Cleanup if (this.isLast) { // Exiting w provider-engine appears to be hopeless. This hack on // our fork just swallows errors from eth-block-tracking // as we unwind the handlers downstream from here. if (this.config.provider && this.config.provider.engine) { this.config.provider.engine.silent = true; } } } catch (error) { const errorData = { type: "migrateErr", error: error }; yield (0, emitEvent_1.emitEvent)(options, "migrate:migration:error", errorData); deployer.finish(); throw error; } }); } // ------------------------------------- Public ------------------------------------------------- /** * Instantiates a deployer, connects this migration and its deployer to the reporter * and launches a migration file's deployment sequence * @param {Object} options config and command-line */ run(options) { return __awaiter(this, void 0, void 0, function* () { const { interfaceAdapter, resolver, context, deployer } = this.prepareForMigrations(options); // Get file path and emit pre-migration event const file = path.relative(options.migrations_directory, this.file); const block = yield interfaceAdapter.getBlock("latest"); const preMigrationsData = { file: file, number: this.number, isFirst: this.isFirst, network: options.network, networkId: options.network_id, blockLimit: block.gasLimit }; yield (0, emitEvent_1.emitEvent)(options, "migrate:migration:start", preMigrationsData); yield this._load(options, context, deployer, resolver); }); } prepareForMigrations(options) { const interfaceAdapter = (0, interface_adapter_1.createInterfaceAdapter)({ provider: options.provider, networkType: options.networks[options.network].type }); const web3 = new interface_adapter_1.Web3Shim({ provider: options.provider, networkType: options.networks[options.network].type }); const resolver = new ResolverIntercept_1.ResolverIntercept(options.resolver); // Initial context. const context = { web3, interfaceAdapter, config: this.config }; const deployer = new deployer_1.default(options); return { interfaceAdapter, resolver, context, deployer }; } serializeable() { return { file: this.file, number: this.number, isFirst: this.isFirst, isLast: this.isLast, dryRun: this.dryRun, interactive: this.interactive }; } } exports.Migration = Migration; //# sourceMappingURL=Migration.js.map /***/ }), /***/ 40960: /***/ ((__unused_webpack_module, exports) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.ResolverIntercept = void 0; class ResolverIntercept { constructor(resolver) { this.resolver = resolver; this.cache = []; } require(contractName) { // remove file extension if present on name const sanitizedContractName = contractName .replace(/^\.\//, "") .replace(/\.sol$/i, ""); // there may be more than one contract of the same name which will be // problematic - only return the first one found in the cache for now for (const contract of this.cache) { // @ts-ignore if (contract.contract_name === sanitizedContractName) { return contract; } } // Note, will error if nothing is found. const resolved = this.resolver.require(sanitizedContractName); this.cache.push(resolved); return resolved; } contracts() { return this.cache; } } exports.ResolverIntercept = ResolverIntercept; //# sourceMappingURL=ResolverIntercept.js.map /***/ }), /***/ 92931: /***/ (function(__unused_webpack_module, exports) { "use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.emitEvent = void 0; const emitEvent = (options, name, data) => __awaiter(void 0, void 0, void 0, function* () { if (options.events) { return yield options.events.emit(name, data); } }); exports.emitEvent = emitEvent; //# sourceMappingURL=emitEvent.js.map /***/ }), /***/ 22478: /***/ (function(__unused_webpack_module, exports, __webpack_require__) { "use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.ResolverIntercept = void 0; const fs_1 = __importDefault(__webpack_require__(57147)); const path = __importStar(__webpack_require__(71017)); const glob_1 = __importDefault(__webpack_require__(12884)); const expect = __importStar(__webpack_require__(14096)); const config_1 = __importDefault(__webpack_require__(20553)); const Migration_1 = __webpack_require__(83474); const emitEvent_1 = __webpack_require__(92931); const inquirer_1 = __importDefault(__webpack_require__(96062)); var ResolverIntercept_1 = __webpack_require__(40960); Object.defineProperty(exports, "ResolverIntercept", ({ enumerable: true, get: function () { return ResolverIntercept_1.ResolverIntercept; } })); /** * This API is consumed by `@truffle/core` at the `migrate` and `test` commands via * the `.runMigrations` method. */ exports["default"] = { Migration: Migration_1.Migration, logger: null, promptToAcceptDryRun: function (options) { return __awaiter(this, void 0, void 0, function* () { const prompt = [ { type: "confirm", name: "proceed", message: `Dry-run successful. Do you want to proceed with real deployment? >> (y/n): `, default: false } ]; const answer = yield inquirer_1.default.prompt(prompt); if (answer.proceed) { return true; } if (options) { yield (0, emitEvent_1.emitEvent)(options, "migrate:dryRun:notAccepted"); } return false; }); }, assemble: function (options) { const config = config_1.default.detect(options); if (!fs_1.default.existsSync(config.migrations_directory) || !(fs_1.default.readdirSync(config.migrations_directory).length > 0)) { return []; } const migrationsDir = config.migrations_directory; const directoryContents = glob_1.default.sync(`${migrationsDir}${path.sep}*`); const files = directoryContents.filter(item => fs_1.default.statSync(item).isFile()); if (files.length === 0) return []; let migrations = files .filter(file => isNaN(parseInt(path.basename(file))) === false) .filter(file => path.extname(file).match(config.migrations_file_extension_regexp) != null) .map(file => new Migration_1.Migration(file, config)); // Make sure to sort the prefixes as numbers and not strings. migrations = migrations.sort((a, b) => { if (a.number > b.number) return 1; if (a.number < b.number) return -1; return 0; }); return migrations; }, run: function (options) { return __awaiter(this, void 0, void 0, function* () { expect.options(options, [ "working_directory", "migrations_directory", "contracts_build_directory", "provider", "artifactor", "resolver", "network", "network_id", "logger", "from" // address doing deployment ]); if (options.reset === true) { yield this.runAll(options); return; } const lastMigration = yield this.lastCompletedMigration(options); // Don't rerun the last completed migration. yield this.runFrom(lastMigration + 1, options); }); }, runFrom: function (number, options) { return __awaiter(this, void 0, void 0, function* () { let migrations = this.assemble(options); while (migrations.length > 0) { if (migrations[0].number >= number) break; migrations.shift(); } if (options.to) { migrations = migrations.filter(migration => migration.number <= options.to); } return yield this.runMigrations(migrations, options); }); }, runAll: function (options) { return __awaiter(this, void 0, void 0, function* () { return yield this.runFrom(0, options); }); }, runMigrations: function (migrations, options) { return __awaiter(this, void 0, void 0, function* () { // Perform a shallow clone of the options object // so that we can override the provider option without // changing the original options object passed in. const clone = {}; Object.keys(options).forEach(key => (clone[key] = options[key])); if (options.quiet) clone.logger = { log: function () { } }; clone.resolver = this.wrapResolver(options.resolver, clone.provider); // Make migrations aware of their position in sequence const total = migrations.length; if (total) { migrations[0].isFirst = true; migrations[total - 1].isLast = true; } yield (0, emitEvent_1.emitEvent)(options, "migrate:runMigrations:start", { migrations, dryRun: options.dryRun }); try { // @ts-ignore global.artifacts = clone.resolver; // @ts-ignore global.config = clone; for (const migration of migrations) { yield migration.run(clone); } yield (0, emitEvent_1.emitEvent)(options, "migrate:runMigrations:finish", { dryRun: options.dryRun, error: null }); return; } catch (error) { yield (0, emitEvent_1.emitEvent)(options, "migrate:runMigrations:finish", { dryRun: options.dryRun, error: error.toString() }); throw error; } finally { // @ts-ignore delete global.artifacts; // @ts-ignore delete global.config; } }); }, wrapResolver: function (resolver, provider) { return { require: function (import_path, search_path) { const abstraction = resolver.require(import_path, search_path); abstraction.setProvider(provider); return abstraction; }, resolve: resolver.resolve }; }, lastCompletedMigration: function (options) { return __awaiter(this, void 0, void 0, function* () { let Migrations; // I don't think we have a good type for this yet try { Migrations = options.resolver.require("Migrations"); } catch (error) { // don't throw, Migrations contract optional return 0; } if (Migrations.isDeployed() === false) return 0; const migrationsOnChain = (migrationsAddress) => __awaiter(this, void 0, void 0, function* () { return ((yield Migrations.interfaceAdapter.getCode(migrationsAddress)) !== "0x"); }); // Two possible Migrations.sol's (lintable/unlintable)