diff --git a/cmd/cmd.js b/cmd/cmd.js index 9c41a5034..b72fd5e36 100644 --- a/cmd/cmd.js +++ b/cmd/cmd.js @@ -3,7 +3,7 @@ const EmbarkController = require('./cmd_controller.js'); const i18n = require('../lib/core/i18n/i18n.js'); const utils = require('../lib/utils/utils.js'); -let embark = new EmbarkController; +let embark = new EmbarkController(); // set PWD to process.cwd() since Windows doesn't have a value for PWD if (!process.env.PWD) { @@ -130,7 +130,7 @@ class Cmd { .command('build [environment]') .option('--contracts', 'only compile contracts into Embark wrappers') .option('--logfile [logfile]', __('filename to output logs (default: none)')) - .option('-c, --client [client]', __('Use a specific ethereum client (supported: %s)', 'geth')) + .option('-c, --client [client]', __('Use a specific ethereum client [%s] (default: %s)', 'geth, parity', 'geth')) .option('--loglevel [loglevel]', __('level of logging to display') + ' ["error", "warn", "info", "debug", "trace"]', /^(error|warn|info|debug|trace)$/i, 'debug') .option('--locale [locale]', __('language to use (default: en)')) .option('--pipeline [pipeline]', __('webpack config to use (default: production)')) @@ -141,7 +141,7 @@ class Cmd { _options.logFile = _options.logfile; // fix casing _options.logLevel = _options.loglevel; // fix casing _options.onlyCompile = _options.contracts; - _options.client = _options.client || 'geth'; + _options.client = _options.client; _options.webpackConfigName = _options.pipeline || 'production'; embark.build(_options); }); @@ -151,7 +151,7 @@ class Cmd { program .command('run [environment]') .option('-p, --port [port]', __('port to run the dev webserver (default: %s)', '8000')) - .option('-c, --client [client]', __('Use a specific ethereum client (supported: %s)', 'geth')) + .option('-c, --client [client]', __('Use a specific ethereum client [%s] (default: %s)', 'geth, parity', 'geth')) .option('-b, --host [host]', __('host to run the dev webserver (default: %s)', 'localhost')) .option('--noserver', __('disable the development webserver')) .option('--nodashboard', __('simple mode, disables the dashboard')) @@ -167,9 +167,9 @@ class Cmd { const nullify = (v) => (!v || typeof v !== 'string') ? null : v; embark.run({ env: env || 'development', - serverPort: nullify(options.port), - serverHost: nullify(options.host), - client: options.client || 'geth', + serverPort: options.port, + serverHost: options.host, + client: options.client, locale: options.locale, runWebserver: options.noserver == null ? null : !options.noserver, useDashboard: !options.nodashboard, @@ -184,7 +184,7 @@ class Cmd { console() { program .command('console [environment]') - .option('-c, --client [client]', __('Use a specific ethereum client (supported: %s)', 'geth')) + .option('-c, --client [client]', __('Use a specific ethereum client [%s] (default: %s)', 'geth, parity', 'geth')) .option('--logfile [logfile]', __('filename to output logs (default: %s)', 'none')) .option('--loglevel [loglevel]', __('level of logging to display') + ' ["error", "warn", "info", "debug", "trace"]', /^(error|warn|info|debug|trace)$/i, 'debug') .option('--locale [locale]', __('language to use (default: en)')) @@ -194,7 +194,7 @@ class Cmd { i18n.setOrDetectLocale(options.locale); embark.console({ env: env || 'development', - client: options.client || 'geth', + client: options.client, locale: options.locale, logFile: options.logfile, logLevel: options.loglevel, @@ -206,7 +206,7 @@ class Cmd { blockchain() { program .command('blockchain [environment]') - .option('-c, --client [client]', __('Use a specific ethereum client (supported: %s)', 'geth')) + .option('-c, --client [client]', __('Use a specific ethereum client [%s] (default: %s)', 'geth, parity', 'geth')) .option('--locale [locale]', __('language to use (default: en)')) .description(__('run blockchain server (default: %s)', 'development')) .action(function(env, options) { @@ -215,7 +215,7 @@ class Cmd { embarkConfig: 'embark.json', interceptLogs: false }); - embark.blockchain(env || 'development', options.client || 'geth'); + embark.blockchain(env || 'development', options.client); }); } @@ -223,7 +223,7 @@ class Cmd { program .command('simulator [environment]') .description(__('run a fast ethereum rpc simulator')) - .option('--testrpc', __('use testrpc as the rpc simulator [%s]', 'default')) + .option('--testrpc', __('use ganache-cli (former "testrpc") as the rpc simulator [%s]', 'default')) .option('-p, --port [port]', __('port to run the rpc simulator (default: %s)', '8545')) .option('-h, --host [host]', __('host to run the rpc simulator (default: %s)', 'localhost')) .option('-a, --accounts [numAccounts]', __('number of accounts (default: %s)', '10')) @@ -288,7 +288,7 @@ class Cmd { .option('--logfile [logfile]', __('filename to output logs (default: %s)', 'none')) .option('--loglevel [loglevel]', __('level of logging to display') + ' ["error", "warn", "info", "debug", "trace"]', /^(error|warn|info|debug|trace)$/i, 'debug') .option('--locale [locale]', __('language to use (default: en)')) - .option('-c, --client [client]', __('Use a specific ethereum client (supported: %s)', 'geth')) + .option('-c, --client [client]', __('Use a specific ethereum client [%s] (default: %s)', 'geth, parity', 'geth')) .option('--pipeline [pipeline]', __('webpack config to use (default: production)')) .description(__('Upload your dapp to a decentralized storage') + '.') .action(function(env, _options) { @@ -301,7 +301,7 @@ class Cmd { _options.ensDomain = _options.ens; _options.logFile = _options.logfile; // fix casing _options.logLevel = _options.loglevel; // fix casing - _options.client = _options.client || 'geth'; + _options.client = _options.client; _options.webpackConfigName = _options.pipeline || 'production'; embark.upload(_options); }); diff --git a/lib/core/config.js b/lib/core/config.js index f999e6641..969f7c1d4 100644 --- a/lib/core/config.js +++ b/lib/core/config.js @@ -120,7 +120,7 @@ Config.prototype._updateBlockchainCors = function(){ } // add whisper cors if(this.communicationConfig && this.communicationConfig.enabled && this.communicationConfig.provider === 'whisper'){ - corsParts.push('embark'); + corsParts.push('http://embark'); } let cors = corsParts.join(','); diff --git a/lib/core/engine.js b/lib/core/engine.js index 7e31a3138..70e67e1f4 100644 --- a/lib/core/engine.js +++ b/lib/core/engine.js @@ -232,6 +232,7 @@ class Engine { web3Service(options) { this.registerModule('blockchain_process', { + client: this.client, locale: this.locale, isDev: this.isDev, ipc: this.ipc diff --git a/lib/modules/blockchain_connector/provider.js b/lib/modules/blockchain_connector/provider.js index 1ccaee1cc..6a01056fc 100644 --- a/lib/modules/blockchain_connector/provider.js +++ b/lib/modules/blockchain_connector/provider.js @@ -19,7 +19,13 @@ class Provider { if (this.type === 'rpc') { self.provider = new this.web3.providers.HttpProvider(self.web3Endpoint); } else if (this.type === 'ws') { - self.provider = new this.web3.providers.WebsocketProvider(self.web3Endpoint, {headers: {Origin: "embark"}}); + // Note: don't pass to the provider things like {headers: {Origin: "embark"}}. Origin header is for browser to fill + // to protect user, it has no meaning if it is used server-side. See here for more details: https://github.com/ethereum/go-ethereum/issues/16608 + // Moreover, Parity reject origins that are not urls so if you try to connect with Origin: "embark" it gives the followin error: + // << Blocked connection to WebSockets server from untrusted origin: Some("embark") >> + // The best choice is to use void origin, BUT Geth rejects void origin, so to keep both clients happy we can use http://embark + self.provider = new this.web3.providers.WebsocketProvider(self.web3Endpoint, {headers: {Origin: "http://embark"}}); + self.provider.on('error', e => self.logger.error('Websocket Error', e)); self.provider.on('end', e => self.logger.error('Websocket connection ended', e)); } else { diff --git a/lib/modules/blockchain_process/blockchain.js b/lib/modules/blockchain_process/blockchain.js index 97b68aae7..d74f8ff69 100644 --- a/lib/modules/blockchain_process/blockchain.js +++ b/lib/modules/blockchain_process/blockchain.js @@ -1,65 +1,65 @@ const async = require('async'); -const child_process = require('child_process'); +const {spawn, exec} = require('child_process'); const fs = require('../../core/fs.js'); const constants = require('../../constants.json'); const utils = require('../../utils/utils.js'); -const GethCommands = require('./geth_commands.js'); +const GethClient = require('./gethClient.js'); +const ParityClient = require('./parityClient.js'); const DevFunds = require('./dev_funds.js'); +const proxy = require('./proxy'); +const Ipc = require('../../core/ipc'); + const {defaultHost, dockerHostSwap} = require('../../utils/host'); -/*eslint complexity: ["error", 37]*/ -var Blockchain = function(options) { - this.blockchainConfig = options.blockchainConfig; - this.env = options.env || 'development'; - this.client = options.client; - this.isDev = options.isDev; - this.onReadyCallback = options.onReadyCallback || (() => {}); - this.onExitCallback = options.onExitCallback; +/*eslint complexity: ["error", 36]*/ +var Blockchain = function(userConfig, clientClass) { + this.userConfig = userConfig; + this.env = userConfig.env || 'development'; + this.isDev = userConfig.isDev; + this.onReadyCallback = userConfig.onReadyCallback || (() => {}); + this.onExitCallback = userConfig.onExitCallback; this.proxyIpc = null; - if ((this.blockchainConfig === {} || JSON.stringify(this.blockchainConfig) === '{"enabled":true}') && this.env !== 'development') { - console.log("===> " + __("warning: running default config on a non-development environment")); - } - - let defaultWsApi = ['eth', 'web3', 'net', 'shh', 'debug', 'pubsub']; - if (this.isDev) { - defaultWsApi.push('personal'); - } + let defaultWsApi = clientClass.DEFAULTS.WS_API; + if (this.isDev) defaultWsApi = clientClass.DEFAULTS.DEV_WS_API; this.config = { - geth_bin: this.blockchainConfig.geth_bin || 'geth', - networkType: this.blockchainConfig.networkType || 'custom', - genesisBlock: this.blockchainConfig.genesisBlock || false, - datadir: this.blockchainConfig.datadir || false, - mineWhenNeeded: this.blockchainConfig.mineWhenNeeded || false, - rpcHost: dockerHostSwap(this.blockchainConfig.rpcHost) || defaultHost, - rpcPort: this.blockchainConfig.rpcPort || 8545, - rpcCorsDomain: this.blockchainConfig.rpcCorsDomain || false, - networkId: this.blockchainConfig.networkId || 1337, - port: this.blockchainConfig.port || 30303, - nodiscover: this.blockchainConfig.nodiscover || false, - mine: this.blockchainConfig.mine || false, - account: this.blockchainConfig.account || {}, - whisper: (this.blockchainConfig.whisper === undefined) || this.blockchainConfig.whisper, - maxpeers: ((this.blockchainConfig.maxpeers === 0) ? 0 : (this.blockchainConfig.maxpeers || 25)), - bootnodes: this.blockchainConfig.bootnodes || "", - rpcApi: (this.blockchainConfig.rpcApi || ['eth', 'web3', 'net', 'debug']), - wsRPC: (this.blockchainConfig.wsRPC === undefined) || this.blockchainConfig.wsRPC, - wsHost: dockerHostSwap(this.blockchainConfig.wsHost) || defaultHost, - wsPort: this.blockchainConfig.wsPort || 8546, - wsOrigins: this.blockchainConfig.wsOrigins || false, - wsApi: (this.blockchainConfig.wsApi || defaultWsApi), - vmdebug: this.blockchainConfig.vmdebug || false, - targetGasLimit: this.blockchainConfig.targetGasLimit || false, - syncMode: this.blockchainConfig.syncMode, - syncmode: this.blockchainConfig.syncmode, - verbosity: this.blockchainConfig.verbosity + silent: this.userConfig.silent, + ethereumClientName: this.userConfig.ethereumClientName, + ethereumClientBin: this.userConfig.ethereumClientBin || this.userConfig.ethereumClientName || 'geth', + networkType: this.userConfig.networkType || clientClass.DEFAULTS.NETWORK_TYPE, + networkId: this.userConfig.networkId || clientClass.DEFAULTS.NETWORK_ID, + genesisBlock: this.userConfig.genesisBlock || false, + datadir: this.userConfig.datadir || false, + mineWhenNeeded: this.userConfig.mineWhenNeeded || false, + rpcHost: dockerHostSwap(this.userConfig.rpcHost) || defaultHost, + rpcPort: this.userConfig.rpcPort || 8545, + rpcCorsDomain: this.userConfig.rpcCorsDomain || false, + rpcApi: this.userConfig.rpcApi || clientClass.DEFAULTS.RPC_API, + port: this.userConfig.port || 30303, + nodiscover: this.userConfig.nodiscover || false, + mine: this.userConfig.mine || false, + account: this.userConfig.account || {}, + devPassword: this.userConfig.devPassword || "", + whisper: (this.userConfig.whisper != false), + maxpeers: ((this.userConfig.maxpeers === 0) ? 0 : (this.userConfig.maxpeers || 25)), + bootnodes: this.userConfig.bootnodes || "", + wsRPC: (this.userConfig.wsRPC != false), + wsHost: dockerHostSwap(this.userConfig.wsHost) || defaultHost, + wsPort: this.userConfig.wsPort || 8546, + wsOrigins: this.userConfig.wsOrigins || false, + wsApi: this.userConfig.wsApi || defaultWsApi, + vmdebug: this.userConfig.vmdebug || false, + targetGasLimit: this.userConfig.targetGasLimit || false, + syncMode: this.userConfig.syncMode || this.userConfig.syncmode, + verbosity: this.userConfig.verbosity, + proxy: this.userConfig.proxy || true }; - if (this.blockchainConfig === {} || this.blockchainConfig.default) { + if (this.userConfig === {} || this.userConfig.default || JSON.stringify(this.userConfig) === '{"enabled":true}') { this.config.account = {}; if (this.env === 'development') { this.isDev = true; @@ -87,35 +87,25 @@ var Blockchain = function(options) { process.exit(); } this.initProxy(); - this.client = new options.client({config: this.config, env: this.env, isDev: this.isDev}); + this.client = new clientClass({config: this.config, env: this.env, isDev: this.isDev}); }; Blockchain.prototype.initProxy = function() { - this.config.proxy = true; - if (this.blockchainConfig.proxy === false) { - this.config.proxy = false; - return; + if (this.config.proxy) { + this.config.rpcPort += constants.blockchain.servicePortOnProxy; + this.config.wsPort += constants.blockchain.servicePortOnProxy; } - - this.config.rpcPort += constants.blockchain.servicePortOnProxy; - this.config.wsPort += constants.blockchain.servicePortOnProxy; }; Blockchain.prototype.setupProxy = async function() { - const proxy = require('./proxy'); - const Ipc = require('../../core/ipc'); + if (!this.proxyIpc) this.proxyIpc = new Ipc({ipcRole: 'client'}); - if(!this.proxyIpc) this.proxyIpc = new Ipc({ipcRole: 'client'}); - let wsProxy; - if(this.config.wsRPC) { + if (this.config.wsRPC) { wsProxy = proxy.serve(this.proxyIpc, this.config.wsHost, this.config.wsPort, true, this.config.wsOrigins); } - - [this.rpcProxy, this.wsProxy] = await Promise.all([ - proxy.serve(this.proxyIpc, this.config.rpcHost, this.config.rpcPort, false), - wsProxy - ]); + + [this.rpcProxy, this.wsProxy] = await Promise.all([proxy.serve(this.proxyIpc, this.config.rpcHost, this.config.rpcPort, false), wsProxy]); }; Blockchain.prototype.shutdownProxy = function() { @@ -123,52 +113,55 @@ Blockchain.prototype.shutdownProxy = function() { return; } - if(this.rpcProxy) this.rpcProxy.close(); - if(this.wsProxy) this.wsProxy.close(); + if (this.rpcProxy) this.rpcProxy.close(); + if (this.wsProxy) this.wsProxy.close(); }; Blockchain.prototype.runCommand = function(cmd, options, callback) { console.log(__("running: %s", cmd.underline).green); - if (this.blockchainConfig.silent) { + if (this.config.silent) { options.silent = true; } - return child_process.exec(cmd, options, callback); + return exec(cmd, options, callback); }; Blockchain.prototype.run = function() { var self = this; console.log("===============================================================================".magenta); console.log("===============================================================================".magenta); - console.log(__("Embark Blockchain Using: %s", this.client.name.underline).magenta); + console.log(__("Embark Blockchain using %s", self.client.prettyName.underline).magenta); console.log("===============================================================================".magenta); console.log("===============================================================================".magenta); - this.checkPathLength(); + + if (self.client.name === 'geth') this.checkPathLength(); + let address = ''; async.waterfall([ function checkInstallation(next) { self.isClientInstalled((err) => { if (err) { - console.log(__("could not find {{geth_bin}} command; is {{client_name}} installed or in the PATH?", {geth_bin: this.config.geth_bin, client_name: this.client.name}).green); - return next(err); + return next({message: err}); } next(); }); }, function init(next) { - if (!self.isDev) { - return self.initChainAndGetAddress((err, addr) => { - address = addr; + if (self.isDev) { + return self.initDevChain((err) => { next(err); }); } - next(); + return self.initChainAndGetAddress((err, addr) => { + address = addr; + next(err); + }); }, function getMainCommand(next) { self.client.mainCommand(address, function(cmd, args) { next(null, cmd, args); }, true); } - ], function (err, cmd, args) { + ], function(err, cmd, args) { if (err) { console.error(err.message); return; @@ -177,7 +170,8 @@ Blockchain.prototype.run = function() { let full_cmd = cmd + " " + args.join(' '); console.log(__("running: %s", full_cmd.underline).green); - self.child = child_process.spawn(cmd, args, {cwd: process.cwd()}); + self.child = spawn(cmd, args, {cwd: process.cwd()}); + self.child.on('error', (err) => { err = err.toString(); console.error('Blockchain error: ', err); @@ -187,28 +181,20 @@ Blockchain.prototype.run = function() { console.error(__('Otherwise, you can change your data directory in blockchain.json (datadir)').yellow); } }); + + // TOCHECK I don't understand why stderr and stdout are reverted. + // This happens with Geth and Parity, so it does not seems a client problem self.child.stdout.on('data', (data) => { - console.error(`Geth error: ${data}`); + console.error(`${self.client.name} error: ${data}`); }); - let httpReady = false; - let wsReady = !self.config.wsRPC; - // Geth logs appear in stderr somehow + self.child.stderr.on('data', async (data) => { data = data.toString(); - if (data.indexOf('HTTP endpoint opened') > -1) { - httpReady = true; - } - - if (data.indexOf('WebSocket endpoint opened') > -1) { - wsReady = true; - } - - if (!self.readyCalled && wsReady && httpReady) { + if (!self.readyCalled && self.client.isReady(data)) { self.readyCalled = true; if (self.isDev) { - self.createFundAndUnlockAccounts((err) => { - // TODO: this is never called! - if(err) console.error('Error creating, unlocking, and funding accounts', err); + self.fundAccounts((err) => { + if (err) console.error('Error funding accounts', err); }); } if (self.config.proxy) { @@ -216,36 +202,34 @@ Blockchain.prototype.run = function() { } self.readyCallback(); } - - console.log('Geth: ' + data); + console.log(`${self.client.name}: ${data}`); }); + self.child.on('exit', (code) => { let strCode; if (code) { - strCode = ' with error code ' + code; + strCode = 'with error code ' + code; } else { - strCode = ' with no error code (manually killed?)'; + strCode = 'with no error code (manually killed?)'; } - console.error('Geth exited' + strCode); - - if(self.onExitCallback){ + console.error(self.client.name + ' exited ' + strCode); + if (self.onExitCallback) { self.onExitCallback(); } }); self.child.on('uncaughtException', (err) => { - console.error('Uncaught geth exception', err); - - if(self.onExitCallback){ + console.error('Uncaught ' + self.client.name + ' exception', err); + if (self.onExitCallback) { self.onExitCallback(); } }); }); }; -Blockchain.prototype.createFundAndUnlockAccounts = function(cb) { +Blockchain.prototype.fundAccounts = function(cb) { DevFunds.new({blockchainConfig: this.config}).then(devFunds => { - devFunds.createFundAndUnlockAccounts((err) => { + devFunds.fundAccounts(this.client.needKeepAlive(), (err) => { cb(err); }); }); @@ -255,16 +239,13 @@ Blockchain.prototype.readyCallback = function() { if (this.onReadyCallback) { this.onReadyCallback(); } - if (this.config.mineWhenNeeded && !this.isDev) { - const GethMiner = require('./miner'); - this.miner = new GethMiner({datadir: this.blockchainConfig.datadir}); + this.miner = this.client.getMiner(); } }; Blockchain.prototype.kill = function() { this.shutdownProxy(); - if (this.child) { this.child.kill(); } @@ -275,8 +256,8 @@ Blockchain.prototype.checkPathLength = function() { if (dappPath.length > 66) { // console.error is captured and sent to the console output regardless of silent setting console.error("===============================================================================".yellow); - console.error("===========> ".yellow + __('WARNING! DApp path length is too long: ').yellow + dappPath.yellow); - console.error("===========> ".yellow + __('This is known to cause issues with starting geth, please consider reducing your DApp path\'s length to 66 characters or less.').yellow); + console.error("===========> ".yellow + __('WARNING! ÐApp path length is too long: ').yellow + dappPath.yellow); + console.error("===========> ".yellow + __('This is known to cause issues with starting geth, please consider reducing your ÐApp path\'s length to 66 characters or less.').yellow); console.error("===============================================================================".yellow); } }; @@ -285,12 +266,81 @@ Blockchain.prototype.isClientInstalled = function(callback) { let versionCmd = this.client.determineVersionCommand(); this.runCommand(versionCmd, {}, (err, stdout, stderr) => { if (err || !stdout || stderr.indexOf("not found") >= 0 || stdout.indexOf("not found") >= 0) { - return callback('Geth not found'); + return callback(__('Ethereum client bin not found:') + ' ' + this.client.getBinaryPath()); } callback(); }); }; +Blockchain.prototype.initDevChain = function(callback) { + const self = this; + const ACCOUNTS_ALREADY_PRESENT = 'accounts_already_present'; + // Init the dev chain + self.client.initDevChain('.embark/development/datadir', (err) => { + if (err) { + console.log(err); + return callback(err); + } + + let needToCreateOtherAccounts = self.config.account && self.config.account.numAccounts; + if (!needToCreateOtherAccounts) return callback(); + + // Create other accounts + async.waterfall([ + function listAccounts(next) { + self.runCommand(self.client.listAccountsCommand(), {}, (err, stdout, _stderr) => { + if (err || stdout === undefined || stdout.indexOf("Fatal") >= 0) { + console.log(__("no accounts found").green); + return next(); + } + // List current addresses + self.config.unlockAddressList = self.client.parseListAccountsCommandResultToAddressList(stdout); + // Count current addresses and remove the default account from the count (because password can be different) + let addressCount = self.client.parseListAccountsCommandResultToAddressCount(stdout); + let utilityAddressCount = self.client.parseListAccountsCommandResultToAddressCount(stdout) - 1; + utilityAddressCount = (utilityAddressCount > 0 ? utilityAddressCount : 0); + let accountsToCreate = self.config.account.numAccounts - utilityAddressCount; + if (accountsToCreate > 0) { + next(null, accountsToCreate, addressCount === 0); + } else { + next(ACCOUNTS_ALREADY_PRESENT); + } + }); + }, + function newAccounts(accountsToCreate, firstAccount, next) { + // At first launch, Geth --dev does not create its own dev account if any other account are present. Parity --dev always does. Make this choerent between the two + if (firstAccount && self.client.name === 'geth') accountsToCreate++; + var accountNumber = 0; + async.whilst( + function() { + return accountNumber < accountsToCreate; + }, + function(callback) { + accountNumber++; + self.runCommand(self.client.newAccountCommand(firstAccount), {}, (err, stdout, _stderr) => { + if (err) { + return callback(err, accountNumber); + } + self.config.unlockAddressList.push(self.client.parseNewAccountCommandResultToAddress(stdout)); + firstAccount = false; + callback(null, accountNumber); + }); + }, + function(err) { + next(err); + } + ); + } + ], (err) => { + if (err && err !== ACCOUNTS_ALREADY_PRESENT) { + console.log(err); + return callback(err); + } + callback(); + }); + }); +}; + Blockchain.prototype.initChainAndGetAddress = function(callback) { const self = this; let address = null; @@ -307,17 +357,23 @@ Blockchain.prototype.initChainAndGetAddress = function(callback) { }, function listAccounts(next) { self.runCommand(self.client.listAccountsCommand(), {}, (err, stdout, _stderr) => { - if (err || stdout === undefined || stdout.match(/{(\w+)}/) === null || stdout.indexOf("Fatal") >= 0) { + if (err || stdout === undefined || stdout.indexOf("Fatal") >= 0) { + console.log(__("no accounts found").green); + return next(); + } + let firstAccountFound = self.client.parseListAccountsCommandResultToAddress(stdout); + if (firstAccountFound === undefined || firstAccountFound === "") { console.log(__("no accounts found").green); return next(); } console.log(__("already initialized").green); - address = stdout.match(/{(\w+)}/)[1]; + address = firstAccountFound; next(ALREADY_INITIALIZED); }); }, function genesisBlock(next) { - if (!self.config.genesisBlock) { + //There's no genesis init with Parity. Custom network are set in the chain property at startup + if (!self.config.genesisBlock || self.client.name === 'parity') { return next(); } console.log(__("initializing genesis block").green); @@ -330,7 +386,7 @@ Blockchain.prototype.initChainAndGetAddress = function(callback) { if (err) { return next(err); } - address = stdout.match(/{(\w+)}/)[1]; + address = self.client.parseNewAccountCommandResultToAddress(stdout); next(); }); } @@ -342,13 +398,34 @@ Blockchain.prototype.initChainAndGetAddress = function(callback) { }); }; -var BlockchainClient = function(blockchainConfig, client, env, onReadyCallback, onExitCallback) { - const isDev = !!blockchainConfig.isDev; - // TODO add other clients at some point - if (client === 'geth') { - return new Blockchain({blockchainConfig, client: GethCommands, env, isDev, onReadyCallback, onExitCallback}); +var BlockchainClient = function(userConfig, clientName, env, onReadyCallback, onExitCallback) { + if ((userConfig === {} || JSON.stringify(userConfig) === '{"enabled":true}') && env !== 'development') { + console.log("===> " + __("warning: running default config on a non-development environment")); } - throw new Error('unknown client'); + // if client is not set in preferences, default is geth + if (!userConfig.ethereumClientName) userConfig.ethereumClientName = 'geth'; + // if clientName is set, it overrides preferences + if (clientName) userConfig.ethereumClientName = clientName; + // Choose correct client instance based on clientName + let clientClass; + switch (userConfig.ethereumClientName) { + case 'geth': + clientClass = GethClient; + break; + + case 'parity': + clientClass = ParityClient; + break; + + default: + console.error(__('Unknow client "%s". Please use one of the following: %s', userConfig.ethereumClientName, 'geth, parity')); + process.exit(); + } + userConfig.isDev = (userConfig.isDev || userConfig.default); + userConfig.env = env; + userConfig.onReadyCallback = onReadyCallback; + userConfig.onExitCallback = onExitCallback; + return new Blockchain(userConfig, clientClass); }; module.exports = BlockchainClient; diff --git a/lib/modules/blockchain_process/blockchainProcess.js b/lib/modules/blockchain_process/blockchainProcess.js index 9ed6b4891..b5d82486b 100644 --- a/lib/modules/blockchain_process/blockchainProcess.js +++ b/lib/modules/blockchain_process/blockchainProcess.js @@ -32,7 +32,7 @@ class BlockchainProcess extends ProcessWrapper { } blockchainExit() { - // tell our parent process that geth has exited + // tell our parent process that ethereum client has exited blockchainProcess.send({result: constants.blockchain.blockchainExit}); } diff --git a/lib/modules/blockchain_process/blockchainProcessLauncher.js b/lib/modules/blockchain_process/blockchainProcessLauncher.js index 992d99034..d23349e53 100644 --- a/lib/modules/blockchain_process/blockchainProcessLauncher.js +++ b/lib/modules/blockchain_process/blockchainProcessLauncher.js @@ -11,6 +11,7 @@ class BlockchainProcessLauncher { this.blockchainConfig = options.blockchainConfig; this.locale = options.locale; this.isDev = options.isDev; + this.client = options.client; } processEnded(code) { @@ -30,9 +31,7 @@ class BlockchainProcessLauncher { this.blockchainProcess.send({ action: constants.blockchain.init, options: { blockchainConfig: this.blockchainConfig, - //client: this.client, - // TODO: assume for now it's geth - client: 'geth', + client: this.client, env: this.env, isDev: this.isDev, locale: this.locale diff --git a/lib/modules/blockchain_process/dev_funds.js b/lib/modules/blockchain_process/dev_funds.js index 13ab4348c..72c0c8329 100644 --- a/lib/modules/blockchain_process/dev_funds.js +++ b/lib/modules/blockchain_process/dev_funds.js @@ -4,28 +4,28 @@ const {getWeiBalanceFromString, buildUrl} = require('../../utils/utils.js'); const {readFileSync, dappPath} = require('../../core/fs'); class DevFunds { - constructor(options) { + constructor(options) { this.blockchainConfig = options.blockchainConfig; this.accounts = []; this.numAccounts = this.blockchainConfig.account.numAccounts || 0; this.password = this.blockchainConfig.account.password ? readFileSync(dappPath(this.blockchainConfig.account.password), 'utf8').replace('\n', '') : 'dev_password'; this.networkId = null; this.balance = Web3.utils.toWei("1", "ether"); - this.provider = options.provider || new Web3.providers.WebsocketProvider(buildUrl('ws', this.blockchainConfig.wsHost, this.blockchainConfig.wsPort), {headers: {Origin: "http://localhost:8000"}}); + this.provider = options.provider || new Web3.providers.WebsocketProvider(buildUrl('ws', this.blockchainConfig.wsHost, this.blockchainConfig.wsPort), {headers: {Origin: "http://embark"}}); this.web3 = new Web3(this.provider); if (this.blockchainConfig.account.balance) { this.balance = getWeiBalanceFromString(this.blockchainConfig.account.balance, this.web3); } this.logger = options.logger || console; } - - static async new(options){ + + static async new(options) { const df = new DevFunds(options); await df._init(); return df; } - - async _init () { + + async _init() { const accounts = await this.web3.eth.getAccounts(); this.web3.eth.defaultAccount = accounts[0]; if (accounts.length > 1) { @@ -34,13 +34,13 @@ class DevFunds { } _sendTx() { - if (this.networkId !== 1337) { + // Send TXs only in dev networks + if (this.networkId !== 1337 && this.networkId !== 17) { return; } this.web3.eth.sendTransaction({value: "1000000000000000", to: "0xA2817254cb8E7b6269D1689c3E0eBadbB78889d1", from: this.web3.eth.defaultAccount}); } - // trigger regular txs due to a bug in geth and stuck transactions in --dev mode _regularTxs(cb) { const self = this; self.web3.eth.net.getId().then((networkId) => { @@ -48,23 +48,30 @@ class DevFunds { if (self.networkId !== 1337) { return; } - - setInterval(function () { self._sendTx(); }, 1500); + setInterval(function() { self._sendTx(); }, 1500); if (cb) { cb(); } }); } - _regularUnlocks() { - const self = this; - setInterval(function () { self.unlockAccounts(self.password, () => { }); }, 20000); + _fundAccounts(balance, cb) { + async.each(this.accounts, (account, next) => { + this.web3.eth.getBalance(account).then(currBalance => { + const remainingBalance = balance - currBalance; + if (remainingBalance <= 0) return next(); + this.web3.eth.sendTransaction({to: account, value: remainingBalance}).catch(console.error); + next(); // don't wait for the tx receipt as it never comes! + }).catch(console.error); + }, cb); } + // TOCHECK: + // This function is not used anymore, but I leave because it is used for testing purpose (see test/devFunds.js) + // I suggest to remove this function and the corresponding test case createAccounts(numAccounts, password, cb) { const numAccountsToCreate = numAccounts - (this.accounts.length + 1); if (numAccountsToCreate === 0) return cb(); - async.timesLimit(numAccountsToCreate, 1, (_, next) => { this.web3.eth.personal.newAccount(password, next); }, (err, accounts) => { @@ -74,6 +81,9 @@ class DevFunds { }); } + // TOCHECK: + // This function is not used anymore, but I leave because it is used for testing purpose (see test/devFunds.js) + // I suggest to remove this function and the corresponding test case unlockAccounts(password, cb) { async.each(this.accounts, (account, next) => { this.web3.eth.personal.unlockAccount(account, password).then((_result) => { @@ -82,33 +92,14 @@ class DevFunds { }, cb); } - fundAccounts(balance, cb) { - async.each(this.accounts, (account, next) => { - this.web3.eth.getBalance(account).then(currBalance => { - const remainingBalance = balance - currBalance; - if (remainingBalance <= 0) return next(); - - this.web3.eth.sendTransaction({to: account, value: remainingBalance}).catch(next); - next(); // don't wait for the tx receipt as it never comes! - }).catch(cb); - }, cb); - } - - createFundAndUnlockAccounts(cb) { + fundAccounts(pingForever = false, cb) { if (!this.web3) { return cb(); } async.waterfall([ (next) => { - this.createAccounts(this.numAccounts, this.password, next); - }, - (next) => { - this.unlockAccounts(this.password, next); - }, - (next) => { - this._regularTxs(); - this._regularUnlocks(); - this.fundAccounts(this.balance, next); + if (pingForever) this._regularTxs(); + this._fundAccounts(this.balance, next); } ], cb); } diff --git a/lib/modules/blockchain_process/geth_commands.js b/lib/modules/blockchain_process/gethClient.js similarity index 53% rename from lib/modules/blockchain_process/geth_commands.js rename to lib/modules/blockchain_process/gethClient.js index 61212b80f..0c23c3902 100644 --- a/lib/modules/blockchain_process/geth_commands.js +++ b/lib/modules/blockchain_process/gethClient.js @@ -1,16 +1,59 @@ const async = require('async'); +const GethMiner = require('./miner'); +const os = require('os'); + +const DEFAULTS = { + "BIN": "geth", + "NETWORK_TYPE": "custom", + "NETWORK_ID": 1337, + "RPC_API": ['eth', 'web3', 'net', 'debug'], + "WS_API": ['eth', 'web3', 'net', 'shh', 'debug', 'pubsub'], + "DEV_WS_API": ['eth', 'web3', 'net', 'shh', 'debug', 'pubsub', 'personal'], + "TARGET_GAS_LIMIT": 8000000 +}; // TODO: make all of this async -class GethCommands { +class GethClient { + + static get DEFAULTS() { + return DEFAULTS; + } + constructor(options) { this.config = options && options.hasOwnProperty('config') ? options.config : {}; this.env = options && options.hasOwnProperty('env') ? options.env : 'development'; this.isDev = options && options.hasOwnProperty('isDev') ? options.isDev : (this.env === 'development'); - this.name = "Go-Ethereum (https://github.com/ethereum/go-ethereum)"; - this.geth_bin = this.config.geth_bin || "geth"; + this.name = "geth"; + this.prettyName = "Go-Ethereum (https://github.com/ethereum/go-ethereum)"; + this.bin = this.config.ethereumClientBin || DEFAULTS.BIN; + this.httpReady = false; + this.wsReady = !this.config.wsRPC; } - commonOptions() { + isReady(data) { + if (data.indexOf('HTTP endpoint opened') > -1) { + this.httpReady = true; + } + if (data.indexOf('WebSocket endpoint opened') > -1) { + this.wsReady = true; + } + return this.httpReady && this.wsReady; + } + + /** + * Check if the client needs some sort of 'keep alive' transactions to avoid freezing by inactivity + * @returns {boolean} if keep alive is needed + */ + needKeepAlive() { + // TODO: check version also (geth version < 1.8.15) + if (this.isDev) { + // Trigger regular txs due to a bug in geth (< 1.8.15) and stuck transactions in --dev mode. + return true; + } + return false; + } + + commonOptions(firstAccount = false) { let config = this.config; let cmd = []; @@ -20,23 +63,33 @@ class GethCommands { cmd.push(`--datadir=${config.datadir}`); } - if (config.syncMode || config.syncmode) { - cmd.push("--syncmode=" + (config.syncmode || config.syncMode)); + if (config.syncMode) { + cmd.push("--syncmode=" + config.syncMode); } + // geth in dev mode needs the first account to have a blank password, so we use for convenience the same Parity's devpassword if (config.account && config.account.password) { - cmd.push(`--password=${config.account.password}`); + if (firstAccount) cmd.push(`--password=${config.account.devPassword}`); + else cmd.push(`--password=${config.account.password}`); } - if (Number.isInteger(config.verbosity) && config.verbosity >=0 && config.verbosity <= 5) { + if (Number.isInteger(config.verbosity) && config.verbosity >= 0 && config.verbosity <= 5) { cmd.push("--verbosity=" + config.verbosity); } return cmd; } + getMiner() { + return new GethMiner({datadir: this.config.datadir}); + } + + getBinaryPath() { + return this.bin; + } + determineVersionCommand() { - return this.geth_bin + " version"; + return this.bin + " version"; } determineNetworkType(config) { @@ -53,89 +106,101 @@ class GethCommands { initGenesisCommmand() { let config = this.config; - let cmd = this.geth_bin + " " + this.commonOptions().join(' '); - + let cmd = this.bin + " " + this.commonOptions().join(' '); if (config.genesisBlock) { cmd += " init \"" + config.genesisBlock + "\" "; } - return cmd; } - newAccountCommand() { - if (!(this.config.account && this.config.account.password)){ + newAccountCommand(firstAccount = false) { + if (!(this.config.account && this.config.account.password)) { console.warn(__('Your blockchain is missing a password and creating an account may fail. Please consider updating ').yellow + __('config/blockchain > account > password').cyan + __(' then re-run the command').yellow); } - return this.geth_bin + " " + this.commonOptions().join(' ') + " account new "; + return this.bin + " " + this.commonOptions(firstAccount).join(' ') + " account new "; + } + + parseNewAccountCommandResultToAddress(data = "") { + if (data.match(/{(\w+)}/)) return "0x" + data.match(/{(\w+)}/)[1]; + return ""; } listAccountsCommand() { - return this.geth_bin + " " + this.commonOptions().join(' ') + " account list "; + return this.bin + " " + this.commonOptions().join(' ') + " account list "; + } + + parseListAccountsCommandResultToAddress(data = "") { + if (data.match(/{(\w+)}/)) return "0x" + data.match(/{(\w+)}/)[1]; + return ""; + } + + parseListAccountsCommandResultToAddressList(data = "") { + let list = data.split(os.EOL); + list.pop(); // Remove empty value + return list.map(el => "0x" + el.match(/{(\w+)}/)[1]); + } + + parseListAccountsCommandResultToAddressCount(data = "") { + const count = this.parseListAccountsCommandResultToAddressList(data).length; + return (count > 0 ? count : 0); } determineRpcOptions(config) { let cmd = []; - cmd.push("--port=" + config.port); cmd.push("--rpc"); cmd.push("--rpcport=" + config.rpcPort); cmd.push("--rpcaddr=" + config.rpcHost); if (config.rpcCorsDomain) { if (config.rpcCorsDomain === '*') { - console.log('=================================='); - console.log(__('rpcCorsDomain set to *')); - console.log(__('make sure you know what you are doing')); - console.log('=================================='); + console.warn('=================================='); + console.warn(__('rpcCorsDomain set to *')); + console.warn(__('make sure you know what you are doing')); + console.warn('=================================='); } cmd.push("--rpccorsdomain=" + config.rpcCorsDomain); } else { - console.log('=================================='); - console.log(__('warning: cors is not set')); - console.log('=================================='); + console.warn('=================================='); + console.warn(__('warning: cors is not set')); + console.warn('=================================='); } - return cmd; } determineWsOptions(config) { let cmd = []; - if (config.wsRPC) { cmd.push("--ws"); cmd.push("--wsport=" + config.wsPort); cmd.push("--wsaddr=" + config.wsHost); if (config.wsOrigins) { if (config.wsOrigins === '*') { - console.log('=================================='); - console.log(__('wsOrigins set to *')); - console.log(__('make sure you know what you are doing')); - console.log('=================================='); + console.warn('=================================='); + console.warn(__('wsOrigins set to *')); + console.warn(__('make sure you know what you are doing')); + console.warn('=================================='); } cmd.push("--wsorigins=" + config.wsOrigins); } else { - console.log('=================================='); - console.log(__('warning: wsOrigins is not set')); - console.log('=================================='); + console.warn('=================================='); + console.warn(__('warning: wsOrigins is not set')); + console.warn('=================================='); } } - return cmd; } + initDevChain(datadir, callback) { + // No specific configuration needed for the dev chain + return callback(); + } + mainCommand(address, done) { let self = this; let config = this.config; - let rpc_api = (this.config.rpcApi || ['eth', 'web3', 'net', 'debug']); - - let defaultWsApi = ['eth', 'web3', 'net', 'shh', 'debug']; - if (this.isDev) { - defaultWsApi.push('personal'); - } - - let ws_api = (this.config.wsApi || defaultWsApi); - + let rpc_api = this.config.rpcApi; + let ws_api = this.config.wsApi; let args = []; - async.series([ function commonOptions(callback) { let cmd = self.commonOptions(); @@ -205,13 +270,18 @@ class GethCommands { callback(null, '--wsapi=' + ws_api.join(',')); }, function accountToUnlock(callback) { + if (self.isDev && self.config.unlockAddressList) { + // The first address is the dev account, that is automatically unlocked by the client using blank password + args.push("--unlock=" + self.config.unlockAddressList.slice(1)); + return callback(null, "--unlock=" + self.config.unlockAddressList.slice(1)); + } let accountAddress = ""; - if(config.account && config.account.address) { + if (config.account && config.account.address) { accountAddress = config.account.address; } else { accountAddress = address; } - if (accountAddress && !self.isDev) { + if (accountAddress) { args.push("--unlock=" + accountAddress); return callback(null, "--unlock=" + accountAddress); } @@ -219,8 +289,8 @@ class GethCommands { }, function gasLimit(callback) { if (config.targetGasLimit) { - args.push("--targetgaslimit=" + config.targetGasLimit); - return callback(null, "--targetgaslimit=" + config.targetGasLimit); + args.push("--miner.gastarget=" + config.targetGasLimit); + return callback(null, "--miner.gastarget=" + config.targetGasLimit); } callback(null, ""); }, @@ -231,13 +301,13 @@ class GethCommands { } callback(null, ''); } - ], function (err) { + ], function(err) { if (err) { throw new Error(err.message); } - return done(self.geth_bin, args); + return done(self.bin, args); }); } } -module.exports = GethCommands; +module.exports = GethClient; diff --git a/lib/modules/blockchain_process/index.js b/lib/modules/blockchain_process/index.js index 3d04214bb..4d620b4e8 100644 --- a/lib/modules/blockchain_process/index.js +++ b/lib/modules/blockchain_process/index.js @@ -14,6 +14,7 @@ class BlockchainModule { this.locale = options.locale; this.isDev = options.isDev; this.ipc = options.ipc; + this.client = options.client; this.registerBlockchainProcess(); } @@ -87,7 +88,7 @@ class BlockchainModule { const {host, port, type, protocol} = self.contractsConfig.deployment; utils.pingEndpoint(host, port, type, protocol, self.blockchainConfig.wsOrigins.split(',')[0], next); } - ], function (err) { + ], function(err) { if (err === true || err === undefined) { return cb(true); } @@ -97,13 +98,15 @@ class BlockchainModule { startBlockchainNode(callback) { const self = this; + let blockchainProcess = new BlockchainProcessLauncher({ events: self.events, logger: self.logger, normalizeInput: utils.normalizeInput, blockchainConfig: self.blockchainConfig, locale: self.locale, - isDev: self.isDev + isDev: self.isDev, + client: self.client }); blockchainProcess.startBlockchainNode(); diff --git a/lib/modules/blockchain_process/parityClient.js b/lib/modules/blockchain_process/parityClient.js new file mode 100644 index 000000000..d1acd208e --- /dev/null +++ b/lib/modules/blockchain_process/parityClient.js @@ -0,0 +1,345 @@ +const async = require('async'); +const fs = require('../../core/fs.js'); +const os = require('os'); + +const DEFAULTS = { + "BIN": "parity", + "NETWORK_TYPE": "dev", + "NETWORK_ID": 17, + "RPC_API": ["web3", "eth", "pubsub", "net", "parity", "private", "parity_pubsub", "traces", "rpc", "shh", "shh_pubsub"], + "WS_API": ["web3", "eth", "pubsub", "net", "parity", "private", "parity_pubsub", "traces", "rpc", "shh", "shh_pubsub"], + "DEV_WS_API": ["web3", "eth", "pubsub", "net", "parity", "private", "parity_pubsub", "traces", "rpc", "shh", "shh_pubsub", "personal"], + "TARGET_GAS_LIMIT": 8000000, + "DEV_ACCOUNT": "0x00a329c0648769a73afac7f9381e08fb43dbea72", + "DEV_WALLET": {"id": "d9460e00-6895-8f58-f40c-bb57aebe6c00", "version": 3, "crypto": {"cipher": "aes-128-ctr", "cipherparams": {"iv": "74245f453143f9d06a095c6e6e309d5d"}, "ciphertext": "2fa611c4aa66452ef81bd1bd288f9d1ed14edf61aa68fc518093f97c791cf719", "kdf": "pbkdf2", "kdfparams": {"c": 10240, "dklen": 32, "prf": "hmac-sha256", "salt": "73b74e437a1144eb9a775e196f450a23ab415ce2c17083c225ddbb725f279b98"}, "mac": "f5882ae121e4597bd133136bf15dcbcc1bb2417a25ad205041a50c59def812a8"}, "address": "00a329c0648769a73afac7f9381e08fb43dbea72", "name": "Development Account", "meta": "{\"description\":\"Never use this account outside of development chain!\",\"passwordHint\":\"Password is empty string\"}"} +}; + +const safePush = function(set, value) { + if (set.indexOf(value) === -1) { + set.push(value); + } +}; + +class ParityClient { + + static get DEFAULTS() { + return DEFAULTS; + } + + constructor(options) { + this.config = options && options.hasOwnProperty('config') ? options.config : {}; + this.env = options && options.hasOwnProperty('env') ? options.env : 'development'; + this.isDev = options && options.hasOwnProperty('isDev') ? options.isDev : (this.env === 'development'); + this.name = "parity"; + this.prettyName = "Parity-Ethereum (https://github.com/paritytech/parity-ethereum)"; + this.bin = this.config.ethereumClientBin || DEFAULTS.BIN; + } + + isReady(data) { + return data.indexOf('Public node URL') > -1; + } + + /** + * Check if the client needs some sort of 'keep alive' transactions to avoid freezing by inactivity + * @returns {boolean} if keep alive is needed + */ + needKeepAlive() { + return false; + } + + commonOptions() { + let config = this.config; + let cmd = []; + + cmd.push(this.determineNetworkType(config)); + + if (config.networkId) { + cmd.push(`--network-id=${config.networkId}`); + } + + if (config.datadir) { + cmd.push(`--base-path=${config.datadir}`); + } + + if (config.syncMode === 'light') { + cmd.push("--light"); + } else if (config.syncMode === 'fast') { + cmd.push("--pruning=fast"); + } else if (config.syncMode === 'full') { + cmd.push("--pruning=archive"); + } + + // In dev mode we store all users passwords in the devPassword file, so Parity can unlock all users from the start + if (this.isDev) cmd.push(`--password=${config.account.devPassword}`); + else if (config.account && config.account.password) { + cmd.push(`--password=${config.account.password}`); + } + + if (Number.isInteger(config.verbosity) && config.verbosity >= 0 && config.verbosity <= 5) { + switch (config.verbosity) { + case 0: // No option to silent Parity, go to less verbose + case 1: + cmd.push("--logging=error"); + break; + case 2: + cmd.push("--logging=warn"); + break; + case 3: + cmd.push("--logging=info"); + break; + case 4: // Debug is the max verbosity for Parity + case 5: + cmd.push("--logging=debug"); + break; + default: + cmd.push("--logging=info"); + break; + } + } + + return cmd; + } + + getMiner() { + console.warn(__("Miner requested, but Parity does not embed a miner! Use Geth or install ethminer (https://github.com/ethereum-mining/ethminer)").yellow); + return; + } + + getBinaryPath() { + return this.bin; + } + + determineVersionCommand() { + return this.bin + " --version"; + } + + determineNetworkType(config) { + if (this.isDev) { + return "--chain=dev"; + } + if (config.networkType === 'rinkeby') { + console.warn(__('Parity does not support the Rinkeby PoA network, switching to Kovan PoA network')); + config.networkType = 'kovan'; + } else if (config.networkType === 'testnet') { + console.warn(__('Parity "testnet" corresponds to Kovan network, switching to Ropsten to be compliant with Geth parameters')); + config.networkType = "ropsten"; + } + if (config.genesisBlock) { + config.networkType = config.genesisBlock; + } + return "--chain=" + config.networkType; + } + + newAccountCommand() { + return this.bin + " " + this.commonOptions().join(' ') + " account new "; + } + + parseNewAccountCommandResultToAddress(data = "") { + return data.replace(/^\n|\n$/g, ""); + } + + listAccountsCommand() { + return this.bin + " " + this.commonOptions().join(' ') + " account list "; + } + + parseListAccountsCommandResultToAddress(data = "") { + return data.replace(/^\n|\n$/g, "").split('\n')[0]; + } + + parseListAccountsCommandResultToAddressList(data = "") { + let list = data.split(os.EOL); + list.pop(); + return list; + } + + parseListAccountsCommandResultToAddressCount(data = "") { + const count = this.parseListAccountsCommandResultToAddressList(data).length; + return (count > 0 ? count : 0); + } + + determineRpcOptions(config) { + let cmd = []; + cmd.push("--port=" + config.port); + cmd.push("--jsonrpc-port=" + config.rpcPort); + cmd.push("--jsonrpc-interface=" + (config.rpcHost === 'localhost' ? 'local' : config.rpcHost)); + if (config.rpcCorsDomain) { + if (config.rpcCorsDomain === '*') { + console.warn('=================================='); + console.warn(__('rpcCorsDomain set to "all"')); + console.warn(__('make sure you know what you are doing')); + console.warn('=================================='); + } + cmd.push("--jsonrpc-cors=" + (config.rpcCorsDomain === '*' ? 'all' : config.rpcCorsDomain)); + } else { + console.warn('=================================='); + console.warn(__('warning: cors is not set')); + console.warn('=================================='); + } + cmd.push("--jsonrpc-hosts=all"); + return cmd; + } + + determineWsOptions(config) { + let cmd = []; + if (config.wsRPC) { + cmd.push("--ws-port=" + config.wsPort); + cmd.push("--ws-interface=" + (config.wsHost === 'localhost' ? 'local' : config.wsHost)); + if (config.wsOrigins) { + if (config.wsOrigins === '*') { + console.warn('=================================='); + console.warn(__('wsOrigins set to "all"')); + console.warn(__('make sure you know what you are doing')); + console.warn('=================================='); + } + cmd.push("--ws-origins=" + (config.wsOrigins === '*' ? 'all' : config.wsOrigins)); + } else { + console.warn('=================================='); + console.warn(__('warning: wsOrigins is not set')); + console.warn('=================================='); + } + cmd.push("--ws-hosts=all"); + } + return cmd; + } + + initDevChain(datadir, callback) { + // Parity requires specific initialization also for the dev chain + const self = this; + const keysDataDir = '.embark/development/datadir/keys/DevelopmentChain'; + async.series([ + function makeDir(next) { + fs.mkdirp(keysDataDir, (err, _result) => { + next(err); + }); + }, + function createDevAccount(next) { + self.createDevAccount(keysDataDir, next); + }, + function updatePasswordFile(next) { + if (self.config.account.password) { + let passwordList = os.EOL + (self.config.account.password ? fs.readFileSync(fs.dappPath(self.config.account.password), 'utf8').replace('\n', '') : 'dev_password'); + fs.writeFileSync(self.config.account.devPassword, passwordList, function(err) { + return next(err); + }); + } + next(); + } + ], (err) => { + callback(err); + }); + } + + createDevAccount(keysDataDir, cb) { + const devAccountWallet = keysDataDir + '/dev.wallet'; + fs.writeFile(devAccountWallet, JSON.stringify(DEFAULTS.DEV_WALLET), function(err) { + if (err) { + return cb(err); + } + cb(); + }); + } + + mainCommand(address, done) { + let self = this; + let config = this.config; + let rpc_api = this.config.rpcApi; + let ws_api = this.config.wsApi; + let args = []; + async.series([ + function commonOptions(callback) { + let cmd = self.commonOptions(); + args = args.concat(cmd); + callback(null, cmd); + }, + function rpcOptions(callback) { + let cmd = self.determineRpcOptions(self.config); + args = args.concat(cmd); + callback(null, cmd); + }, + function wsOptions(callback) { + let cmd = self.determineWsOptions(self.config); + args = args.concat(cmd); + callback(null, cmd); + }, + function dontGetPeers(callback) { + if (config.nodiscover) { + args.push("--no-discovery"); + return callback(null, "--no-discovery"); + } + callback(null, ""); + }, + function vmDebug(callback) { + if (config.vmdebug) { + args.push("--tracing on"); + return callback(null, "--tracing on"); + } + callback(null, ""); + }, + function maxPeers(callback) { + let cmd = "--max-peers=" + config.maxpeers; + args.push(cmd); + callback(null, cmd); + }, + function bootnodes(callback) { + if (config.bootnodes && config.bootnodes !== "" && config.bootnodes !== []) { + args.push("--bootnodes=" + config.bootnodes); + return callback(null, "--bootnodes=" + config.bootnodes); + } + callback(""); + }, + function whisper(callback) { + if (config.whisper) { + safePush(rpc_api, 'shh'); + safePush(rpc_api, 'shh_pubsub'); + safePush(ws_api, 'shh'); + safePush(ws_api, 'shh_pubsub'); + args.push("--whisper"); + return callback(null, "--whisper"); + } + callback(""); + }, + function rpcApi(callback) { + args.push('--jsonrpc-apis=' + rpc_api.join(',')); + callback(null, '--jsonrpc-apis=' + rpc_api.join(',')); + }, + function wsApi(callback) { + args.push('--ws-apis=' + ws_api.join(',')); + callback(null, '--ws-apis=' + ws_api.join(',')); + }, + function accountToUnlock(callback) { + if (self.isDev) { + let unlockAddressList = self.config.unlockAddressList ? self.config.unlockAddressList : DEFAULTS.DEV_ACCOUNT; + args.push("--unlock=" + unlockAddressList); + return callback(null, "--unlock=" + unlockAddressList); + } + let accountAddress = ""; + if (config.account && config.account.address) { + accountAddress = config.account.address; + } else { + accountAddress = address; + } + if (accountAddress && !self.isDev) { + args.push("--unlock=" + accountAddress); + return callback(null, "--unlock=" + accountAddress); + } + callback(null, ""); + }, + function gasLimit(callback) { + if (config.targetGasLimit) { + args.push("--gas-floor-target=" + config.targetGasLimit); + return callback(null, "--gas-floor-target=" + config.targetGasLimit); + } + // Default Parity gas limit is 4700000: let's set to the geth default + args.push("--gas-floor-target=" + DEFAULTS.TARGET_GAS_LIMIT); + return callback(null, "--gas-floor-target=" + DEFAULTS.TARGET_GAS_LIMIT); + } + ], function(err) { + if (err) { + throw new Error(err.message); + } + return done(self.bin, args); + }); + } +} + +module.exports = ParityClient; diff --git a/lib/modules/whisper/index.js b/lib/modules/whisper/index.js index 861b61357..f03ab3c62 100644 --- a/lib/modules/whisper/index.js +++ b/lib/modules/whisper/index.js @@ -26,20 +26,42 @@ class Whisper { connectToProvider() { let {host, port} = this.communicationConfig.connection; let web3Endpoint = 'ws://' + host + ':' + port; - this.web3.setProvider(new Web3.providers.WebsocketProvider(web3Endpoint, {headers: {Origin: "embark"}})); + // Note: dont't pass to the provider things like {headers: {Origin: "embark"}}. Origin header is for browser to fill + // to protect user, it has no meaning if it is used server-side. See here for more details: https://github.com/ethereum/go-ethereum/issues/16608 + // Moreover, Parity reject origins that are not urls so if you try to connect with Origin: "embark" it gives the followin error: + // << Blocked connection to WebSockets server from untrusted origin: Some("embark") >> + // The best choice is to use void origin, BUT Geth rejects void origin, so to keep both clients happy we can use http://embark + this.web3.setProvider(new Web3.providers.WebsocketProvider(web3Endpoint, {headers: {Origin: "http://embark"}})); } setServiceCheck() { const self = this; - self.events.request("services:register", 'Whisper', function (cb) { + self.events.request("services:register", 'Whisper', function(cb) { if (!self.web3.currentProvider || self.web3.currentProvider.connection.readyState !== 1) { return self.connectToProvider(); } - self.web3.shh.getVersion(function (err, version) { - if (err || version == "2") { - return cb({name: 'Whisper', status: 'off'}); - } - return cb({name: 'Whisper (version ' + version + ')', status: 'on'}); + // 1) Parity does not implement shh_version JSON-RPC method + // 2) web3 1.0 still does not implement web3_clientVersion + // so we must do all by our own + self.web3._requestManager.send({method: 'web3_clientVersion', params: []}, (err, clientVersion) => { + if (err) return cb(err); + if (clientVersion.indexOf("Parity-Ethereum//v2") === 0) { + // This is Parity + return self.web3.shh.getInfo(function(err) { + if (err) { + return cb({name: 'Whisper', status: 'off'}); + } + // TOFIX Assume Whisper v6 until there's a way to understand it via JSON-RPC + return cb({name: 'Whisper (version 6)', status: 'on'}); + }); + } + // Assume it is a Geth compliant client + self.web3.shh.getVersion(function(err, version) { + if (err || version == "2") { + return cb({name: 'Whisper', status: 'off'}); + } + return cb({name: 'Whisper (version ' + version + ')', status: 'on'}); + }); }); }); } @@ -85,7 +107,7 @@ class Whisper { const code = `\nEmbarkJS.Messages.setProvider('whisper', ${JSON.stringify(config)});`; this.embark.addProviderInit('communication', code, shouldInit); - const consoleConfig = Object.assign({}, config, {providerOptions: {headers: {Origin: "embark"}}}); + const consoleConfig = Object.assign({}, config, {providerOptions: {headers: {Origin: "http://embark"}}}); const consoleCode = `\nEmbarkJS.Messages.setProvider('whisper', ${JSON.stringify(consoleConfig)});`; this.embark.addConsoleProviderInit('communication', consoleCode, shouldInit); } diff --git a/lib/modules/whisper/js/embarkjs.js b/lib/modules/whisper/js/embarkjs.js index 93176bab3..d7a53a029 100644 --- a/lib/modules/whisper/js/embarkjs.js +++ b/lib/modules/whisper/js/embarkjs.js @@ -3,7 +3,7 @@ // for the whisper v5 and web3.js 1.0 let __embarkWhisperNewWeb3 = {}; -__embarkWhisperNewWeb3.setProvider = function (options) { +__embarkWhisperNewWeb3.setProvider = function(options) { const self = this; let provider; if (options === undefined) { @@ -14,7 +14,7 @@ __embarkWhisperNewWeb3.setProvider = function (options) { // TODO: take into account type self.web3 = new Web3(new Web3.providers.WebsocketProvider("ws://" + provider, options.providerOptions)); self.web3.currentProvider.on('connect', () => { - self.getWhisperVersion(function (err, version) { + self.getWhisperVersion(function(err, version) { if (err) { console.log("whisper not available"); } else if (version >= 5) { @@ -35,7 +35,7 @@ __embarkWhisperNewWeb3.setProvider = function (options) { }); }; -__embarkWhisperNewWeb3.sendMessage = function (options) { +__embarkWhisperNewWeb3.sendMessage = function(options) { var topics, data, ttl, payload; topics = options.topic; data = options.data || options.payload; @@ -67,7 +67,7 @@ __embarkWhisperNewWeb3.sendMessage = function (options) { if (options.pubKey) { message.pubKey = options.pubKey; // encrypt using a given pubKey - } else if(options.symKeyID) { + } else if (options.symKeyID) { message.symKeyID = options.symKeyID; // encrypts using given sym key ID } else { message.symKeyID = this.symKeyID; // encrypts using the sym key ID @@ -77,18 +77,18 @@ __embarkWhisperNewWeb3.sendMessage = function (options) { throw new Error("missing option: topic"); } - this.web3.shh.post(message, function () { + this.web3.shh.post(message, function() { }); }; -__embarkWhisperNewWeb3.listenTo = function (options, callback) { +__embarkWhisperNewWeb3.listenTo = function(options, callback) { var topics = options.topic; let promise = new __MessageEvents(); let subOptions = {}; - if(topics){ + if (topics) { if (typeof topics === 'string') { topics = [this.web3.utils.toHex(topics).slice(0, 10)]; } else { @@ -116,34 +116,53 @@ __embarkWhisperNewWeb3.listenTo = function (options, callback) { } let filter = this.web3.shh.subscribe("messages", subOptions) - .on('data', function (result) { - var payload = JSON.parse(EmbarkJS.Utils.toAscii(result.payload)); - var data; - data = { - topic: EmbarkJS.Utils.toAscii(result.topic), - data: payload, - //from: result.from, - time: result.timestamp - }; + .on('data', function(result) { + var payload = JSON.parse(EmbarkJS.Utils.toAscii(result.payload)); + var data; + data = { + topic: EmbarkJS.Utils.toAscii(result.topic), + data: payload, + //from: result.from, + time: result.timestamp + }; - if (callback) { - return callback(null, data); - } - promise.cb(payload, data, result); - }); + if (callback) { + return callback(null, data); + } + promise.cb(payload, data, result); + }); promise.filter = filter; return promise; }; -__embarkWhisperNewWeb3.getWhisperVersion = function (cb) { - this.web3.shh.getVersion(function (err, version) { - cb(err, version); +__embarkWhisperNewWeb3.getWhisperVersion = function(cb) { + // 1) Parity does not implement shh_version JSON-RPC method + // 2) web3 1.0 still does not implement web3_clientVersion + // so we must do all by our own + const self = this; + self.web3._requestManager.send({method: 'web3_clientVersion', params: []}, (err, clientVersion) => { + if (err) return cb(err); + if (clientVersion.indexOf("Parity-Ethereum//v2") === 0) { + // This is Parity + self.web3.shh.getInfo(function(err) { + if (err) { + return cb(err, 0); + } + // TOFIX Assume Whisper v6 until there's a way to understand it via JSON-RPC + return cb(err, 6); + }); + } else { + // Assume it is a Geth compliant client + self.web3.shh.getVersion(function(err, version) { + cb(err, version); + }); + } }); }; -__embarkWhisperNewWeb3.isAvailable = function () { +__embarkWhisperNewWeb3.isAvailable = function() { return new Promise((resolve, reject) => { if (!this.web3.shh) { return resolve(false); diff --git a/locales/en.json b/locales/en.json index 4e6888e0e..21463989d 100644 --- a/locales/en.json +++ b/locales/en.json @@ -14,7 +14,9 @@ "no colors in case it's needed for compatbility purposes": "no colors in case it's needed for compatbility purposes", "filename to output logs (default: %s)": "filename to output logs (default: %s)", "run dapp (default: %s)": "run dapp (default: %s)", - "Use a specific ethereum client or simulator (supported: %s)": "Use a specific ethereum client or simulator (supported: %s)", + "Use a specific ethereum client [%s] (default: %s)": "Use a specific ethereum client [%s] (default: %s)", + "Unknow client \"%s\". Please use one of the following: %s": "Unknow client \"%s\". Please use one of the following: %s", + "Miner requested, but Parity does not embed a miner! Use Geth or install ethminer (https://github.com/ethereum-mining/ethminer)":"Miner requested, but Parity does not embed a miner! Use Geth or install ethminer (https://github.com/ethereum-mining/ethminer)", "run blockchain server (default: %s)": "run blockchain server (default: %s)", "run a fast ethereum rpc simulator": "run a fast ethereum rpc simulator", "use testrpc as the rpc simulator [%s]": "use testrpc as the rpc simulator [%s]", @@ -123,7 +125,6 @@ "Starting Blockchain node in another process": "Starting Blockchain node in another process", "Blockchain node is ready": "Blockchain node is ready", "terminating due to error": "terminating due to error", - "Unable to start the blockchain process. Is Geth installed?": "Unable to start the blockchain process. Is Geth installed?", "Error while downloading the file": "Error while downloading the file", "Error while loading the content of ": "Error while loading the content of ", "Installing packages...": "Installing packages...", @@ -144,6 +145,7 @@ "DApp path length is too long: ": "DApp path length is too long: ", "WARNING! DApp path length is too long: ": "WARNING! DApp path length is too long: ", "This is known to cause issues with starting geth, please consider reducing your DApp path's length to 66 characters or less.": "This is known to cause issues with starting geth, please consider reducing your DApp path's length to 66 characters or less.", + "Ethereum client bin not found:":"Ethereum client bin not found:", "%s is not installed on your machine": "%s is not installed on your machine", "You can install it by visiting: %s": "You can install it by visiting: %s", "Starting ipfs process": "Starting ipfs process", diff --git a/locales/es.json b/locales/es.json index f0cf4e109..68446819a 100644 --- a/locales/es.json +++ b/locales/es.json @@ -76,7 +76,7 @@ "unknown command": "comando desconocido", "did you mean": "quiso decir", "warning: running default config on a non-development environment": "precaución: ejecutando la configuración predeterminada en un ambiente de no-desarrollo", - "could not find {{geth_bin}} command; is {{client_name}} installed or in the PATH?": "no se pudo encontrar el comando {{geth_bin}}; ¿Se encuentra {{client_name}} instalado o en la ruta (PATH)?", + "Ethereum client bin not found:":"Ethereum client bin not found:", "no accounts found": "no se encontraron cuentas", "initializing genesis block": "inicializando bloque genesis", "rpcCorsDomain set to *": "rpcCorsDomain definido como *", diff --git a/locales/fr.json b/locales/fr.json index 11d69ba2a..c82b0fa53 100644 --- a/locales/fr.json +++ b/locales/fr.json @@ -18,14 +18,14 @@ "filename to output logs (default: none)": "nom de fichier pour les journaux de sortie (par défaut: aucun)", "level of logging to display": "niveau de journalisation à afficher", "deploy and build dapp at ": "Publiez et créez la dapp dans ", - "port to run the dev webserver (default: %s)": "port pour exécuter le serveur de développement Web (par défaut:% s)", - "host to run the dev webserver (default: %s)": "hôte pour exécuter le serveur de développement Web (par défaut:% s)", + "port to run the dev webserver (default: %s)": "port pour exécuter le serveur de développement Web (par défaut: %s)", + "host to run the dev webserver (default: %s)": "hôte pour exécuter le serveur de développement Web (par défaut: %s)", "disable the development webserver": "désactiver le serveur de développement Web", "simple mode, disables the dashboard": "mode simple, désactive le tableau de bord", "no colors in case it's needed for compatbility purposes": "pas de couleur au cas où cela serait nécessaire à des fins de compatibilité", "filename to output logs (default: %s)": "nom de fichier pour les journaux de sortie (par défaut: %s)", "run dapp (default: %s)": "lancer la dapp (par défaut: %s)", - "Use a specific ethereum client or simulator (supported: %s)": "Utiliser un client ou simulateur ethereum spécifique (supporté:% s)", + "Use a specific ethereum client [%s] (default: %s)": "Utiliser un client ethereum spécifique [%s] (supporté: %s)", "run blockchain server (default: %s)": "exécuter le serveur blockchain (par défaut: %s)", "run a fast ethereum rpc simulator": "exécuter un simulateur ethereum RPC rapide", "use testrpc as the rpc simulator [%s]": "utiliser testrpc comme simulateur RPC [%s]", @@ -76,7 +76,7 @@ "unknown command": "commande inconnue", "did you mean": "vouliez-vous dire", "warning: running default config on a non-development environment": "avertissement: exécution de la configuration par défaut sur un environnement de non-développement", - "could not find {{geth_bin}} command; is {{client_name}} installed or in the PATH?": "Impossible de trouver la commande {{geth_bin}}, est-ce que {{client_name}} est installé ou dans le PATH?", + "Ethereum client bin not found:":"Ethereum client bin not found:", "no accounts found": "Aucun compte trouvé", "initializing genesis block": "initialisation du bloc de genèse", "rpcCorsDomain set to *": "rpcCorsDomain défini sur *", diff --git a/locales/pt.json b/locales/pt.json index a4af4cf11..8eddcee12 100644 --- a/locales/pt.json +++ b/locales/pt.json @@ -25,7 +25,7 @@ "no colors in case it's needed for compatbility purposes": "sem cores, em caso seja necessario para compabitilidade com a terminal", "filename to output logs (default: %s)": "ficheiro/arquivo para os logs (predefinido: %s)", "run dapp (default: %s)": "executa a dapp (applicacao decentralizada) (predefinido: %s)", - "Use a specific ethereum client or simulator (supported: %s)": "Usa um cliente ou simulador de ethereum específico (supportado: %s)", + "Use a specific ethereum client [%s] (default: %s)": "Usa um cliente de ethereum específico [%s] (supportado: %s)", "run blockchain server (default: %s)": "executa un node de blockchain (predefinido: %s)", "run a fast ethereum rpc simulator": "executa um simulador RPC de ethereum", "use testrpc as the rpc simulator [%s]": "usa testrpc como simulator de rpc [%s]", @@ -76,7 +76,7 @@ "unknown command": "comando desconhecido", "did you mean": "você quis dizer", "warning: running default config on a non-development environment": "aviso: executando a configuração padrão em um ambiente de não desenvolvimento", - "could not find {{geth_bin}} command; is {{client_name}} installed or in the PATH?": "não foi possível encontrar o comando {{geth_bin}}; o {{client_name}} instalado ou no PATH?", + "Ethereum client bin not found:":"Ethereum client bin not found:", "no accounts found": "nenhuma conta encontrada", "initializing genesis block": "inicializando o bloco de gênese", "rpcCorsDomain set to *": "rpcCorsDomain definido como *", diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index c557a94e9..0c08fc95c 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -15327,6 +15327,22 @@ "write-file-atomic": "^2.0.0" } }, + "ws": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-3.0.0.tgz", + "integrity": "sha1-mN2wAFbIOQy3Ued4h4hJf5kQO2w=", + "requires": { + "safe-buffer": "~5.0.1", + "ultron": "~1.1.0" + }, + "dependencies": { + "safe-buffer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.0.1.tgz", + "integrity": "sha1-0mPKVGls2KMGtcplUekt5XkY++c=" + } + } + }, "ws": { "version": "3.3.3", "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz", diff --git a/templates/boilerplate/config/blockchain.js b/templates/boilerplate/config/blockchain.js index 4b929d114..b51d5b431 100644 --- a/templates/boilerplate/config/blockchain.js +++ b/templates/boilerplate/config/blockchain.js @@ -16,10 +16,12 @@ module.exports = { // default environment, merges with the settings in default // assumed to be the intended environment by `embark run` and `embark blockchain` development: { + ethereumClientName: "geth", // Can be geth or parity (default:geth) + //ethereumClientBin: "geth", // path to the client binary. Useful if it is not in the global PATH networkType: "custom", // Can be: testnet, rinkeby, livenet or custom, in which case, it will use the specified networkId - networkId: "1337", // Network id used when networkType is custom + networkId: 1337, // Network id used when networkType is custom isDev: true, // Uses and ephemeral proof-of-authority network with a pre-funded developer account, mining enabled - datadir: ".embark/development/datadir", // Data directory for the databases and keystore + datadir: ".embark/development/datadir", // Data directory for the databases and keystore (Geth 1.8.15 and Parity 2.0.4 can use the same base folder, till now they does not conflict with each other) mineWhenNeeded: true, // Uses our custom script (if isDev is false) to mine only when needed nodiscover: true, // Disables the peer discovery mechanism (manual peer addition) maxpeers: 0, // Maximum number of network peers (network disabled if set to 0) (default: 25) @@ -30,7 +32,8 @@ module.exports = { account: { // numAccounts: 3, // When specified, creates accounts for use in the dapp. This option only works in the development environment, and can be used as a quick start option that bypasses the need for MetaMask in development. These accounts are unlocked and funded with the below settings. // password: "config/development/password", // Password for the created accounts (as specified in the `numAccounts` setting). If `mineWhenNeeded` is enabled (and isDev is not), this password is used to create a development account controlled by the node. - // balance: "5 ether" // Balance to be given to the created accounts (as specified in the `numAccounts` setting) + // balance: "5 ether", // Balance to be given to the created accounts (as specified in the `numAccounts` setting) + devPassword: "config/development/devpassword" // [Parity-only] File with a void line to unlock the Parity dev account } }, @@ -38,7 +41,7 @@ module.exports = { // used with "embark run privatenet" and/or "embark blockchain privatenet" privatenet: { networkType: "custom", - networkId: "1337", + networkId: 1337, isDev: false, datadir: ".embark/privatenet/datadir", // -- mineWhenNeeded -- @@ -60,8 +63,28 @@ module.exports = { maxpeers: 0, proxy: true, account: { - // "address": "", // When specified, uses that address instead of the default one for the network - password: "config/privatenet/password" // Password to unlock the account. If `mineWhenNeeded` is enabled (and isDev is not), this password is used to create a development account controlled by the node. + // address: "", // When specified, uses that address instead of the default one for the network + password: "config/privatenet/password" // Password to unlock the account + }, + targetGasLimit: 8000000, + simulatorMnemonic: "example exile argue silk regular smile grass bomb merge arm assist farm", + simulatorBlocktime: 0 + }, + + privateparitynet: { + ethereumClientName: "parity", + networkType: "custom", + networkId: 1337, + isDev: false, + genesisBlock: "config/privatenet/genesis-parity.json", // Genesis block to initiate on first creation of a development node + datadir: ".embark/privatenet/datadir", + mineWhenNeeded: false, + nodiscover: true, + maxpeers: 0, + proxy: true, + account: { + // address: "", // When specified, uses that address instead of the default one for the network + password: "config/privatenet/password" // Password to unlock the account }, targetGasLimit: 8000000, simulatorMnemonic: "example exile argue silk regular smile grass bomb merge arm assist farm", diff --git a/templates/boilerplate/config/development/devpassword b/templates/boilerplate/config/development/devpassword new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/templates/boilerplate/config/development/devpassword @@ -0,0 +1 @@ + diff --git a/templates/boilerplate/config/development/password b/templates/boilerplate/config/development/password new file mode 100644 index 000000000..fca906b15 --- /dev/null +++ b/templates/boilerplate/config/development/password @@ -0,0 +1 @@ +dev_password \ No newline at end of file diff --git a/templates/boilerplate/config/privatenet/genesis-parity.json b/templates/boilerplate/config/privatenet/genesis-parity.json new file mode 100644 index 000000000..03f574b33 --- /dev/null +++ b/templates/boilerplate/config/privatenet/genesis-parity.json @@ -0,0 +1,147 @@ +{ + "name": "DevelopmentChain", + "engine": { + "instantSeal": null + }, + "params": { + "gasLimitBoundDivisor": "0x0400", + "accountStartNonce": "0x0", + "maximumExtraDataSize": "0x20", + "minGasLimit": "0x1388", + "networkID": "0x11", + "registrar": "0x0000000000000000000000000000000000001337", + "eip150Transition": "0x0", + "eip160Transition": "0x0", + "eip161abcTransition": "0x0", + "eip161dTransition": "0x0", + "eip155Transition": "0x0", + "eip98Transition": "0x7fffffffffffff", + "eip86Transition": "0x7fffffffffffff", + "maxCodeSize": 24576, + "maxCodeSizeTransition": "0x0", + "eip140Transition": "0x0", + "eip211Transition": "0x0", + "eip214Transition": "0x0", + "eip658Transition": "0x0", + "wasmActivationTransition": "0x0" + }, + "genesis": { + "seal": { + "generic": "0x0" + }, + "difficulty": "0x20000", + "author": "0x0000000000000000000000000000000000000000", + "timestamp": "0x00", + "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "extraData": "0x", + "gasLimit": "0x7A1200" + }, + "accounts": { + "0000000000000000000000000000000000000001": { + "balance": "1", + "builtin": { + "name": "ecrecover", + "pricing": { + "linear": { + "base": 3000, + "word": 0 + } + } + } + }, + "0000000000000000000000000000000000000002": { + "balance": "1", + "builtin": { + "name": "sha256", + "pricing": { + "linear": { + "base": 60, + "word": 12 + } + } + } + }, + "0000000000000000000000000000000000000003": { + "balance": "1", + "builtin": { + "name": "ripemd160", + "pricing": { + "linear": { + "base": 600, + "word": 120 + } + } + } + }, + "0000000000000000000000000000000000000004": { + "balance": "1", + "builtin": { + "name": "identity", + "pricing": { + "linear": { + "base": 15, + "word": 3 + } + } + } + }, + "0000000000000000000000000000000000000005": { + "balance": "1", + "builtin": { + "name": "modexp", + "activate_at": 0, + "pricing": { + "modexp": { + "divisor": 20 + } + } + } + }, + "0000000000000000000000000000000000000006": { + "balance": "1", + "builtin": { + "name": "alt_bn128_add", + "activate_at": 0, + "pricing": { + "linear": { + "base": 500, + "word": 0 + } + } + } + }, + "0000000000000000000000000000000000000007": { + "balance": "1", + "builtin": { + "name": "alt_bn128_mul", + "activate_at": 0, + "pricing": { + "linear": { + "base": 40000, + "word": 0 + } + } + } + }, + "0000000000000000000000000000000000000008": { + "balance": "1", + "builtin": { + "name": "alt_bn128_pairing", + "activate_at": 0, + "pricing": { + "alt_bn128_pairing": { + "base": 100000, + "pair": 80000 + } + } + } + }, + "0000000000000000000000000000000000001337": { + "balance": "1", + "constructor": "0x606060405233600060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550670de0b6b3a764000060035534610000575b612904806100666000396000f3006060604052361561013c576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806306b2ff471461014157806313af40351461018c57806319362a28146101bf5780633f3935d114610248578063432ced04146102b75780634f39ca59146102eb5780636795dbcd1461032457806369fe0e2d146103c857806379ce9fac146103fd5780638da5cb5b1461045557806390b97fc1146104a457806392698814146105245780639890220b1461055d578063ac4e73f914610584578063ac72c12014610612578063c3a358251461064b578063ddca3f43146106c3578063deb931a2146106e6578063df57b74214610747578063e30bd740146107a8578063eadf976014610862578063ef5454d6146108e7578063f25eb5c114610975578063f6d339e414610984575b610000565b3461000057610172600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610a1f565b604051808215151515815260200191505060405180910390f35b34610000576101bd600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610a81565b005b346100005761022e60048080356000191690602001909190803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509190803560001916906020019091905050610ba2565b604051808215151515815260200191505060405180910390f35b346100005761029d600480803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091905050610dc9565b604051808215151515815260200191505060405180910390f35b6102d1600480803560001916906020019091905050611035565b604051808215151515815260200191505060405180910390f35b346100005761030a60048080356000191690602001909190505061115f565b604051808215151515815260200191505060405180910390f35b346100005761038660048080356000191690602001909190803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091905050611378565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34610000576103e3600480803590602001909190505061140d565b604051808215151515815260200191505060405180910390f35b346100005761043b60048080356000191690602001909190803573ffffffffffffffffffffffffffffffffffffffff169060200190919050506114b4565b604051808215151515815260200191505060405180910390f35b34610000576104626115fb565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b346100005761050660048080356000191690602001909190803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091905050611621565b60405180826000191660001916815260200191505060405180910390f35b34610000576105436004808035600019169060200190919050506116b2565b604051808215151515815260200191505060405180910390f35b346100005761056a611715565b604051808215151515815260200191505060405180910390f35b34610000576105f8600480803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509190803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050611824565b604051808215151515815260200191505060405180910390f35b3461000057610631600480803560001916906020019091905050611d8b565b604051808215151515815260200191505060405180910390f35b34610000576106ad60048080356000191690602001909190803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091905050611dee565b6040518082815260200191505060405180910390f35b34610000576106d0611e83565b6040518082815260200191505060405180910390f35b3461000057610705600480803560001916906020019091905050611e89565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3461000057610766600480803560001916906020019091905050611ed2565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34610000576107d9600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050611f1b565b6040518080602001828103825283818151815260200191508051906020019080838360008314610828575b80518252602083111561082857602082019150602081019050602083039250610804565b505050905090810190601f1680156108545780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34610000576108cd60048080356000191690602001909190803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509190803590602001909190505061200c565b604051808215151515815260200191505060405180910390f35b346100005761095b600480803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509190803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050612236565b604051808215151515815260200191505060405180910390f35b3461000057610982612425565b005b3461000057610a0560048080356000191690602001909190803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509190803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050612698565b604051808215151515815260200191505060405180910390f35b60006000600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020805460018160011615610100020316600290049050141590505b919050565b600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610add57610b9f565b8073ffffffffffffffffffffffffffffffffffffffff16600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f70aea8d848e8a90fb7661b227dc522eb6395c3dac71b63cb59edd5c9899b236460405180905060405180910390a380600060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b5b50565b6000833373ffffffffffffffffffffffffffffffffffffffff1660016000836000191660001916815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16141515610c1d57610dc1565b82600160008760001916600019168152602001908152602001600020600201856040518082805190602001908083835b60208310610c705780518252602082019150602081019050602083039250610c4d565b6001836020036101000a03801982511681845116808217855250505050505090500191505090815260200160405180910390208160001916905550836040518082805190602001908083835b60208310610cdf5780518252602082019150602081019050602083039250610cbc565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051809103902085600019167fb829c3e412537bbe794c048ccb9e4605bb4aaaa8e4d4c15c1a6e0c2adc1716ea866040518080602001828103825283818151815260200191508051906020019080838360008314610d82575b805182526020831115610d8257602082019150602081019050602083039250610d5e565b505050905090810190601f168015610dae5780820380516001836020036101000a031916815260200191505b509250505060405180910390a3600191505b5b509392505050565b6000813373ffffffffffffffffffffffffffffffffffffffff1660016000836040518082805190602001908083835b60208310610e1b5780518252602082019150602081019050602083039250610df8565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405180910390206000191660001916815260200190815260200160002060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16141515610ea45761102f565b82600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209080519060200190828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10610f2d57805160ff1916838001178555610f5b565b82800160010185558215610f5b579182015b82811115610f5a578251825591602001919060010190610f3f565b5b509050610f8091905b80821115610f7c576000816000905550600101610f64565b5090565b50503373ffffffffffffffffffffffffffffffffffffffff16836040518082805190602001908083835b60208310610fcd5780518252602082019150602081019050602083039250610faa565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405180910390207f098ae8581bb8bd9af1beaf7f2e9f51f31a8e5a8bfada4e303a645d71d9c9192060405180905060405180910390a3600191505b5b50919050565b600081600060016000836000191660001916815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614151561109b57611159565b6003543410156110aa57611158565b3360016000856000191660001916815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055503373ffffffffffffffffffffffffffffffffffffffff1683600019167f4963513eca575aba66fdcd25f267aae85958fe6fb97e75fa25d783f1a091a22160405180905060405180910390a3600191505b5b5b50919050565b6000813373ffffffffffffffffffffffffffffffffffffffff1660016000836000191660001916815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415156111da57611372565b6002600060016000866000191660001916815260200190815260200160002060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020805460018160011615610100020316600290046000825580601f1061127c57506112b3565b601f0160209004906000526020600020908101906112b291905b808211156112ae576000816000905550600101611296565b5090565b5b5060016000846000191660001916815260200190815260200160002060006000820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905550503373ffffffffffffffffffffffffffffffffffffffff1683600019167fef1961b4d2909dc23643b309bfe5c3e5646842d98c3a58517037ef3871185af360405180905060405180910390a3600191505b5b50919050565b6000600160008460001916600019168152602001908152602001600020600201826040518082805190602001908083835b602083106113cc57805182526020820191506020810190506020830392506113a9565b6001836020036101000a0380198251168184511680821785525050505050509050019150509081526020016040518091039020546001900490505b92915050565b6000600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561146b576114af565b816003819055507f6bbc57480a46553fa4d156ce702beef5f3ad66303b0ed1a5d4cb44966c6584c3826040518082815260200191505060405180910390a1600190505b5b919050565b6000823373ffffffffffffffffffffffffffffffffffffffff1660016000836000191660001916815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614151561152f576115f4565b8260016000866000191660001916815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1685600019167f7b97c62130aa09acbbcbf7482630e756592496f1759eaf702f469cf64dfb779460405180905060405180910390a4600191505b5b5092915050565b600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000600160008460001916600019168152602001908152602001600020600201826040518082805190602001908083835b602083106116755780518252602082019150602081019050602083039250611652565b6001836020036101000a03801982511681845116808217855250505050505090500191505090815260200160405180910390205490505b92915050565b6000600060016000846000191660001916815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16141590505b919050565b6000600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561177357611821565b7fdef931299fe61d176f949118058530c1f3f539dcb6950b4e372c9b835c33ca073073ffffffffffffffffffffffffffffffffffffffff16316040518082815260200191505060405180910390a13373ffffffffffffffffffffffffffffffffffffffff166108fc3073ffffffffffffffffffffffffffffffffffffffff16319081150290604051809050600060405180830381858888f19350505050151561181b57610000565b600190505b5b90565b60006000836040518082805190602001908083835b6020831061185c5780518252602082019150602081019050602083039250611839565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405180910390203373ffffffffffffffffffffffffffffffffffffffff1660016000836000191660001916815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614151561190157611d83565b846040518082805190602001908083835b602083106119355780518252602082019150602081019050602083039250611912565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405180910390209150600060016000846000191660001916815260200190815260200160002060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614158015611ab4575081600019166002600060016000866000191660001916815260200190815260200160002060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206040518082805460018160011615610100020316600290048015611aa15780601f10611a7f576101008083540402835291820191611aa1565b820191906000526020600020905b815481529060010190602001808311611a8d575b5050915050604051809103902060001916145b15611c79576002600060016000856000191660001916815260200190815260200160002060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020805460018160011615610100020316600290046000825580601f10611b5b5750611b92565b601f016020900490600052602060002090810190611b9191905b80821115611b8d576000816000905550600101611b75565b5090565b5b5060016000836000191660001916815260200190815260200160002060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16856040518082805190602001908083835b60208310611c1c5780518252602082019150602081019050602083039250611bf9565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405180910390207f12491ad95fd945e444d88a894ffad3c21959880a4dcd8af99d4ae4ffc71d4abd60405180905060405180910390a35b8360016000846000191660001916815260200190815260200160002060010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508373ffffffffffffffffffffffffffffffffffffffff16856040518082805190602001908083835b60208310611d215780518252602082019150602081019050602083039250611cfe565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405180910390207f728435a0031f6a04538fcdd24922a7e06bc7bc945db03e83d22122d1bc5f28df60405180905060405180910390a3600192505b5b505092915050565b6000600060016000846000191660001916815260200190815260200160002060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16141590505b919050565b6000600160008460001916600019168152602001908152602001600020600201826040518082805190602001908083835b60208310611e425780518252602082019150602081019050602083039250611e1f565b6001836020036101000a0380198251168184511680821785525050505050509050019150509081526020016040518091039020546001900490505b92915050565b60035481565b600060016000836000191660001916815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690505b919050565b600060016000836000191660001916815260200190815260200160002060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690505b919050565b6020604051908101604052806000815250600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015611fff5780601f10611fd457610100808354040283529160200191611fff565b820191906000526020600020905b815481529060010190602001808311611fe257829003601f168201915b505050505090505b919050565b6000833373ffffffffffffffffffffffffffffffffffffffff1660016000836000191660001916815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415156120875761222e565b82600102600160008760001916600019168152602001908152602001600020600201856040518082805190602001908083835b602083106120dd57805182526020820191506020810190506020830392506120ba565b6001836020036101000a03801982511681845116808217855250505050505090500191505090815260200160405180910390208160001916905550836040518082805190602001908083835b6020831061214c5780518252602082019150602081019050602083039250612129565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051809103902085600019167fb829c3e412537bbe794c048ccb9e4605bb4aaaa8e4d4c15c1a6e0c2adc1716ea8660405180806020018281038252838181518152602001915080519060200190808383600083146121ef575b8051825260208311156121ef576020820191506020810190506020830392506121cb565b505050905090810190601f16801561221b5780820380516001836020036101000a031916815260200191505b509250505060405180910390a3600191505b5b509392505050565b6000600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156122945761241f565b82600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209080519060200190828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061231d57805160ff191683800117855561234b565b8280016001018555821561234b579182015b8281111561234a57825182559160200191906001019061232f565b5b50905061237091905b8082111561236c576000816000905550600101612354565b5090565b50508173ffffffffffffffffffffffffffffffffffffffff16836040518082805190602001908083835b602083106123bd578051825260208201915060208101905060208303925061239a565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405180910390207f098ae8581bb8bd9af1beaf7f2e9f51f31a8e5a8bfada4e303a645d71d9c9192060405180905060405180910390a3600190505b5b92915050565b3373ffffffffffffffffffffffffffffffffffffffff16600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060405180828054600181600116156101000203166002900480156124d65780601f106124b45761010080835404028352918201916124d6565b820191906000526020600020905b8154815290600101906020018083116124c2575b505091505060405180910390207f12491ad95fd945e444d88a894ffad3c21959880a4dcd8af99d4ae4ffc71d4abd60405180905060405180910390a360016000600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060405180828054600181600116156101000203166002900480156125b05780601f1061258e5761010080835404028352918201916125b0565b820191906000526020600020905b81548152906001019060200180831161259c575b505091505060405180910390206000191660001916815260200190815260200160002060010160006101000a81549073ffffffffffffffffffffffffffffffffffffffff0219169055600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020805460018160011615610100020316600290046000825580601f1061265d5750612694565b601f01602090049060005260206000209081019061269391905b8082111561268f576000816000905550600101612677565b5090565b5b505b565b6000833373ffffffffffffffffffffffffffffffffffffffff1660016000836000191660001916815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16141515612713576128d0565b8273ffffffffffffffffffffffffffffffffffffffff16600102600160008760001916600019168152602001908152602001600020600201856040518082805190602001908083835b6020831061277f578051825260208201915060208101905060208303925061275c565b6001836020036101000a03801982511681845116808217855250505050505090500191505090815260200160405180910390208160001916905550836040518082805190602001908083835b602083106127ee57805182526020820191506020810190506020830392506127cb565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051809103902085600019167fb829c3e412537bbe794c048ccb9e4605bb4aaaa8e4d4c15c1a6e0c2adc1716ea866040518080602001828103825283818151815260200191508051906020019080838360008314612891575b8051825260208311156128915760208201915060208101905060208303925061286d565b505050905090810190601f1680156128bd5780820380516001836020036101000a031916815260200191505b509250505060405180910390a3600191505b5b5093925050505600a165627a7a7230582066b2da4773a0f1d81efe071c66b51c46868a871661efd18c0f629353ff4c1f9b0029" + }, + "00a329c0648769a73afac7f9381e08fb43dbea72": { + "balance": "1606938044258990275541962092341162602522202993782792835301376" + } + } +} \ No newline at end of file diff --git a/templates/demo/config/blockchain.js b/templates/demo/config/blockchain.js index f3428c718..ed22d42b5 100644 --- a/templates/demo/config/blockchain.js +++ b/templates/demo/config/blockchain.js @@ -16,10 +16,12 @@ module.exports = { // default environment, merges with the settings in default // assumed to be the intended environment by `embark run` and `embark blockchain` development: { + ethereumClientName: "geth", // Can be geth or parity (default:geth) + //ethereumClientBin: "geth", // path to the client binary. Useful if it is not in the global PATH networkType: "custom", // Can be: testnet, rinkeby, livenet or custom, in which case, it will use the specified networkId - networkId: "1337", // Network id used when networkType is custom + networkId: 1337, // Network id used when networkType is custom isDev: true, // Uses and ephemeral proof-of-authority network with a pre-funded developer account, mining enabled - datadir: ".embark/development/datadir", // Data directory for the databases and keystore + datadir: ".embark/development/datadir", // Data directory for the databases and keystore (Geth 1.8.15 and Parity 2.0.4 can use the same base folder, till now they does not conflict with each other) mineWhenNeeded: true, // Uses our custom script (if isDev is false) to mine only when needed nodiscover: true, // Disables the peer discovery mechanism (manual peer addition) maxpeers: 0, // Maximum number of network peers (network disabled if set to 0) (default: 25) @@ -30,7 +32,8 @@ module.exports = { account: { // numAccounts: 3, // When specified, creates accounts for use in the dapp. This option only works in the development environment, and can be used as a quick start option that bypasses the need for MetaMask in development. These accounts are unlocked and funded with the below settings. // password: "config/development/password", // Password for the created accounts (as specified in the `numAccounts` setting). If `mineWhenNeeded` is enabled (and isDev is not), this password is used to create a development account controlled by the node. - // balance: "5 ether" // Balance to be given to the created accounts (as specified in the `numAccounts` setting) + // balance: "5 ether", // Balance to be given to the created accounts (as specified in the `numAccounts` setting) + devPassword: "config/development/devpassword" // [Parity-only] File with a void line to unlock the Parity dev account } }, @@ -38,7 +41,7 @@ module.exports = { // used with "embark run privatenet" and/or "embark blockchain privatenet" privatenet: { networkType: "custom", - networkId: "1337", + networkId: 1337, isDev: false, datadir: ".embark/privatenet/datadir", // -- mineWhenNeeded -- @@ -70,6 +73,28 @@ module.exports = { simulatorBlocktime: 0 }, + // merges with the settings in default + // used with "embark run privatparityenet" and/or "embark blockchain privateparitynet" + privateparitynet: { + ethereumClientName: "parity", + networkType: "custom", + networkId: 1337, + isDev: false, + genesisBlock: "config/privatenet/genesis-parity.json", // Genesis block to initiate on first creation of a development node + datadir: ".embark/privatenet/datadir", // (Geth 1.8.15 and Parity 2.0.4 can use the same base folder, till now they does not conflict with each other) + mineWhenNeeded: false, + nodiscover: true, + maxpeers: 0, + proxy: true, + account: { + // address: "", // When specified, uses that address instead of the default one for the network + password: "config/privatenet/password" // Password to unlock the account + }, + targetGasLimit: 8000000, + simulatorMnemonic: "example exile argue silk regular smile grass bomb merge arm assist farm", + simulatorBlocktime: 0 + }, + // merges with the settings in default // used with "embark run testnet" and/or "embark blockchain testnet" testnet: { @@ -90,7 +115,7 @@ module.exports = { account: { password: "config/livenet/password" } - }, + } // you can name an environment with specific settings and then specify with // "embark run custom_name" or "embark blockchain custom_name" diff --git a/templates/demo/config/development/devpassword b/templates/demo/config/development/devpassword new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/templates/demo/config/development/devpassword @@ -0,0 +1 @@ + diff --git a/templates/demo/config/development/password b/templates/demo/config/development/password new file mode 100644 index 000000000..fca906b15 --- /dev/null +++ b/templates/demo/config/development/password @@ -0,0 +1 @@ +dev_password \ No newline at end of file diff --git a/templates/demo/config/privatenet/genesis-parity.json b/templates/demo/config/privatenet/genesis-parity.json new file mode 100644 index 000000000..03f574b33 --- /dev/null +++ b/templates/demo/config/privatenet/genesis-parity.json @@ -0,0 +1,147 @@ +{ + "name": "DevelopmentChain", + "engine": { + "instantSeal": null + }, + "params": { + "gasLimitBoundDivisor": "0x0400", + "accountStartNonce": "0x0", + "maximumExtraDataSize": "0x20", + "minGasLimit": "0x1388", + "networkID": "0x11", + "registrar": "0x0000000000000000000000000000000000001337", + "eip150Transition": "0x0", + "eip160Transition": "0x0", + "eip161abcTransition": "0x0", + "eip161dTransition": "0x0", + "eip155Transition": "0x0", + "eip98Transition": "0x7fffffffffffff", + "eip86Transition": "0x7fffffffffffff", + "maxCodeSize": 24576, + "maxCodeSizeTransition": "0x0", + "eip140Transition": "0x0", + "eip211Transition": "0x0", + "eip214Transition": "0x0", + "eip658Transition": "0x0", + "wasmActivationTransition": "0x0" + }, + "genesis": { + "seal": { + "generic": "0x0" + }, + "difficulty": "0x20000", + "author": "0x0000000000000000000000000000000000000000", + "timestamp": "0x00", + "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "extraData": "0x", + "gasLimit": "0x7A1200" + }, + "accounts": { + "0000000000000000000000000000000000000001": { + "balance": "1", + "builtin": { + "name": "ecrecover", + "pricing": { + "linear": { + "base": 3000, + "word": 0 + } + } + } + }, + "0000000000000000000000000000000000000002": { + "balance": "1", + "builtin": { + "name": "sha256", + "pricing": { + "linear": { + "base": 60, + "word": 12 + } + } + } + }, + "0000000000000000000000000000000000000003": { + "balance": "1", + "builtin": { + "name": "ripemd160", + "pricing": { + "linear": { + "base": 600, + "word": 120 + } + } + } + }, + "0000000000000000000000000000000000000004": { + "balance": "1", + "builtin": { + "name": "identity", + "pricing": { + "linear": { + "base": 15, + "word": 3 + } + } + } + }, + "0000000000000000000000000000000000000005": { + "balance": "1", + "builtin": { + "name": "modexp", + "activate_at": 0, + "pricing": { + "modexp": { + "divisor": 20 + } + } + } + }, + "0000000000000000000000000000000000000006": { + "balance": "1", + "builtin": { + "name": "alt_bn128_add", + "activate_at": 0, + "pricing": { + "linear": { + "base": 500, + "word": 0 + } + } + } + }, + "0000000000000000000000000000000000000007": { + "balance": "1", + "builtin": { + "name": "alt_bn128_mul", + "activate_at": 0, + "pricing": { + "linear": { + "base": 40000, + "word": 0 + } + } + } + }, + "0000000000000000000000000000000000000008": { + "balance": "1", + "builtin": { + "name": "alt_bn128_pairing", + "activate_at": 0, + "pricing": { + "alt_bn128_pairing": { + "base": 100000, + "pair": 80000 + } + } + } + }, + "0000000000000000000000000000000000001337": { + "balance": "1", + "constructor": "0x606060405233600060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550670de0b6b3a764000060035534610000575b612904806100666000396000f3006060604052361561013c576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806306b2ff471461014157806313af40351461018c57806319362a28146101bf5780633f3935d114610248578063432ced04146102b75780634f39ca59146102eb5780636795dbcd1461032457806369fe0e2d146103c857806379ce9fac146103fd5780638da5cb5b1461045557806390b97fc1146104a457806392698814146105245780639890220b1461055d578063ac4e73f914610584578063ac72c12014610612578063c3a358251461064b578063ddca3f43146106c3578063deb931a2146106e6578063df57b74214610747578063e30bd740146107a8578063eadf976014610862578063ef5454d6146108e7578063f25eb5c114610975578063f6d339e414610984575b610000565b3461000057610172600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610a1f565b604051808215151515815260200191505060405180910390f35b34610000576101bd600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610a81565b005b346100005761022e60048080356000191690602001909190803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509190803560001916906020019091905050610ba2565b604051808215151515815260200191505060405180910390f35b346100005761029d600480803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091905050610dc9565b604051808215151515815260200191505060405180910390f35b6102d1600480803560001916906020019091905050611035565b604051808215151515815260200191505060405180910390f35b346100005761030a60048080356000191690602001909190505061115f565b604051808215151515815260200191505060405180910390f35b346100005761038660048080356000191690602001909190803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091905050611378565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34610000576103e3600480803590602001909190505061140d565b604051808215151515815260200191505060405180910390f35b346100005761043b60048080356000191690602001909190803573ffffffffffffffffffffffffffffffffffffffff169060200190919050506114b4565b604051808215151515815260200191505060405180910390f35b34610000576104626115fb565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b346100005761050660048080356000191690602001909190803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091905050611621565b60405180826000191660001916815260200191505060405180910390f35b34610000576105436004808035600019169060200190919050506116b2565b604051808215151515815260200191505060405180910390f35b346100005761056a611715565b604051808215151515815260200191505060405180910390f35b34610000576105f8600480803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509190803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050611824565b604051808215151515815260200191505060405180910390f35b3461000057610631600480803560001916906020019091905050611d8b565b604051808215151515815260200191505060405180910390f35b34610000576106ad60048080356000191690602001909190803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091905050611dee565b6040518082815260200191505060405180910390f35b34610000576106d0611e83565b6040518082815260200191505060405180910390f35b3461000057610705600480803560001916906020019091905050611e89565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3461000057610766600480803560001916906020019091905050611ed2565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34610000576107d9600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050611f1b565b6040518080602001828103825283818151815260200191508051906020019080838360008314610828575b80518252602083111561082857602082019150602081019050602083039250610804565b505050905090810190601f1680156108545780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34610000576108cd60048080356000191690602001909190803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509190803590602001909190505061200c565b604051808215151515815260200191505060405180910390f35b346100005761095b600480803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509190803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050612236565b604051808215151515815260200191505060405180910390f35b3461000057610982612425565b005b3461000057610a0560048080356000191690602001909190803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509190803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050612698565b604051808215151515815260200191505060405180910390f35b60006000600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020805460018160011615610100020316600290049050141590505b919050565b600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610add57610b9f565b8073ffffffffffffffffffffffffffffffffffffffff16600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f70aea8d848e8a90fb7661b227dc522eb6395c3dac71b63cb59edd5c9899b236460405180905060405180910390a380600060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b5b50565b6000833373ffffffffffffffffffffffffffffffffffffffff1660016000836000191660001916815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16141515610c1d57610dc1565b82600160008760001916600019168152602001908152602001600020600201856040518082805190602001908083835b60208310610c705780518252602082019150602081019050602083039250610c4d565b6001836020036101000a03801982511681845116808217855250505050505090500191505090815260200160405180910390208160001916905550836040518082805190602001908083835b60208310610cdf5780518252602082019150602081019050602083039250610cbc565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051809103902085600019167fb829c3e412537bbe794c048ccb9e4605bb4aaaa8e4d4c15c1a6e0c2adc1716ea866040518080602001828103825283818151815260200191508051906020019080838360008314610d82575b805182526020831115610d8257602082019150602081019050602083039250610d5e565b505050905090810190601f168015610dae5780820380516001836020036101000a031916815260200191505b509250505060405180910390a3600191505b5b509392505050565b6000813373ffffffffffffffffffffffffffffffffffffffff1660016000836040518082805190602001908083835b60208310610e1b5780518252602082019150602081019050602083039250610df8565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405180910390206000191660001916815260200190815260200160002060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16141515610ea45761102f565b82600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209080519060200190828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10610f2d57805160ff1916838001178555610f5b565b82800160010185558215610f5b579182015b82811115610f5a578251825591602001919060010190610f3f565b5b509050610f8091905b80821115610f7c576000816000905550600101610f64565b5090565b50503373ffffffffffffffffffffffffffffffffffffffff16836040518082805190602001908083835b60208310610fcd5780518252602082019150602081019050602083039250610faa565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405180910390207f098ae8581bb8bd9af1beaf7f2e9f51f31a8e5a8bfada4e303a645d71d9c9192060405180905060405180910390a3600191505b5b50919050565b600081600060016000836000191660001916815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614151561109b57611159565b6003543410156110aa57611158565b3360016000856000191660001916815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055503373ffffffffffffffffffffffffffffffffffffffff1683600019167f4963513eca575aba66fdcd25f267aae85958fe6fb97e75fa25d783f1a091a22160405180905060405180910390a3600191505b5b5b50919050565b6000813373ffffffffffffffffffffffffffffffffffffffff1660016000836000191660001916815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415156111da57611372565b6002600060016000866000191660001916815260200190815260200160002060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020805460018160011615610100020316600290046000825580601f1061127c57506112b3565b601f0160209004906000526020600020908101906112b291905b808211156112ae576000816000905550600101611296565b5090565b5b5060016000846000191660001916815260200190815260200160002060006000820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905550503373ffffffffffffffffffffffffffffffffffffffff1683600019167fef1961b4d2909dc23643b309bfe5c3e5646842d98c3a58517037ef3871185af360405180905060405180910390a3600191505b5b50919050565b6000600160008460001916600019168152602001908152602001600020600201826040518082805190602001908083835b602083106113cc57805182526020820191506020810190506020830392506113a9565b6001836020036101000a0380198251168184511680821785525050505050509050019150509081526020016040518091039020546001900490505b92915050565b6000600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561146b576114af565b816003819055507f6bbc57480a46553fa4d156ce702beef5f3ad66303b0ed1a5d4cb44966c6584c3826040518082815260200191505060405180910390a1600190505b5b919050565b6000823373ffffffffffffffffffffffffffffffffffffffff1660016000836000191660001916815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614151561152f576115f4565b8260016000866000191660001916815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1685600019167f7b97c62130aa09acbbcbf7482630e756592496f1759eaf702f469cf64dfb779460405180905060405180910390a4600191505b5b5092915050565b600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000600160008460001916600019168152602001908152602001600020600201826040518082805190602001908083835b602083106116755780518252602082019150602081019050602083039250611652565b6001836020036101000a03801982511681845116808217855250505050505090500191505090815260200160405180910390205490505b92915050565b6000600060016000846000191660001916815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16141590505b919050565b6000600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561177357611821565b7fdef931299fe61d176f949118058530c1f3f539dcb6950b4e372c9b835c33ca073073ffffffffffffffffffffffffffffffffffffffff16316040518082815260200191505060405180910390a13373ffffffffffffffffffffffffffffffffffffffff166108fc3073ffffffffffffffffffffffffffffffffffffffff16319081150290604051809050600060405180830381858888f19350505050151561181b57610000565b600190505b5b90565b60006000836040518082805190602001908083835b6020831061185c5780518252602082019150602081019050602083039250611839565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405180910390203373ffffffffffffffffffffffffffffffffffffffff1660016000836000191660001916815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614151561190157611d83565b846040518082805190602001908083835b602083106119355780518252602082019150602081019050602083039250611912565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405180910390209150600060016000846000191660001916815260200190815260200160002060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614158015611ab4575081600019166002600060016000866000191660001916815260200190815260200160002060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206040518082805460018160011615610100020316600290048015611aa15780601f10611a7f576101008083540402835291820191611aa1565b820191906000526020600020905b815481529060010190602001808311611a8d575b5050915050604051809103902060001916145b15611c79576002600060016000856000191660001916815260200190815260200160002060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020805460018160011615610100020316600290046000825580601f10611b5b5750611b92565b601f016020900490600052602060002090810190611b9191905b80821115611b8d576000816000905550600101611b75565b5090565b5b5060016000836000191660001916815260200190815260200160002060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16856040518082805190602001908083835b60208310611c1c5780518252602082019150602081019050602083039250611bf9565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405180910390207f12491ad95fd945e444d88a894ffad3c21959880a4dcd8af99d4ae4ffc71d4abd60405180905060405180910390a35b8360016000846000191660001916815260200190815260200160002060010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508373ffffffffffffffffffffffffffffffffffffffff16856040518082805190602001908083835b60208310611d215780518252602082019150602081019050602083039250611cfe565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405180910390207f728435a0031f6a04538fcdd24922a7e06bc7bc945db03e83d22122d1bc5f28df60405180905060405180910390a3600192505b5b505092915050565b6000600060016000846000191660001916815260200190815260200160002060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16141590505b919050565b6000600160008460001916600019168152602001908152602001600020600201826040518082805190602001908083835b60208310611e425780518252602082019150602081019050602083039250611e1f565b6001836020036101000a0380198251168184511680821785525050505050509050019150509081526020016040518091039020546001900490505b92915050565b60035481565b600060016000836000191660001916815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690505b919050565b600060016000836000191660001916815260200190815260200160002060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690505b919050565b6020604051908101604052806000815250600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015611fff5780601f10611fd457610100808354040283529160200191611fff565b820191906000526020600020905b815481529060010190602001808311611fe257829003601f168201915b505050505090505b919050565b6000833373ffffffffffffffffffffffffffffffffffffffff1660016000836000191660001916815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415156120875761222e565b82600102600160008760001916600019168152602001908152602001600020600201856040518082805190602001908083835b602083106120dd57805182526020820191506020810190506020830392506120ba565b6001836020036101000a03801982511681845116808217855250505050505090500191505090815260200160405180910390208160001916905550836040518082805190602001908083835b6020831061214c5780518252602082019150602081019050602083039250612129565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051809103902085600019167fb829c3e412537bbe794c048ccb9e4605bb4aaaa8e4d4c15c1a6e0c2adc1716ea8660405180806020018281038252838181518152602001915080519060200190808383600083146121ef575b8051825260208311156121ef576020820191506020810190506020830392506121cb565b505050905090810190601f16801561221b5780820380516001836020036101000a031916815260200191505b509250505060405180910390a3600191505b5b509392505050565b6000600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156122945761241f565b82600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209080519060200190828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061231d57805160ff191683800117855561234b565b8280016001018555821561234b579182015b8281111561234a57825182559160200191906001019061232f565b5b50905061237091905b8082111561236c576000816000905550600101612354565b5090565b50508173ffffffffffffffffffffffffffffffffffffffff16836040518082805190602001908083835b602083106123bd578051825260208201915060208101905060208303925061239a565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405180910390207f098ae8581bb8bd9af1beaf7f2e9f51f31a8e5a8bfada4e303a645d71d9c9192060405180905060405180910390a3600190505b5b92915050565b3373ffffffffffffffffffffffffffffffffffffffff16600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060405180828054600181600116156101000203166002900480156124d65780601f106124b45761010080835404028352918201916124d6565b820191906000526020600020905b8154815290600101906020018083116124c2575b505091505060405180910390207f12491ad95fd945e444d88a894ffad3c21959880a4dcd8af99d4ae4ffc71d4abd60405180905060405180910390a360016000600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060405180828054600181600116156101000203166002900480156125b05780601f1061258e5761010080835404028352918201916125b0565b820191906000526020600020905b81548152906001019060200180831161259c575b505091505060405180910390206000191660001916815260200190815260200160002060010160006101000a81549073ffffffffffffffffffffffffffffffffffffffff0219169055600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020805460018160011615610100020316600290046000825580601f1061265d5750612694565b601f01602090049060005260206000209081019061269391905b8082111561268f576000816000905550600101612677565b5090565b5b505b565b6000833373ffffffffffffffffffffffffffffffffffffffff1660016000836000191660001916815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16141515612713576128d0565b8273ffffffffffffffffffffffffffffffffffffffff16600102600160008760001916600019168152602001908152602001600020600201856040518082805190602001908083835b6020831061277f578051825260208201915060208101905060208303925061275c565b6001836020036101000a03801982511681845116808217855250505050505090500191505090815260200160405180910390208160001916905550836040518082805190602001908083835b602083106127ee57805182526020820191506020810190506020830392506127cb565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051809103902085600019167fb829c3e412537bbe794c048ccb9e4605bb4aaaa8e4d4c15c1a6e0c2adc1716ea866040518080602001828103825283818151815260200191508051906020019080838360008314612891575b8051825260208311156128915760208201915060208101905060208303925061286d565b505050905090810190601f1680156128bd5780820380516001836020036101000a031916815260200191505b509250505060405180910390a3600191505b5b5093925050505600a165627a7a7230582066b2da4773a0f1d81efe071c66b51c46868a871661efd18c0f629353ff4c1f9b0029" + }, + "00a329c0648769a73afac7f9381e08fb43dbea72": { + "balance": "1606938044258990275541962092341162602522202993782792835301376" + } + } +} \ No newline at end of file diff --git a/test/blockchain.js b/test/blockchain.js index cdf6570f6..e006d1884 100644 --- a/test/blockchain.js +++ b/test/blockchain.js @@ -1,30 +1,29 @@ /*globals describe, it*/ -const Blockchain = require('../lib/modules/blockchain_process/blockchain.js'); +const Blockchain = require('../lib/modules/blockchain_process/blockchain.js'); const constants = require('../lib/constants.json'); const {defaultHost} = require('../lib/utils/host'); const assert = require('assert'); -describe('embark.Blockchain', function () { - //let Client = function() {}; - //Client.prototype.name = "ClientName"; +describe('embark.Blockchain', function() { - describe('#initializer', function () { - //let client = new Client(); + describe('#initializer', function() { - describe('with empty config', function () { - it('should have a default config', function (done) { - let config = { + describe('with empty config', function() { + it('should have a default config', function(done) { + let blockchain = new Blockchain({}); + let expectedConfig = { networkType: 'custom', genesisBlock: false, - geth_bin: 'geth', + ethereumClientName: 'geth', + ethereumClientBin: 'geth', datadir: false, mineWhenNeeded: false, rpcHost: defaultHost, rpcPort: 8545, rpcApi: ['eth', 'web3', 'net', 'debug'], rpcCorsDomain: false, - networkId: 12301, + networkId: 1337, port: 30303, nodiscover: false, maxpeers: 25, @@ -32,36 +31,35 @@ describe('embark.Blockchain', function () { vmdebug: false, whisper: true, account: {}, + devPassword: "", bootnodes: "", - wsApi: ["eth", "web3", "net", "shh", "debug"], + wsApi: ["eth", "web3", "net", "shh", "debug", "pubsub"], wsHost: defaultHost, wsOrigins: false, wsPort: 8546, wsRPC: true, targetGasLimit: false, - syncmode: undefined, syncMode: undefined, - syncmode: undefined, verbosity: undefined, - proxy: true + proxy: true, + silent: undefined }; - let blockchain = new Blockchain(config, 'geth'); + // We check also proxy's ports because proxy is set to true + expectedConfig.wsPort += constants.blockchain.servicePortOnProxy; + expectedConfig.rpcPort += constants.blockchain.servicePortOnProxy; - if(config.proxy){ - config.wsPort += constants.blockchain.servicePortOnProxy; - config.rpcPort += constants.blockchain.servicePortOnProxy; - } - assert.deepEqual(blockchain.config, config); + assert.deepEqual(blockchain.config, expectedConfig); done(); }); }); - describe('with config', function () { - it('should take config params', function (done) { + describe('with config', function() { + it('should take config params', function(done) { let config = { networkType: 'livenet', genesisBlock: 'foo/bar/genesis.json', - geth_bin: 'geth', + ethereumClientName: 'parity', + ethereumClientBin: 'parity', datadir: '/foo/datadir/', mineWhenNeeded: true, rpcHost: defaultHost, @@ -76,6 +74,7 @@ describe('embark.Blockchain', function () { vmdebug: false, whisper: false, account: {}, + devPassword: "foo/bar/devpassword", bootnodes: "", wsApi: ["eth", "web3", "net", "shh", "debug"], wsHost: defaultHost, @@ -84,18 +83,48 @@ describe('embark.Blockchain', function () { wsRPC: true, targetGasLimit: false, syncMode: undefined, - syncmode: undefined, verbosity: undefined, proxy: true }; - let blockchain = new Blockchain(config, 'geth'); + let blockchain = new Blockchain(config); - if(config.proxy){ - config.wsPort += constants.blockchain.servicePortOnProxy; - config.rpcPort += constants.blockchain.servicePortOnProxy; - } + let expectedConfig = { + networkType: 'livenet', + genesisBlock: 'foo/bar/genesis.json', + ethereumClientName: 'parity', + ethereumClientBin: 'parity', + datadir: '/foo/datadir/', + mineWhenNeeded: true, + rpcHost: defaultHost, + rpcPort: 12345, + rpcApi: ['eth', 'web3', 'net', 'debug'], + rpcCorsDomain: true, + networkId: 1, + port: 123456, + nodiscover: true, + maxpeers: 25, + mine: true, + vmdebug: false, + whisper: false, + account: {}, + devPassword: "foo/bar/devpassword", + bootnodes: "", + wsApi: ["eth", "web3", "net", "shh", "debug"], + wsHost: defaultHost, + wsOrigins: false, + wsPort: 12346, + wsRPC: true, + targetGasLimit: false, + syncMode: undefined, + verbosity: undefined, + proxy: true, + silent: undefined + }; + // We check also proxy's ports because proxy is set to true + expectedConfig.wsPort += constants.blockchain.servicePortOnProxy; + expectedConfig.rpcPort += constants.blockchain.servicePortOnProxy; - assert.deepEqual(blockchain.config, config); + assert.deepEqual(blockchain.config, expectedConfig); done(); }); }); diff --git a/test/devFunds.js b/test/devFunds.js index 5cf14d9ff..3dc10bcfc 100644 --- a/test/devFunds.js +++ b/test/devFunds.js @@ -10,7 +10,7 @@ const FakeIpcProvider = require('./helpers/fakeIpcProvider'); const utils = require('../lib/utils/utils'); i18n.setOrDetectLocale('en'); -describe('embark.DevFunds', function () { +describe('embark.DevFunds', function() { let config = { networkType: 'livenet', genesisBlock: 'foo/bar/genesis.json', @@ -41,7 +41,6 @@ describe('embark.DevFunds', function () { wsRPC: true, targetGasLimit: false, syncMode: undefined, - syncmode: undefined, verbosity: undefined, proxy: true }; @@ -51,7 +50,7 @@ describe('embark.DevFunds', function () { config.rpcPort += constants.blockchain.servicePortOnProxy; } - describe('#create, fund, and unlock accounts', function () { + describe('#create, fund, and unlock accounts', function() { let provider = new FakeIpcProvider(); const web3 = new Web3(provider); let devFunds; @@ -61,7 +60,8 @@ describe('embark.DevFunds', function () { devFunds = await DevFunds.new({blockchainConfig: config, provider: provider, logger: new TestLogger({})}); }); - it('should create correct number of accounts', function (done) { + // TOCHECK: DevFunds does not provide this function anymore, please consider to remove this test + it('should create correct number of accounts', function(done) { provider.injectResult('0x11f4d0a3c12e86b4b5f39b213f7e19d048276dae'); // createAccount #1 provider.injectResult('0x22f4d0a3c12e86b4b5f39b213f7e19d048276dab'); // createAccount #2 @@ -81,7 +81,8 @@ describe('embark.DevFunds', function () { }); }); - it('should unlock accounts', function (done) { + // TOCHECK: DevFunds does not provide this function anymore, please consider to remove this test + it('should unlock accounts', function(done) { if (devFunds.accounts.length === 0) { assert.equal(true, true, "no accounts to unlock"); return done(); @@ -97,7 +98,7 @@ describe('embark.DevFunds', function () { }); }); - it('should fund accounts', function (done) { + it('should fund accounts', function(done) { if (devFunds.accounts.length === 0) { assert.equal(true, true, "no accounts to fund"); @@ -108,7 +109,7 @@ describe('embark.DevFunds', function () { // provider.injectResult('0x11f4d0A3c12e86B4b5F39B213F7E19D048276DAe'); // send tx response }); - devFunds.fundAccounts(devFunds.balance, (errFundAccounts) => { + devFunds.fundAccounts(false, (errFundAccounts) => { assert.equal(errFundAccounts, null); @@ -136,7 +137,7 @@ describe('embark.DevFunds', function () { cb(); }).catch(cb); - }, function (errAcctsBalance) { + }, function(errAcctsBalance) { if (errAcctsBalance) throw errAcctsBalance; done(); }); diff --git a/test_apps/test_app/package-lock.json b/test_apps/test_app/package-lock.json index dd65a50ed..024d5dcc9 100644 --- a/test_apps/test_app/package-lock.json +++ b/test_apps/test_app/package-lock.json @@ -19,9 +19,9 @@ "integrity": "sha512-5PgPDV6F5s69XNznTcP0za3qH7qgBkr9DVQTXfZtpF+3iEyuIZB1Mjxu52F5CFxgzQUQJoBYHVxtH4Itdb5MgA==", "dev": true, "requires": { - "chalk": "2.4.1", - "esutils": "2.0.2", - "js-tokens": "3.0.2" + "chalk": "^2.0.0", + "esutils": "^2.0.2", + "js-tokens": "^3.0.0" }, "dependencies": { "js-tokens": { @@ -38,7 +38,7 @@ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, "requires": { - "color-convert": "1.9.2" + "color-convert": "^1.9.0" } }, "asap": { @@ -51,8 +51,8 @@ "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "requires": { - "core-js": "2.5.7", - "regenerator-runtime": "0.11.1" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" }, "dependencies": { "core-js": { @@ -73,9 +73,9 @@ "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", "dev": true, "requires": { - "ansi-styles": "3.2.1", - "escape-string-regexp": "1.0.5", - "supports-color": "5.4.0" + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" } }, "classnames": { @@ -111,7 +111,7 @@ "embark-service": { "version": "file:extensions/embark-service", "requires": { - "haml": "0.4.3" + "haml": "^0.4.3" } }, "encoding": { @@ -119,7 +119,7 @@ "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz", "integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=", "requires": { - "iconv-lite": "0.4.23" + "iconv-lite": "~0.4.13" } }, "escape-string-regexp": { @@ -139,13 +139,13 @@ "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-0.8.17.tgz", "integrity": "sha1-xNWY6taUkRJlPWWIsBpc3Nn5D90=", "requires": { - "core-js": "1.2.7", - "isomorphic-fetch": "2.2.1", - "loose-envify": "1.4.0", - "object-assign": "4.1.1", - "promise": "7.3.1", - "setimmediate": "1.0.5", - "ua-parser-js": "0.7.18" + "core-js": "^1.0.0", + "isomorphic-fetch": "^2.1.1", + "loose-envify": "^1.0.0", + "object-assign": "^4.1.0", + "promise": "^7.1.1", + "setimmediate": "^1.0.5", + "ua-parser-js": "^0.7.18" } }, "haml": { @@ -164,7 +164,7 @@ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz", "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==", "requires": { - "safer-buffer": "2.1.2" + "safer-buffer": ">= 2.1.2 < 3" } }, "invariant": { @@ -172,7 +172,7 @@ "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", "requires": { - "loose-envify": "1.4.0" + "loose-envify": "^1.0.0" } }, "is-stream": { @@ -185,8 +185,8 @@ "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz", "integrity": "sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk=", "requires": { - "node-fetch": "1.7.3", - "whatwg-fetch": "2.0.4" + "node-fetch": "^1.0.1", + "whatwg-fetch": ">=0.10.0" } }, "jquery": { @@ -209,7 +209,7 @@ "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", "requires": { - "js-tokens": "4.0.0" + "js-tokens": "^3.0.0 || ^4.0.0" } }, "node-fetch": { @@ -217,8 +217,8 @@ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz", "integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==", "requires": { - "encoding": "0.1.12", - "is-stream": "1.1.0" + "encoding": "^0.1.11", + "is-stream": "^1.0.1" } }, "object-assign": { @@ -231,7 +231,7 @@ "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", "requires": { - "asap": "2.0.6" + "asap": "~2.0.3" } }, "prop-types": { @@ -239,8 +239,8 @@ "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.6.2.tgz", "integrity": "sha512-3pboPvLiWD7dkI3qf3KbUe6hKFKa52w+AE0VCqECtf+QHAKgOL37tTaNCnuX1nAAQ4ZhyP+kYVKf8rLmJ/feDQ==", "requires": { - "loose-envify": "1.4.0", - "object-assign": "4.1.1" + "loose-envify": "^1.3.1", + "object-assign": "^4.1.1" } }, "prop-types-extra": { @@ -248,8 +248,8 @@ "resolved": "https://registry.npmjs.org/prop-types-extra/-/prop-types-extra-1.1.0.tgz", "integrity": "sha512-QFyuDxvMipmIVKD2TwxLVPzMnO4e5oOf1vr3tJIomL8E7d0lr6phTHd5nkPhFIzTD1idBLLEPeylL9g+rrTzRg==", "requires": { - "react-is": "16.4.2", - "warning": "3.0.0" + "react-is": "^16.3.2", + "warning": "^3.0.0" } }, "react": { @@ -257,10 +257,10 @@ "resolved": "https://registry.npmjs.org/react/-/react-16.4.2.tgz", "integrity": "sha512-dMv7YrbxO4y2aqnvA7f/ik9ibeLSHQJTI6TrYAenPSaQ6OXfb+Oti+oJiy8WBxgRzlKatYqtCjphTgDSCEiWFg==", "requires": { - "fbjs": "0.8.17", - "loose-envify": "1.4.0", - "object-assign": "4.1.1", - "prop-types": "15.6.2" + "fbjs": "^0.8.16", + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1", + "prop-types": "^15.6.0" } }, "react-bootstrap": { @@ -268,18 +268,18 @@ "resolved": "https://registry.npmjs.org/react-bootstrap/-/react-bootstrap-0.32.1.tgz", "integrity": "sha512-RbfzKUbsukWsToWqGHfCCyMFq9QQI0TznutdyxyJw6dih2NvIne25Mrssg8LZsprqtPpyQi8bN0L0Fx3fUsL8Q==", "requires": { - "babel-runtime": "6.26.0", - "classnames": "2.2.6", - "dom-helpers": "3.3.1", - "invariant": "2.2.4", - "keycode": "2.2.0", - "prop-types": "15.6.2", - "prop-types-extra": "1.1.0", - "react-overlays": "0.8.3", - "react-prop-types": "0.4.0", - "react-transition-group": "2.4.0", - "uncontrollable": "4.1.0", - "warning": "3.0.0" + "babel-runtime": "^6.11.6", + "classnames": "^2.2.5", + "dom-helpers": "^3.2.0", + "invariant": "^2.2.1", + "keycode": "^2.1.2", + "prop-types": "^15.5.10", + "prop-types-extra": "^1.0.1", + "react-overlays": "^0.8.0", + "react-prop-types": "^0.4.0", + "react-transition-group": "^2.0.0", + "uncontrollable": "^4.1.0", + "warning": "^3.0.0" } }, "react-dom": { @@ -287,10 +287,10 @@ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.4.2.tgz", "integrity": "sha512-Usl73nQqzvmJN+89r97zmeUpQDKDlh58eX6Hbs/ERdDHzeBzWy+ENk7fsGQ+5KxArV1iOFPT46/VneklK9zoWw==", "requires": { - "fbjs": "0.8.17", - "loose-envify": "1.4.0", - "object-assign": "4.1.1", - "prop-types": "15.6.2" + "fbjs": "^0.8.16", + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1", + "prop-types": "^15.6.0" } }, "react-is": { @@ -308,12 +308,12 @@ "resolved": "https://registry.npmjs.org/react-overlays/-/react-overlays-0.8.3.tgz", "integrity": "sha512-h6GT3jgy90PgctleP39Yu3eK1v9vaJAW73GOA/UbN9dJ7aAN4BTZD6793eI1D5U+ukMk17qiqN/wl3diK1Z5LA==", "requires": { - "classnames": "2.2.6", - "dom-helpers": "3.3.1", - "prop-types": "15.6.2", - "prop-types-extra": "1.1.0", - "react-transition-group": "2.4.0", - "warning": "3.0.0" + "classnames": "^2.2.5", + "dom-helpers": "^3.2.1", + "prop-types": "^15.5.10", + "prop-types-extra": "^1.0.1", + "react-transition-group": "^2.2.0", + "warning": "^3.0.0" } }, "react-prop-types": { @@ -321,7 +321,7 @@ "resolved": "https://registry.npmjs.org/react-prop-types/-/react-prop-types-0.4.0.tgz", "integrity": "sha1-+ZsL+0AGkpya8gUefBQUpcdbk9A=", "requires": { - "warning": "3.0.0" + "warning": "^3.0.0" } }, "react-transition-group": { @@ -329,10 +329,10 @@ "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-2.4.0.tgz", "integrity": "sha512-Xv5d55NkJUxUzLCImGSanK8Cl/30sgpOEMGc5m86t8+kZwrPxPCPcFqyx83kkr+5Lz5gs6djuvE5By+gce+VjA==", "requires": { - "dom-helpers": "3.3.1", - "loose-envify": "1.4.0", - "prop-types": "15.6.2", - "react-lifecycles-compat": "3.0.4" + "dom-helpers": "^3.3.1", + "loose-envify": "^1.3.1", + "prop-types": "^15.6.2", + "react-lifecycles-compat": "^3.0.4" } }, "regenerator-runtime": { @@ -356,7 +356,7 @@ "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", "dev": true, "requires": { - "has-flag": "3.0.0" + "has-flag": "^3.0.0" } }, "ua-parser-js": { @@ -369,7 +369,7 @@ "resolved": "https://registry.npmjs.org/uncontrollable/-/uncontrollable-4.1.0.tgz", "integrity": "sha1-4DWCkSUuGGUiLZCTmxny9J+Bwak=", "requires": { - "invariant": "2.2.4" + "invariant": "^2.1.0" } }, "warning": { @@ -377,7 +377,7 @@ "resolved": "https://registry.npmjs.org/warning/-/warning-3.0.0.tgz", "integrity": "sha1-MuU3fLVy3kqwR1O9+IIcAe1gW3w=", "requires": { - "loose-envify": "1.4.0" + "loose-envify": "^1.0.0" } }, "whatwg-fetch": {