From 8f3a42b926b80edd34946dcaa93ab350440b41b7 Mon Sep 17 00:00:00 2001 From: Jonathan Rainville Date: Tue, 14 Aug 2018 13:36:08 -0400 Subject: [PATCH] catch $accounts in contract config --- lib/modules/contracts_manager/index.js | 7 +- lib/modules/deployment/contract_deployer.js | 88 ++++++++++--------- .../test_app/test/array_references_spec.js | 12 +-- 3 files changed, 57 insertions(+), 50 deletions(-) diff --git a/lib/modules/contracts_manager/index.js b/lib/modules/contracts_manager/index.js index 17e0fc91..8f2d54af 100644 --- a/lib/modules/contracts_manager/index.js +++ b/lib/modules/contracts_manager/index.js @@ -246,14 +246,14 @@ class ContractsManager { for (let j = 0; j < ref.length; j++) { let arg = ref[j]; - if (arg[0] === "$") { + if (arg[0] === "$" && !arg.startsWith('$accounts')) { self.contractDependencies[className] = self.contractDependencies[className] || []; self.contractDependencies[className].push(arg.substr(1)); self.checkDependency(className, arg.substr(1)); } if (Array.isArray(arg)) { for (let sub_arg of arg) { - if (sub_arg[0] === "$") { + if (sub_arg[0] === "$" && !sub_arg.startsWith('$accounts')) { self.contractDependencies[className] = self.contractDependencies[className] || []; self.contractDependencies[className].push(sub_arg.substr(1)); self.checkDependency(className, sub_arg.substr(1)); @@ -266,6 +266,9 @@ class ContractsManager { if (contract.onDeploy !== [] && contract.onDeploy !== undefined) { let regex = /\$\w+/g; contract.onDeploy.map((cmd) => { + if (cmd.indexOf('$accounts') > -1) { + return; + } cmd.replace(regex, (match) => { self.contractDependencies[className] = self.contractDependencies[className] || []; self.contractDependencies[className].push(match.substr(1)); diff --git a/lib/modules/deployment/contract_deployer.js b/lib/modules/deployment/contract_deployer.js index c5ece90b..7c83bb6a 100644 --- a/lib/modules/deployment/contract_deployer.js +++ b/lib/modules/deployment/contract_deployer.js @@ -17,7 +17,7 @@ class ContractDeployer { // TODO: determining the arguments could also be in a module since it's not // part of ta 'normal' contract deployment - determineArguments(suppliedArgs, contract, callback) { + determineArguments(suppliedArgs, contract, accounts, callback) { const self = this; let args = suppliedArgs; @@ -34,20 +34,27 @@ class ContractDeployer { } } + function parseArg(arg, cb) { + const match = arg.match(/\$accounts\[([0-9]+)]/); + if (match) { + if (!accounts[match[1]]) { + return cb(__('No corresponding account at index $d', match[1])); + } + return cb(null, accounts[match[1]]); + } + let contractName = arg.substr(1); + self.events.request('contracts:contract', contractName, (referedContract) => { + cb(null, referedContract.deployedAddress); + }); + } + async.map(args, (arg, nextEachCb) => { if (arg[0] === "$") { - let contractName = arg.substr(1); - self.events.request('contracts:contract', contractName, (referedContract) => { - nextEachCb(null, referedContract.deployedAddress); - }); + parseArg(arg, nextEachCb); } else if (Array.isArray(arg)) { async.map(arg, (sub_arg, nextSubEachCb) => { if (sub_arg[0] === "$") { - let contractName = sub_arg.substr(1); - - self.events.request('contracts:contract', contractName, (referedContract) => { - nextSubEachCb(null, referedContract.deployedAddress); - }); + parseArg(sub_arg, nextSubEachCb); } else { nextSubEachCb(null, sub_arg); } @@ -63,6 +70,8 @@ class ContractDeployer { checkAndDeployContract(contract, params, callback) { let self = this; contract.error = false; + let accounts = []; + let deploymentAccount; if (contract.deploy === false) { self.events.emit("deploy:contract:undeployed", contract); @@ -77,8 +86,36 @@ class ContractDeployer { }); }, + // TODO: can potentially go to a beforeDeploy plugin + function getAccounts(next) { + deploymentAccount = self.blockchain.defaultAccount(); + self.blockchain.getAccounts(function (err, _accounts) { + if (err) { + return next(new Error(err)); + } + accounts = _accounts; + + // applying deployer account configuration, if any + if (typeof contract.fromIndex === 'number') { + deploymentAccount = accounts[contract.fromIndex]; + if (deploymentAccount === undefined) { + return next(__("error deploying") + " " + contract.className + ": " + __("no account found at index") + " " + contract.fromIndex + __(" check the config")); + } + } + if (typeof contract.from === 'string' && typeof contract.fromIndex !== 'undefined') { + self.logger.warn(__('Both "from" and "fromIndex" are defined for contract') + ' "' + contract.className + '". ' + __('Using "from" as deployer account.')); + } + if (typeof contract.from === 'string') { + deploymentAccount = contract.from; + } + + deploymentAccount = deploymentAccount || accounts[0]; + contract.deploymentAccount = deploymentAccount; + next(); + }); + }, function _determineArguments(next) { - self.determineArguments(params || contract.args, contract, (err, realArgs) => { + self.determineArguments(params || contract.args, contract, accounts, (err, realArgs) => { if (err) { return next(err); } @@ -141,40 +178,11 @@ class ContractDeployer { deployContract(contract, callback) { let self = this; - let accounts = []; let contractParams = (contract.realArgs || contract.args).slice(); - let deploymentAccount = self.blockchain.defaultAccount(); let deployObject; const logFunction = contract.silent ? self.logger.trace.bind(self.logger) : self.logger.info.bind(self.logger); async.waterfall([ - // TODO: can potentially go to a beforeDeploy plugin - function getAccounts(next) { - self.blockchain.getAccounts(function (err, _accounts) { - if (err) { - return next(new Error(err)); - } - accounts = _accounts; - - // applying deployer account configuration, if any - if (typeof contract.fromIndex === 'number') { - deploymentAccount = accounts[contract.fromIndex]; - if (deploymentAccount === undefined) { - return next(__("error deploying") + " " + contract.className + ": " + __("no account found at index") + " " + contract.fromIndex + __(" check the config")); - } - } - if (typeof contract.from === 'string' && typeof contract.fromIndex !== 'undefined') { - self.logger.warn(__('Both "from" and "fromIndex" are defined for contract') + ' "' + contract.className + '". ' + __('Using "from" as deployer account.')); - } - if (typeof contract.from === 'string') { - deploymentAccount = contract.from; - } - - deploymentAccount = deploymentAccount || accounts[0]; - contract.deploymentAccount = deploymentAccount; - next(); - }); - }, function doLinking(next) { let contractCode = contract.code; self.events.request('contracts:list', (_err, contracts) => { diff --git a/test_apps/test_app/test/array_references_spec.js b/test_apps/test_app/test/array_references_spec.js index ca11c3bb..c6f18e64 100644 --- a/test_apps/test_app/test/array_references_spec.js +++ b/test_apps/test_app/test/array_references_spec.js @@ -1,14 +1,10 @@ -/*global contract, config, it*/ +/*global contract, config, it, web3*/ const assert = require('assert'); const SomeContract = require('Embark/contracts/SomeContract'); -const SimpleStorage = require('Embark/contracts/SimpleStorage'); const MyToken2 = require('Embark/contracts/MyToken2'); config({ contracts: { - "SimpleStorage": { - args: [100] - }, "Token": { deploy: false, args: [1000] @@ -19,7 +15,7 @@ config({ }, "SomeContract": { "args": [ - ["$MyToken2", "$SimpleStorage"], + ["$MyToken2", "$accounts[0]"], 100 ] } @@ -34,9 +30,9 @@ contract("SomeContract", function() { assert.strictEqual(address, MyToken2.options.address); }); - it("set SimpleStorage address", async function() { + it("set account address", async function() { let address = await SomeContract.methods.addr_2().call(); - assert.strictEqual(address, SimpleStorage.options.address); + assert.strictEqual(address, web3.eth.defaultAccount); }); });