From 668fd3a0647ae48c3de06b2a93b5955efde48d7c Mon Sep 17 00:00:00 2001 From: Jonathan Rainville Date: Thu, 17 May 2018 13:12:54 -0400 Subject: [PATCH 01/13] add fundAccount script that keeps the user's account funded --- js/fundAccount.js | 52 ++++++++++++++++++++++++++++ lib/cmds/blockchain/blockchain.js | 5 ++- lib/cmds/blockchain/geth_commands.js | 6 ++++ 3 files changed, 60 insertions(+), 3 deletions(-) create mode 100644 js/fundAccount.js diff --git a/js/fundAccount.js b/js/fundAccount.js new file mode 100644 index 00000000..ee17938f --- /dev/null +++ b/js/fundAccount.js @@ -0,0 +1,52 @@ +/*global web3, eth*/ + +(function () { + + var workAccount = '0xDf18Cb4F2005Bc52F94E9BD6C31f7B0C6394E2C2'; + + // Blockchain process ends if Javascript ends + function keepAlive() { + setInterval(function () { + // Do nothing + }, 999999); + } + + var workAccountBalance = eth.getBalance(workAccount); + var TARGET = 15000000000000000000; + if (workAccountBalance >= TARGET) { + return keepAlive(); + } + + function getNonce() { + return web3.eth.getTransactionCount(eth.coinbase); + } + + function getGasPrice() { + return web3.eth.getGasPrice(); + } + + function sendTransaction(nonce, gasPrice) { + web3.eth.sendTransaction({ + from: eth.coinbase, + to: workAccount, + value: TARGET - workAccountBalance, + gasPrice: gasPrice, + nonce: nonce + }, function (err, _result) { + if (err) { + console.error('Error while transferring funds to user account', err); + } + }); + } + + try { + var nonce = getNonce(); + var gasPrice = getGasPrice(); + sendTransaction(nonce, gasPrice); + } catch (e) { + console.error('Error while getting nonce or gas price', e); + } + + + keepAlive(); +})(); diff --git a/lib/cmds/blockchain/blockchain.js b/lib/cmds/blockchain/blockchain.js index 4bbb68eb..840fa30b 100644 --- a/lib/cmds/blockchain/blockchain.js +++ b/lib/cmds/blockchain/blockchain.js @@ -77,6 +77,8 @@ Blockchain.prototype.run = function() { return; } let address = ''; + // copy mining script + fs.copySync(fs.embarkPath("js"), ".embark/" + this.env + "/js", {overwrite: true}); if (!this.isDev) { address = this.initChainAndGetAddress(); } @@ -102,9 +104,6 @@ Blockchain.prototype.initChainAndGetAddress = function() { this.datadir = '.embark/' + this.env + '/datadir'; fs.mkdirpSync(this.datadir); - // copy mining script - fs.copySync(fs.embarkPath("js"), ".embark/" + this.env + "/js", {overwrite: true}); - // check if an account already exists, create one if not, return address result = this.runCommand(this.client.listAccountsCommand()); if (result.output === undefined || result.output.match(/{(\w+)}/) === null || result.output.indexOf("Fatal") >= 0) { diff --git a/lib/cmds/blockchain/geth_commands.js b/lib/cmds/blockchain/geth_commands.js index 379bf54e..7f08f755 100644 --- a/lib/cmds/blockchain/geth_commands.js +++ b/lib/cmds/blockchain/geth_commands.js @@ -206,6 +206,12 @@ class GethCommands { } callback(null, ""); }, + function fundAccount(callback) { + if (self.isDev) { // TODO add config param? + return callback(null, "js .embark/" + self.env + "/js/fundAccount.js"); + } + callback(null, ""); + }, function isDev(callback) { if (self.isDev) { return callback(null, '--dev'); From c3c4518cb4c108ba3e9decf3625acb29f4f4ca76 Mon Sep 17 00:00:00 2001 From: Jonathan Rainville Date: Thu, 17 May 2018 13:48:39 -0400 Subject: [PATCH 02/13] move account parsing to its own module --- lib/contracts/accountParser.js | 66 ++++++++++++++++++++++++++++ lib/contracts/provider.js | 78 +++++----------------------------- 2 files changed, 77 insertions(+), 67 deletions(-) create mode 100644 lib/contracts/accountParser.js diff --git a/lib/contracts/accountParser.js b/lib/contracts/accountParser.js new file mode 100644 index 00000000..139f3c7c --- /dev/null +++ b/lib/contracts/accountParser.js @@ -0,0 +1,66 @@ +const bip39 = require("bip39"); +const hdkey = require('ethereumjs-wallet/hdkey'); +const fs = require('../core/fs'); + + +class AccountParser { + static parseAccountsConfig(accountsConfig, web3, logger) { + let accounts = []; + if (accountsConfig && accountsConfig.length) { + accountsConfig.forEach(accountConfig => { + const account = AccountParser.getAccount(accountConfig, web3, logger); + if (!account) { + return; + } + if (Array.isArray(account)) { + accounts = accounts.concat(account); + return; + } + accounts.push(account); + }); + } + return accounts; + } + + static getAccount(accountConfig, web3, logger) { + if (!logger) { + logger = console; + } + if (accountConfig.privateKey) { + if (!accountConfig.privateKey.startsWith('0x')) { + accountConfig.privateKey = '0x' + accountConfig.privateKey; + } + return web3.eth.accounts.privateKeyToAccount(accountConfig.privateKey); + } + if (accountConfig.privateKeyFile) { + let fileContent = fs.readFileSync(fs.dappPath(accountConfig.privateKeyFile)).toString(); + fileContent = fileContent.trim().split(/[,;]/); + return fileContent.map(key => { + if (!key.startsWith('0x')) { + key = '0x' + key; + } + return web3.eth.accounts.privateKeyToAccount(key); + }); + } + if (accountConfig.mnemonic) { + const hdwallet = hdkey.fromMasterSeed(bip39.mnemonicToSeed(accountConfig.mnemonic.trim())); + + const addressIndex = accountConfig.addressIndex || 0; + const numAddresses = accountConfig.numAddresses || 1; + const wallet_hdpath = accountConfig.hdpath || "m/44'/60'/0'/0/"; + + const accounts = []; + for (let i = addressIndex; i < addressIndex + numAddresses; i++) { + const wallet = hdwallet.derivePath(wallet_hdpath + i).getWallet(); + accounts.push(web3.eth.accounts.privateKeyToAccount('0x' + wallet.getPrivateKey().toString('hex'))); + } + return accounts; + } + logger.warn('Unsupported account configuration: ' + JSON.stringify(accountConfig)); + logger.warn('Try using one of those: ' + + '{ "privateKey": "your-private-key", "privateKeyFile": "path/to/file/containing/key", "mnemonic": "12 word mnemonic" }'); + return null; + } +} + +module.exports = AccountParser; diff --git a/lib/contracts/provider.js b/lib/contracts/provider.js index a5225f0e..4f89b0e2 100644 --- a/lib/contracts/provider.js +++ b/lib/contracts/provider.js @@ -1,8 +1,6 @@ const ProviderEngine = require('web3-provider-engine'); const RpcSubprovider = require('web3-provider-engine/subproviders/rpc.js'); -const bip39 = require("bip39"); -const hdkey = require('ethereumjs-wallet/hdkey'); -const fs = require('../core/fs'); +const AccountParser = require('./accountParser'); class Provider { constructor(options) { @@ -18,35 +16,18 @@ class Provider { rpcUrl: options.web3Endpoint })); - if (this.accountsConfig && this.accountsConfig.length) { - this.accounts = []; - this.addresses = []; - this.accountsConfig.forEach(accountConfig => { - const account = this.getAccount(accountConfig); - if (!account) { - return; - } - if (Array.isArray(account)) { - this.accounts = this.accounts.concat(account); - account.forEach(acc => { - this.addresses.push(acc.address); - }); - return; - } - this.accounts.push(account); + this.accounts = AccountParser.parseAccountsConfig(this.accountsConfig, this.web3, this.logger); + this.addresses = []; + if (this.accounts.length) { + this.accounts.forEach(account => { this.addresses.push(account.address); + this.web3.eth.accounts.wallet.add(account); }); - - if (this.accounts.length) { - this.accounts.forEach(account => { - this.web3.eth.accounts.wallet.add(account); - }); - this.asyncMethods = { - eth_accounts: self.eth_accounts.bind(this) - }; - if (this.isDev) { - this.logger.warn('You are using your own account in the develop environment. It might not be funded.'); - } + this.asyncMethods = { + eth_accounts: self.eth_accounts.bind(this) + }; + if (this.isDev) { + this.logger.warn('You are using your own account in the develop environment. It might not be funded.'); } } @@ -58,43 +39,6 @@ class Provider { this.engine.start(); } - getAccount(accountConfig) { - if (accountConfig.privateKey) { - if (!accountConfig.privateKey.startsWith('0x')) { - accountConfig.privateKey = '0x' + accountConfig.privateKey; - } - return this.web3.eth.accounts.privateKeyToAccount(accountConfig.privateKey); - } - if (accountConfig.privateKeyFile) { - let fileContent = fs.readFileSync(fs.dappPath(accountConfig.privateKeyFile)).toString(); - fileContent = fileContent.trim().split(/[,;]/); - return fileContent.map(key => { - if (!key.startsWith('0x')) { - key = '0x' + key; - } - return this.web3.eth.accounts.privateKeyToAccount(key); - }); - } - if (accountConfig.mnemonic) { - const hdwallet = hdkey.fromMasterSeed(bip39.mnemonicToSeed(accountConfig.mnemonic.trim())); - - const addressIndex = accountConfig.addressIndex || 0; - const numAddresses = accountConfig.numAddresses || 1; - const wallet_hdpath = accountConfig.hdpath || "m/44'/60'/0'/0/"; - - const accounts = []; - for (let i = addressIndex; i < addressIndex + numAddresses; i++) { - const wallet = hdwallet.derivePath(wallet_hdpath + i).getWallet(); - accounts.push(this.web3.eth.accounts.privateKeyToAccount('0x' + wallet.getPrivateKey().toString('hex'))); - } - return accounts; - } - this.logger.warn('Unsupported account configuration: ' + JSON.stringify(accountConfig)); - this.logger.warn('Try using one of those: ' + - '{ "privateKey": "your-private-key", "privateKeyFile": "path/to/file/containing/key", "mnemonic": "12 word mnemonic" }'); - return null; - } - eth_accounts(payload, cb) { return cb(null, this.addresses); } From 59c4456206a1a00229578a14ea5e9aec2d1ceacb Mon Sep 17 00:00:00 2001 From: Jonathan Rainville Date: Thu, 17 May 2018 13:52:09 -0400 Subject: [PATCH 03/13] move provide rtests to accountParser tests --- test/{provider.js => accountParser.js} | 55 +++++++++++--------------- 1 file changed, 22 insertions(+), 33 deletions(-) rename test/{provider.js => accountParser.js} (64%) diff --git a/test/provider.js b/test/accountParser.js similarity index 64% rename from test/provider.js rename to test/accountParser.js index 1fc0ebbf..f6e6e79d 100644 --- a/test/provider.js +++ b/test/accountParser.js @@ -1,44 +1,34 @@ -/*global describe, it, before*/ +/*global describe, it*/ const assert = require('assert'); const sinon = require('sinon'); -const Provider = require('../lib/contracts/provider'); +const AccountParser = require('../lib/contracts/accountParser'); let TestLogger = require('../lib/tests/test_logger.js'); -describe('embark.provider', function () { +describe('embark.AccountParser', function () { describe('#getAccount', function () { - let provider; - - before(() => { - const web3 = { - eth: { - accounts: { - privateKeyToAccount: sinon.stub().callsFake((key) => { - return {key}; - }) - } + const web3 = { + eth: { + accounts: { + privateKeyToAccount: sinon.stub().callsFake((key) => { + return {key}; + }) } - }; - - provider = new Provider({ - accountsConfig: [], - logger: new TestLogger({}), - web3Endpoint: 'http:localhost:555', - web3 - }); - }); + } + }; + const testLogger = new TestLogger({}); it('should return one account with the key', function () { - const account = provider.getAccount({ + const account = AccountParser.getAccount({ privateKey: 'myKey' - }); + }, web3, testLogger); assert.deepEqual(account, {key: '0xmyKey'}); }); it('should return two accounts from the keys in the file', function () { - const account = provider.getAccount({ + const account = AccountParser.getAccount({ privateKeyFile: 'test/keyFiles/twoKeys' - }); + }, web3, testLogger); assert.deepEqual(account, [ {key: '0xkey1'}, @@ -47,20 +37,19 @@ describe('embark.provider', function () { }); it('should return one account from the mnemonic', function () { - const account = provider.getAccount({ + const account = AccountParser.getAccount({ mnemonic: 'example exile argue silk regular smile grass bomb merge arm assist farm' - }); - + }, web3, testLogger); assert.deepEqual(account, [{key: "0xf942d5d524ec07158df4354402bfba8d928c99d0ab34d0799a6158d56156d986"}]); }); it('should return two accounts from the mnemonic using numAddresses', function () { - const account = provider.getAccount({ + const account = AccountParser.getAccount({ mnemonic: 'example exile argue silk regular smile grass bomb merge arm assist farm', numAddresses: 2 - }); + }, web3, testLogger); assert.deepEqual(account, [ @@ -70,9 +59,9 @@ describe('embark.provider', function () { }); it('should return nothing with bad config', function () { - const account = provider.getAccount({ + const account = AccountParser.getAccount({ badConfig: 'not working' - }); + }, web3, testLogger); assert.strictEqual(account, null); }); From 94f0d98e28d9127d8c51f3177c9f5ae9f846a77f Mon Sep 17 00:00:00 2001 From: Jonathan Rainville Date: Thu, 17 May 2018 15:32:57 -0400 Subject: [PATCH 04/13] get accounts and generate script with the right address --- js/fundAccount.js | 52 -------------------------- lib/cmds/blockchain/blockchain.js | 13 ++++--- lib/cmds/blockchain/fundAccout.js.ejs | 53 +++++++++++++++++++++++++++ lib/cmds/blockchain/geth_commands.js | 22 +++++++++-- lib/index.js | 2 +- 5 files changed, 81 insertions(+), 61 deletions(-) delete mode 100644 js/fundAccount.js create mode 100644 lib/cmds/blockchain/fundAccout.js.ejs diff --git a/js/fundAccount.js b/js/fundAccount.js deleted file mode 100644 index ee17938f..00000000 --- a/js/fundAccount.js +++ /dev/null @@ -1,52 +0,0 @@ -/*global web3, eth*/ - -(function () { - - var workAccount = '0xDf18Cb4F2005Bc52F94E9BD6C31f7B0C6394E2C2'; - - // Blockchain process ends if Javascript ends - function keepAlive() { - setInterval(function () { - // Do nothing - }, 999999); - } - - var workAccountBalance = eth.getBalance(workAccount); - var TARGET = 15000000000000000000; - if (workAccountBalance >= TARGET) { - return keepAlive(); - } - - function getNonce() { - return web3.eth.getTransactionCount(eth.coinbase); - } - - function getGasPrice() { - return web3.eth.getGasPrice(); - } - - function sendTransaction(nonce, gasPrice) { - web3.eth.sendTransaction({ - from: eth.coinbase, - to: workAccount, - value: TARGET - workAccountBalance, - gasPrice: gasPrice, - nonce: nonce - }, function (err, _result) { - if (err) { - console.error('Error while transferring funds to user account', err); - } - }); - } - - try { - var nonce = getNonce(); - var gasPrice = getGasPrice(); - sendTransaction(nonce, gasPrice); - } catch (e) { - console.error('Error while getting nonce or gas price', e); - } - - - keepAlive(); -})(); diff --git a/lib/cmds/blockchain/blockchain.js b/lib/cmds/blockchain/blockchain.js index 840fa30b..81785d1b 100644 --- a/lib/cmds/blockchain/blockchain.js +++ b/lib/cmds/blockchain/blockchain.js @@ -7,6 +7,7 @@ var GethCommands = require('./geth_commands.js'); /*eslint complexity: ["error", 35]*/ var Blockchain = function(options) { this.blockchainConfig = options.blockchainConfig; + this.accountsConfig = options.accountsConfig; this.env = options.env || 'development'; this.client = options.client; this.isDev = options.isDev; @@ -41,7 +42,8 @@ var Blockchain = function(options) { vmdebug: this.blockchainConfig.vmdebug || false, targetGasLimit: this.blockchainConfig.targetGasLimit || false, light: this.blockchainConfig.light || false, - fast: this.blockchainConfig.fast || false + fast: this.blockchainConfig.fast || false, + accountsConfig: this.accountsConfig }; if (this.blockchainConfig === {} || JSON.stringify(this.blockchainConfig) === '{"enabled":true}') { @@ -77,8 +79,6 @@ Blockchain.prototype.run = function() { return; } let address = ''; - // copy mining script - fs.copySync(fs.embarkPath("js"), ".embark/" + this.env + "/js", {overwrite: true}); if (!this.isDev) { address = this.initChainAndGetAddress(); } @@ -104,6 +104,9 @@ Blockchain.prototype.initChainAndGetAddress = function() { this.datadir = '.embark/' + this.env + '/datadir'; fs.mkdirpSync(this.datadir); + // copy mining script + fs.copySync(fs.embarkPath("js"), ".embark/" + this.env + "/js", {overwrite: true}); + // check if an account already exists, create one if not, return address result = this.runCommand(this.client.listAccountsCommand()); if (result.output === undefined || result.output.match(/{(\w+)}/) === null || result.output.indexOf("Fatal") >= 0) { @@ -123,9 +126,9 @@ Blockchain.prototype.initChainAndGetAddress = function() { return address; }; -var BlockchainClient = function(blockchainConfig, client, env, isDev) { +var BlockchainClient = function(blockchainConfig, accountsConfig, client, env, isDev) { if (client === 'geth') { - return new Blockchain({blockchainConfig: blockchainConfig, client: GethCommands, env: env, isDev}); + return new Blockchain({blockchainConfig, accountsConfig, client: GethCommands, env, isDev}); } else { throw new Error('unknown client'); } diff --git a/lib/cmds/blockchain/fundAccout.js.ejs b/lib/cmds/blockchain/fundAccout.js.ejs new file mode 100644 index 00000000..8a979722 --- /dev/null +++ b/lib/cmds/blockchain/fundAccout.js.ejs @@ -0,0 +1,53 @@ +/*global web3, eth*/ + +(function () { + +var workAccount = '<%- accountAddress %>'; + +// Blockchain process ends if Javascript ends +function keepAlive() { + setInterval(function () { + // Just stay alive + }, 999999); +} + +var workAccountBalance = eth.getBalance(workAccount); +var TARGET = 15000000000000000000; +if (workAccountBalance >= TARGET) { + return keepAlive(); +} + +function getNonce() { + return web3.eth.getTransactionCount(eth.coinbase); +} + +function getGasPrice() { + return web3.eth.getGasPrice(); +} + +function sendTransaction(nonce, gasPrice) { + web3.eth.sendTransaction({ + from: eth.coinbase, + to: workAccount, + value: TARGET - workAccountBalance, + gasPrice: gasPrice, + nonce: nonce + }, function (err, _result) { + if (err) { + console.error('Error while transferring funds to user account', err); + } + }); +} + +try { + var nonce = getNonce(); + var gasPrice = getGasPrice(); + sendTransaction(nonce, gasPrice); +} catch (e) { + console.error('Error while getting nonce or gas price', e); +} + + +keepAlive(); + +})(); diff --git a/lib/cmds/blockchain/geth_commands.js b/lib/cmds/blockchain/geth_commands.js index 7f08f755..c2bd8e70 100644 --- a/lib/cmds/blockchain/geth_commands.js +++ b/lib/cmds/blockchain/geth_commands.js @@ -1,4 +1,7 @@ -let async = require('async'); +const async = require('async'); +const Web3 = require('web3'); +const AccountParser = require('../../contracts/accountParser'); +const fs = require('../../core/fs'); // TODO: make all of this async class GethCommands { @@ -207,8 +210,21 @@ class GethCommands { callback(null, ""); }, function fundAccount(callback) { - if (self.isDev) { // TODO add config param? - return callback(null, "js .embark/" + self.env + "/js/fundAccount.js"); + if (self.isDev && self.config.accountsConfig && self.config.accountsConfig.length) { + const accounts = AccountParser.parseAccountsConfig(self.config.accountsConfig, new Web3()); + if (accounts.length) { + const fundAccountTemplate = require('./fundAccout.js.ejs'); + const code = fundAccountTemplate({accountAddress: accounts[0].address}); + const filePath = `.embark/${self.env}/js/fundAccount.js`; + fs.writeFile(fs.dappPath(filePath), code, (err) => { + if (err) { + console.error('Failed to created the script to fund the account'); + return callback(null, ''); + } + callback(null, filePath); + }); + return; + } } callback(null, ""); }, diff --git a/lib/index.js b/lib/index.js index 00dcb5f4..6a2e7d2e 100644 --- a/lib/index.js +++ b/lib/index.js @@ -61,7 +61,7 @@ class Embark { if(webServerConfig) blockchainConfig.wsOrigins = `http://${webServerConfig.host}:${webServerConfig.port}`; if(storageConfig) blockchainConfig.wsOrigins += `${blockchainConfig.wsOrigins.length ? ',' : ''}${storageConfig.protocol}://${storageConfig.host}:${storageConfig.port}`; } - return require('./cmds/blockchain/blockchain.js')(blockchainConfig, client, env, this.isDev(env)).run(); + return require('./cmds/blockchain/blockchain.js')(blockchainConfig, this.config.contractsConfig.deployment.accounts, client, env, this.isDev(env)).run(); } simulator(options) { From 50103a8c0246207285e338e3f848edc555360f7b Mon Sep 17 00:00:00 2001 From: Jonathan Rainville Date: Fri, 18 May 2018 13:39:29 -0400 Subject: [PATCH 05/13] conflict in en.json --- lib/i18n/locales/en.json | 21 ++++++--------------- test/blockchain.js | 6 ++++-- 2 files changed, 10 insertions(+), 17 deletions(-) diff --git a/lib/i18n/locales/en.json b/lib/i18n/locales/en.json index f2437081..064f90df 100644 --- a/lib/i18n/locales/en.json +++ b/lib/i18n/locales/en.json @@ -3,7 +3,6 @@ "Contract Name": "Contract Name", "New Application": "New Application", "create a barebones project meant only for contract development": "create a barebones project meant only for contract development", - "language to use (default: en)": "language to use (default: en)", "create a working dapp with a SimpleStorage contract": "create a working dapp with a SimpleStorage contract", "filename to output logs (default: none)": "filename to output logs (default: none)", "level of logging to display": "level of logging to display", @@ -26,9 +25,6 @@ "custom gas limit (default: %s)": "custom gas limit (default: %s)", "run tests": "run tests", "resets embarks state on this dapp including clearing cache": "resets embarks state on this dapp including clearing cache", - "Graph will not include undeployed contracts": "Graph will not include undeployed contracts", - "Graph will not include functions": "Graph will not include functions", - "Graph will not include events": "Graph will not include events", "generates documentation based on the smart contracts configured": "generates documentation based on the smart contracts configured", "Upload your dapp to a decentralized storage": "Upload your dapp to a decentralized storage", "output the version number": "output the version number", @@ -42,12 +38,7 @@ "dashboard start": "dashboard start", "loaded plugins": "loaded plugins", "loading solc compiler": "loading solc compiler", - "Cannot upload: {{platform}} node is not running on {{url}}.": "Cannot upload: {{platform}} node is not running on {{url}}.", - "http:// Cannot upload: {{platform}} node is not running on {{url}}.": "http:// Cannot upload: {{platform}} node is not running on {{url}}.", - "Cannot upload:": "Cannot upload:", - "node is not running on": "node is not running on", "compiling solidity contracts": "compiling solidity contracts", - "Cannot upload: {{platform}} node is not running on {{protocol}}://{{host}}:{{port}}.": "Cannot upload: {{platform}} node is not running on {{protocol}}://{{host}}:{{port}}.", "%s doesn't have a compatible contract compiler. Maybe a plugin exists for it.": "%s doesn't have a compatible contract compiler. Maybe a plugin exists for it.", "assuming %s to be an interface": "assuming %s to be an interface", "{{className}}: couldn't find instanceOf contract {{parentContractName}}": "{{className}}: couldn't find instanceOf contract {{parentContractName}}", @@ -79,15 +70,15 @@ "to immediatly exit (alias: exit)": "to immediatly exit (alias: exit)", "The web3 object and the interfaces for the deployed contracts and their methods are also available": "The web3 object and the interfaces for the deployed contracts and their methods are also available", "versions in use": "versions in use", + "language to use (default: en)": "language to use (default: en)", "executing": "executing", - "finished deploying": "finished deploying", "writing file": "writing file", "errors found while generating": "errors found while generating", - "deploying to swarm!": "deploying to swarm!", - "adding %s to swarm": "adding %s to swarm", - "error uploading to swarm": "error uploading to swarm", "Looking for documentation? You can find it at": "Looking for documentation? You can find it at", "Ready": "Ready", + "Graph will not include undeployed contracts": "Graph will not include undeployed contracts", + "Graph will not include functions": "Graph will not include functions", + "Graph will not include events": "Graph will not include events", "Embark Blockchain Using: %s": "Embark Blockchain Using: %s", "running: %s": "running: %s", "Initializing Embark Template....": "Initializing Embark Template....", @@ -110,5 +101,5 @@ "downloading {{packageName}} {{version}}....": "downloading {{packageName}} {{version}}....", "Swarm node is offline...": "Swarm node is offline...", "Swarm node detected...": "Swarm node detected...", - "file not found, creating it...": "file not found, creating it..." -} + "Ethereum node (version unknown)": "Ethereum node (version unknown)" +} \ No newline at end of file diff --git a/test/blockchain.js b/test/blockchain.js index 06957e0f..af09cdac 100644 --- a/test/blockchain.js +++ b/test/blockchain.js @@ -15,6 +15,7 @@ describe('embark.Blockchain', function () { let config = { networkType: 'custom', genesisBlock: false, + accountsConfig: {}, geth_bin: 'geth', datadir: false, mineWhenNeeded: false, @@ -40,7 +41,7 @@ describe('embark.Blockchain', function () { fast: false, light: false }; - let blockchain = new Blockchain(config, 'geth'); + let blockchain = new Blockchain(config, {}, 'geth'); assert.deepEqual(blockchain.config, config); done(); @@ -54,6 +55,7 @@ describe('embark.Blockchain', function () { genesisBlock: 'foo/bar/genesis.json', geth_bin: 'geth', datadir: '/foo/datadir/', + accountsConfig: {}, mineWhenNeeded: true, rpcHost: 'someserver', rpcPort: 12345, @@ -77,7 +79,7 @@ describe('embark.Blockchain', function () { fast: false, light: false }; - let blockchain = new Blockchain(config, 'geth'); + let blockchain = new Blockchain(config, {}, 'geth'); assert.deepEqual(blockchain.config, config); done(); From 372266418f1bea5b260f2fcd6ea49d2eb20319de Mon Sep 17 00:00:00 2001 From: Jonathan Rainville Date: Thu, 17 May 2018 15:42:04 -0400 Subject: [PATCH 06/13] too many spaces --- lib/cmds/blockchain/fundAccout.js.ejs | 1 - lib/contracts/accountParser.js | 1 - 2 files changed, 2 deletions(-) diff --git a/lib/cmds/blockchain/fundAccout.js.ejs b/lib/cmds/blockchain/fundAccout.js.ejs index 8a979722..3213f1e6 100644 --- a/lib/cmds/blockchain/fundAccout.js.ejs +++ b/lib/cmds/blockchain/fundAccout.js.ejs @@ -47,7 +47,6 @@ try { console.error('Error while getting nonce or gas price', e); } - keepAlive(); })(); diff --git a/lib/contracts/accountParser.js b/lib/contracts/accountParser.js index 139f3c7c..f2f56f8d 100644 --- a/lib/contracts/accountParser.js +++ b/lib/contracts/accountParser.js @@ -2,7 +2,6 @@ const bip39 = require("bip39"); const hdkey = require('ethereumjs-wallet/hdkey'); const fs = require('../core/fs'); - class AccountParser { static parseAccountsConfig(accountsConfig, web3, logger) { let accounts = []; From 418c55851bd337d4d5cad85f97f18c0cde15017f Mon Sep 17 00:00:00 2001 From: Jonathan Rainville Date: Thu, 17 May 2018 15:45:43 -0400 Subject: [PATCH 07/13] remove warning when dev --- lib/contracts/provider.js | 4 ---- lib/core/engine.js | 1 - 2 files changed, 5 deletions(-) diff --git a/lib/contracts/provider.js b/lib/contracts/provider.js index 4f89b0e2..93a2746c 100644 --- a/lib/contracts/provider.js +++ b/lib/contracts/provider.js @@ -8,7 +8,6 @@ class Provider { this.web3 = options.web3; this.accountsConfig = options.accountsConfig; this.logger = options.logger; - this.isDev = options.isDev; this.engine = new ProviderEngine(); this.asyncMethods = {}; @@ -26,9 +25,6 @@ class Provider { this.asyncMethods = { eth_accounts: self.eth_accounts.bind(this) }; - if (this.isDev) { - this.logger.warn('You are using your own account in the develop environment. It might not be funded.'); - } } // network connectivity error diff --git a/lib/core/engine.js b/lib/core/engine.js index 18bb6682..ab945664 100644 --- a/lib/core/engine.js +++ b/lib/core/engine.js @@ -283,7 +283,6 @@ class Engine { web3: this.web3, accountsConfig: this.config.contractsConfig.deployment.accounts, logger: this.logger, - isDev: this.isDev, web3Endpoint }; this.web3.setProvider(new Provider(providerOptions)); From 6c8653ef098824b6fdea76a8f91fd6406ec6d1c9 Mon Sep 17 00:00:00 2001 From: Jonathan Rainville Date: Fri, 18 May 2018 09:25:44 -0400 Subject: [PATCH 08/13] move code to front end. funds on provider start --- lib/cmds/blockchain/fundAccout.js.ejs | 52 ------------------- lib/cmds/blockchain/geth_commands.js | 22 -------- lib/contracts/fundAccount.js | 72 +++++++++++++++++++++++++++ lib/contracts/provider.js | 61 ++++++++++++++++------- lib/core/engine.js | 57 +++++++++++++-------- 5 files changed, 150 insertions(+), 114 deletions(-) delete mode 100644 lib/cmds/blockchain/fundAccout.js.ejs create mode 100644 lib/contracts/fundAccount.js diff --git a/lib/cmds/blockchain/fundAccout.js.ejs b/lib/cmds/blockchain/fundAccout.js.ejs deleted file mode 100644 index 3213f1e6..00000000 --- a/lib/cmds/blockchain/fundAccout.js.ejs +++ /dev/null @@ -1,52 +0,0 @@ -/*global web3, eth*/ - -(function () { - -var workAccount = '<%- accountAddress %>'; - -// Blockchain process ends if Javascript ends -function keepAlive() { - setInterval(function () { - // Just stay alive - }, 999999); -} - -var workAccountBalance = eth.getBalance(workAccount); -var TARGET = 15000000000000000000; -if (workAccountBalance >= TARGET) { - return keepAlive(); -} - -function getNonce() { - return web3.eth.getTransactionCount(eth.coinbase); -} - -function getGasPrice() { - return web3.eth.getGasPrice(); -} - -function sendTransaction(nonce, gasPrice) { - web3.eth.sendTransaction({ - from: eth.coinbase, - to: workAccount, - value: TARGET - workAccountBalance, - gasPrice: gasPrice, - nonce: nonce - }, function (err, _result) { - if (err) { - console.error('Error while transferring funds to user account', err); - } - }); -} - -try { - var nonce = getNonce(); - var gasPrice = getGasPrice(); - sendTransaction(nonce, gasPrice); -} catch (e) { - console.error('Error while getting nonce or gas price', e); -} - -keepAlive(); - -})(); diff --git a/lib/cmds/blockchain/geth_commands.js b/lib/cmds/blockchain/geth_commands.js index c2bd8e70..b05ada7a 100644 --- a/lib/cmds/blockchain/geth_commands.js +++ b/lib/cmds/blockchain/geth_commands.js @@ -1,7 +1,4 @@ const async = require('async'); -const Web3 = require('web3'); -const AccountParser = require('../../contracts/accountParser'); -const fs = require('../../core/fs'); // TODO: make all of this async class GethCommands { @@ -209,25 +206,6 @@ class GethCommands { } callback(null, ""); }, - function fundAccount(callback) { - if (self.isDev && self.config.accountsConfig && self.config.accountsConfig.length) { - const accounts = AccountParser.parseAccountsConfig(self.config.accountsConfig, new Web3()); - if (accounts.length) { - const fundAccountTemplate = require('./fundAccout.js.ejs'); - const code = fundAccountTemplate({accountAddress: accounts[0].address}); - const filePath = `.embark/${self.env}/js/fundAccount.js`; - fs.writeFile(fs.dappPath(filePath), code, (err) => { - if (err) { - console.error('Failed to created the script to fund the account'); - return callback(null, ''); - } - callback(null, filePath); - }); - return; - } - } - callback(null, ""); - }, function isDev(callback) { if (self.isDev) { return callback(null, '--dev'); diff --git a/lib/contracts/fundAccount.js b/lib/contracts/fundAccount.js new file mode 100644 index 00000000..cb9baade --- /dev/null +++ b/lib/contracts/fundAccount.js @@ -0,0 +1,72 @@ +const async = require('async'); +const TARGET = 15000000000000000000; +const ALREADY_FUNDED = 'alreadyFunded'; + +function fundAccount(web3, accountAddress, callback) { + let accountBalance; + let coinbaseAddress; + let lastNonce; + let gasPrice; + + async.waterfall([ + function getAccountBalance(next) { + web3.eth.getBalance(accountAddress, (err, balance) => { + if (err) { + return next(err); + } + if (balance >= TARGET) { + return next(ALREADY_FUNDED); + } + accountBalance = balance; + next(); + }); + }, + function getNeededParams(next) { + async.parallel([ + function getCoinbaseAddress(paraCb) { + web3.eth.getCoinbase() + .then((address) => { + coinbaseAddress = address; + paraCb(); + }).catch(paraCb); + }, + function getGasPrice(paraCb) { + web3.eth.getGasPrice((err, price) => { + if (err) { + return paraCb(err); + } + gasPrice = price; + paraCb(); + }); + } + ], (err, _result) => { + next(err); + }); + }, + function getNonce(next) { + web3.eth.getTransactionCount(coinbaseAddress, (err, nonce) => { + if (err) { + return next(err); + } + lastNonce = nonce; + next(); + }); + }, + function sendTransaction(next) { + web3.eth.sendTransaction({ + from: coinbaseAddress, + to: accountAddress, + value: TARGET - accountBalance, + gasPrice: gasPrice, + nonce: lastNonce + }, next); + } + ], (err) => { + if (err && err !== ALREADY_FUNDED) { + return callback(err); + } + callback(); + }); +} + +module.exports = fundAccount; diff --git a/lib/contracts/provider.js b/lib/contracts/provider.js index 93a2746c..8b621262 100644 --- a/lib/contracts/provider.js +++ b/lib/contracts/provider.js @@ -1,38 +1,63 @@ const ProviderEngine = require('web3-provider-engine'); const RpcSubprovider = require('web3-provider-engine/subproviders/rpc.js'); +const async = require('async'); const AccountParser = require('./accountParser'); +const fundAccount = require('./fundAccount'); + +const NO_ACCOUNTS = 'noAccounts'; class Provider { constructor(options) { - const self = this; this.web3 = options.web3; this.accountsConfig = options.accountsConfig; + this.web3Endpoint = options.web3Endpoint; this.logger = options.logger; this.engine = new ProviderEngine(); this.asyncMethods = {}; + } - this.engine.addProvider(new RpcSubprovider({ - rpcUrl: options.web3Endpoint + startProvider(callback) { + const self = this; + self.engine.addProvider(new RpcSubprovider({ + rpcUrl: self.web3Endpoint })); - this.accounts = AccountParser.parseAccountsConfig(this.accountsConfig, this.web3, this.logger); - this.addresses = []; - if (this.accounts.length) { - this.accounts.forEach(account => { - this.addresses.push(account.address); - this.web3.eth.accounts.wallet.add(account); - }); - this.asyncMethods = { - eth_accounts: self.eth_accounts.bind(this) - }; - } - // network connectivity error - this.engine.on('error', (err) => { + self.engine.on('error', (err) => { // report connectivity errors - this.logger.error(err.stack); + self.logger.error(err.stack); + }); + + self.engine.start(); + self.web3.setProvider(self); + + self.accounts = AccountParser.parseAccountsConfig(self.accountsConfig, self.web3, self.logger); + self.addresses = []; + async.waterfall([ + function fundAccounts(next) { + if (!self.accounts.length) { + return next(NO_ACCOUNTS); + } + async.each(self.accounts, (account, eachCb) => { + fundAccount(self.web3, account.address, eachCb); + }, next); + }, + function populateWeb3Wallet(next) { + self.accounts.forEach(account => { + self.addresses.push(account.address); + self.web3.eth.accounts.wallet.add(account); + }); + self.asyncMethods = { + eth_accounts: self.eth_accounts.bind(self) + }; + next(); + } + ], function (err) { + if (err && err !== NO_ACCOUNTS) { + self.logger.error((err)); + } + callback(); }); - this.engine.start(); } eth_accounts(payload, cb) { diff --git a/lib/core/engine.js b/lib/core/engine.js index ab945664..c59e9566 100644 --- a/lib/core/engine.js +++ b/lib/core/engine.js @@ -275,6 +275,7 @@ class Engine { web3Service(options) { let self = this; this.web3 = options.web3; + let provider; if (this.web3 === undefined) { this.web3 = new Web3(); if (this.config.contractsConfig.deployment.type === "rpc") { @@ -285,43 +286,55 @@ class Engine { logger: this.logger, web3Endpoint }; - this.web3.setProvider(new Provider(providerOptions)); + provider = new Provider(providerOptions); } else { throw new Error("contracts config error: unknown deployment type " + this.config.contractsConfig.deployment.type); } } - self.servicesMonitor.addCheck('Ethereum', function (cb) { - if (self.web3.currentProvider === undefined) { - return cb({name: __("No Blockchain node found"), status: 'off'}); + async.waterfall([ + function (next) { + if (!provider) { + return next(); + } + provider.startProvider(next); } - - self.web3.eth.getAccounts(function(err, _accounts) { - if (err) { + ], function (err) { + if (err) { + console.error(err); + } + self.servicesMonitor.addCheck('Ethereum', function (cb) { + if (self.web3.currentProvider === undefined) { return cb({name: __("No Blockchain node found"), status: 'off'}); } - // TODO: web3_clientVersion method is currently not implemented in web3.js 1.0 - self.web3._requestManager.send({method: 'web3_clientVersion', params: []}, (err, version) => { + self.web3.eth.getAccounts(function(err, _accounts) { if (err) { - return cb({name: __("Ethereum node (version unknown)"), status: 'on'}); + return cb({name: __("No Blockchain node found"), status: 'off'}); } - if (version.indexOf("/") < 0) { - return cb({name: version, status: 'on'}); - } - let nodeName = version.split("/")[0]; - let versionNumber = version.split("/")[1].split("-")[0]; - let name = nodeName + " " + versionNumber + " (Ethereum)"; - return cb({name: name, status: 'on'}); + // TODO: web3_clientVersion method is currently not implemented in web3.js 1.0 + self.web3._requestManager.send({method: 'web3_clientVersion', params: []}, (err, version) => { + if (err) { + return cb({name: __("Ethereum node (version unknown)"), status: 'on'}); + } + if (version.indexOf("/") < 0) { + return cb({name: version, status: 'on'}); + } + let nodeName = version.split("/")[0]; + let versionNumber = version.split("/")[1].split("-")[0]; + let name = nodeName + " " + versionNumber + " (Ethereum)"; + + return cb({name: name, status: 'on'}); + }); }); }); - }); - this.registerModule('whisper', { - addCheck: this.servicesMonitor.addCheck.bind(this.servicesMonitor), - communicationConfig: this.config.communicationConfig, - web3: this.web3 + self.registerModule('whisper', { + addCheck: self.servicesMonitor.addCheck.bind(self.servicesMonitor), + communicationConfig: self.config.communicationConfig, + web3: self.web3 + }); }); } From a1e3c741a04c239117bf778dd07dc10147a79535 Mon Sep 17 00:00:00 2001 From: Jonathan Rainville Date: Fri, 18 May 2018 09:34:59 -0400 Subject: [PATCH 09/13] remove remaning of accounts config in blockchain --- lib/cmds/blockchain/blockchain.js | 8 +++----- lib/i18n/locales/en.json | 5 ++++- lib/index.js | 2 +- test/blockchain.js | 10 ++++------ 4 files changed, 12 insertions(+), 13 deletions(-) diff --git a/lib/cmds/blockchain/blockchain.js b/lib/cmds/blockchain/blockchain.js index 81785d1b..56b43b5a 100644 --- a/lib/cmds/blockchain/blockchain.js +++ b/lib/cmds/blockchain/blockchain.js @@ -7,7 +7,6 @@ var GethCommands = require('./geth_commands.js'); /*eslint complexity: ["error", 35]*/ var Blockchain = function(options) { this.blockchainConfig = options.blockchainConfig; - this.accountsConfig = options.accountsConfig; this.env = options.env || 'development'; this.client = options.client; this.isDev = options.isDev; @@ -42,8 +41,7 @@ var Blockchain = function(options) { vmdebug: this.blockchainConfig.vmdebug || false, targetGasLimit: this.blockchainConfig.targetGasLimit || false, light: this.blockchainConfig.light || false, - fast: this.blockchainConfig.fast || false, - accountsConfig: this.accountsConfig + fast: this.blockchainConfig.fast || false }; if (this.blockchainConfig === {} || JSON.stringify(this.blockchainConfig) === '{"enabled":true}') { @@ -126,9 +124,9 @@ Blockchain.prototype.initChainAndGetAddress = function() { return address; }; -var BlockchainClient = function(blockchainConfig, accountsConfig, client, env, isDev) { +var BlockchainClient = function(blockchainConfig, client, env, isDev) { if (client === 'geth') { - return new Blockchain({blockchainConfig, accountsConfig, client: GethCommands, env, isDev}); + return new Blockchain({blockchainConfig, client: GethCommands, env, isDev}); } else { throw new Error('unknown client'); } diff --git a/lib/i18n/locales/en.json b/lib/i18n/locales/en.json index 064f90df..81f2aa87 100644 --- a/lib/i18n/locales/en.json +++ b/lib/i18n/locales/en.json @@ -101,5 +101,8 @@ "downloading {{packageName}} {{version}}....": "downloading {{packageName}} {{version}}....", "Swarm node is offline...": "Swarm node is offline...", "Swarm node detected...": "Swarm node detected...", - "Ethereum node (version unknown)": "Ethereum node (version unknown)" + "Ethereum node (version unknown)": "Ethereum node (version unknown)", + "No Blockchain node found": "No Blockchain node found", + "Couldn't connect to an Ethereum node are you sure it's on?": "Couldn't connect to an Ethereum node are you sure it's on?", + "make sure you have an Ethereum node or simulator running. e.g '%s'": "make sure you have an Ethereum node or simulator running. e.g '%s'" } \ No newline at end of file diff --git a/lib/index.js b/lib/index.js index 6a2e7d2e..00dcb5f4 100644 --- a/lib/index.js +++ b/lib/index.js @@ -61,7 +61,7 @@ class Embark { if(webServerConfig) blockchainConfig.wsOrigins = `http://${webServerConfig.host}:${webServerConfig.port}`; if(storageConfig) blockchainConfig.wsOrigins += `${blockchainConfig.wsOrigins.length ? ',' : ''}${storageConfig.protocol}://${storageConfig.host}:${storageConfig.port}`; } - return require('./cmds/blockchain/blockchain.js')(blockchainConfig, this.config.contractsConfig.deployment.accounts, client, env, this.isDev(env)).run(); + return require('./cmds/blockchain/blockchain.js')(blockchainConfig, client, env, this.isDev(env)).run(); } simulator(options) { diff --git a/test/blockchain.js b/test/blockchain.js index af09cdac..bcb48d08 100644 --- a/test/blockchain.js +++ b/test/blockchain.js @@ -15,7 +15,6 @@ describe('embark.Blockchain', function () { let config = { networkType: 'custom', genesisBlock: false, - accountsConfig: {}, geth_bin: 'geth', datadir: false, mineWhenNeeded: false, @@ -32,7 +31,7 @@ describe('embark.Blockchain', function () { whisper: true, account: {}, bootnodes: "", - wsApi: [ "eth", "web3", "net", "shh" ], + wsApi: ["eth", "web3", "net", "shh"], wsHost: "localhost", wsOrigins: false, wsPort: 8546, @@ -41,7 +40,7 @@ describe('embark.Blockchain', function () { fast: false, light: false }; - let blockchain = new Blockchain(config, {}, 'geth'); + let blockchain = new Blockchain(config, 'geth'); assert.deepEqual(blockchain.config, config); done(); @@ -55,7 +54,6 @@ describe('embark.Blockchain', function () { genesisBlock: 'foo/bar/genesis.json', geth_bin: 'geth', datadir: '/foo/datadir/', - accountsConfig: {}, mineWhenNeeded: true, rpcHost: 'someserver', rpcPort: 12345, @@ -70,7 +68,7 @@ describe('embark.Blockchain', function () { whisper: false, account: {}, bootnodes: "", - wsApi: [ "eth", "web3", "net", "shh" ], + wsApi: ["eth", "web3", "net", "shh"], wsHost: "localhost", wsOrigins: false, wsPort: 8546, @@ -79,7 +77,7 @@ describe('embark.Blockchain', function () { fast: false, light: false }; - let blockchain = new Blockchain(config, {}, 'geth'); + let blockchain = new Blockchain(config, 'geth'); assert.deepEqual(blockchain.config, config); done(); From 09cdab7e2b2e7d40ec260e3c49aaeb65b86ee08c Mon Sep 17 00:00:00 2001 From: Jonathan Rainville Date: Fri, 18 May 2018 09:46:39 -0400 Subject: [PATCH 10/13] fund account only in dev --- lib/contracts/provider.js | 4 ++++ lib/core/engine.js | 3 ++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/contracts/provider.js b/lib/contracts/provider.js index 8b621262..04be7501 100644 --- a/lib/contracts/provider.js +++ b/lib/contracts/provider.js @@ -12,6 +12,7 @@ class Provider { this.accountsConfig = options.accountsConfig; this.web3Endpoint = options.web3Endpoint; this.logger = options.logger; + this.isDev = options.isDev; this.engine = new ProviderEngine(); this.asyncMethods = {}; } @@ -38,6 +39,9 @@ class Provider { if (!self.accounts.length) { return next(NO_ACCOUNTS); } + if (!self.isDev) { + return next(); + } async.each(self.accounts, (account, eachCb) => { fundAccount(self.web3, account.address, eachCb); }, next); diff --git a/lib/core/engine.js b/lib/core/engine.js index c59e9566..5885d27e 100644 --- a/lib/core/engine.js +++ b/lib/core/engine.js @@ -40,7 +40,7 @@ class Engine { }, 0); if (this.interceptLogs || this.interceptLogs === undefined) { - this.doInterceptLogs(); + // this.doInterceptLogs(); } } @@ -284,6 +284,7 @@ class Engine { web3: this.web3, accountsConfig: this.config.contractsConfig.deployment.accounts, logger: this.logger, + isDev: this.isDev, web3Endpoint }; provider = new Provider(providerOptions); From 4c17aa9d400a669b1004a0bff8438dc7dfb01c25 Mon Sep 17 00:00:00 2001 From: Jonathan Rainville Date: Fri, 18 May 2018 13:27:01 -0400 Subject: [PATCH 11/13] fix some PR comments --- lib/cmds/blockchain/blockchain.js | 1 + lib/contracts/accountParser.js | 10 +++++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/lib/cmds/blockchain/blockchain.js b/lib/cmds/blockchain/blockchain.js index 56b43b5a..5598e91d 100644 --- a/lib/cmds/blockchain/blockchain.js +++ b/lib/cmds/blockchain/blockchain.js @@ -125,6 +125,7 @@ Blockchain.prototype.initChainAndGetAddress = function() { }; var BlockchainClient = function(blockchainConfig, client, env, isDev) { + // TODO add other clients at some point if (client === 'geth') { return new Blockchain({blockchainConfig, client: GethCommands, env, isDev}); } else { diff --git a/lib/contracts/accountParser.js b/lib/contracts/accountParser.js index f2f56f8d..e2460bd6 100644 --- a/lib/contracts/accountParser.js +++ b/lib/contracts/accountParser.js @@ -29,15 +29,23 @@ class AccountParser { if (!accountConfig.privateKey.startsWith('0x')) { accountConfig.privateKey = '0x' + accountConfig.privateKey; } + if (!web3.utils.isHexStrict(accountConfig.privateKey)) { + logger.warn(`Private key ending with ${accountConfig.privateKey.substr(accountConfig.privateKey.length - 5)} is not a HEX string`); + return null; + } return web3.eth.accounts.privateKeyToAccount(accountConfig.privateKey); } if (accountConfig.privateKeyFile) { let fileContent = fs.readFileSync(fs.dappPath(accountConfig.privateKeyFile)).toString(); fileContent = fileContent.trim().split(/[,;]/); - return fileContent.map(key => { + return fileContent.map((key, index) => { if (!key.startsWith('0x')) { key = '0x' + key; } + if (!web3.utils.isHexStrict(key)) { + logger.warn(`Private key is not a HEX string in file ${accountConfig.privateKeyFile} at index ${index}`); + return null; + } return web3.eth.accounts.privateKeyToAccount(key); }); } From 6c1d9d9b39f8f03f42d00e6361dc097e0aab10ff Mon Sep 17 00:00:00 2001 From: Jonathan Rainville Date: Fri, 18 May 2018 13:30:12 -0400 Subject: [PATCH 12/13] rename startProvider to startWeb3Provider --- lib/contracts/provider.js | 2 +- lib/core/engine.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/contracts/provider.js b/lib/contracts/provider.js index 04be7501..29b5ad2a 100644 --- a/lib/contracts/provider.js +++ b/lib/contracts/provider.js @@ -17,7 +17,7 @@ class Provider { this.asyncMethods = {}; } - startProvider(callback) { + startWeb3Provider(callback) { const self = this; self.engine.addProvider(new RpcSubprovider({ rpcUrl: self.web3Endpoint diff --git a/lib/core/engine.js b/lib/core/engine.js index 5885d27e..b41736e8 100644 --- a/lib/core/engine.js +++ b/lib/core/engine.js @@ -298,7 +298,7 @@ class Engine { if (!provider) { return next(); } - provider.startProvider(next); + provider.startWeb3Provider(next); } ], function (err) { if (err) { From 6702cd223141d9bc7740bba86e6f342912760d4f Mon Sep 17 00:00:00 2001 From: Jonathan Rainville Date: Fri, 18 May 2018 13:44:03 -0400 Subject: [PATCH 13/13] fix tests --- test/accountParser.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/accountParser.js b/test/accountParser.js index f6e6e79d..d79b002f 100644 --- a/test/accountParser.js +++ b/test/accountParser.js @@ -13,6 +13,9 @@ describe('embark.AccountParser', function () { return {key}; }) } + }, + utils: { + isHexStrict: sinon.stub().returns(true) } }; const testLogger = new TestLogger({});