catch $accounts in contract config

This commit is contained in:
Jonathan Rainville 2018-08-14 13:36:08 -04:00 committed by Iuri Matias
parent 0b171401c6
commit 8f3a42b926
3 changed files with 57 additions and 50 deletions

View File

@ -246,14 +246,14 @@ class ContractsManager {
for (let j = 0; j < ref.length; j++) { for (let j = 0; j < ref.length; j++) {
let arg = ref[j]; let arg = ref[j];
if (arg[0] === "$") { if (arg[0] === "$" && !arg.startsWith('$accounts')) {
self.contractDependencies[className] = self.contractDependencies[className] || []; self.contractDependencies[className] = self.contractDependencies[className] || [];
self.contractDependencies[className].push(arg.substr(1)); self.contractDependencies[className].push(arg.substr(1));
self.checkDependency(className, arg.substr(1)); self.checkDependency(className, arg.substr(1));
} }
if (Array.isArray(arg)) { if (Array.isArray(arg)) {
for (let sub_arg of 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] = self.contractDependencies[className] || [];
self.contractDependencies[className].push(sub_arg.substr(1)); self.contractDependencies[className].push(sub_arg.substr(1));
self.checkDependency(className, sub_arg.substr(1)); self.checkDependency(className, sub_arg.substr(1));
@ -266,6 +266,9 @@ class ContractsManager {
if (contract.onDeploy !== [] && contract.onDeploy !== undefined) { if (contract.onDeploy !== [] && contract.onDeploy !== undefined) {
let regex = /\$\w+/g; let regex = /\$\w+/g;
contract.onDeploy.map((cmd) => { contract.onDeploy.map((cmd) => {
if (cmd.indexOf('$accounts') > -1) {
return;
}
cmd.replace(regex, (match) => { cmd.replace(regex, (match) => {
self.contractDependencies[className] = self.contractDependencies[className] || []; self.contractDependencies[className] = self.contractDependencies[className] || [];
self.contractDependencies[className].push(match.substr(1)); self.contractDependencies[className].push(match.substr(1));

View File

@ -17,7 +17,7 @@ class ContractDeployer {
// TODO: determining the arguments could also be in a module since it's not // TODO: determining the arguments could also be in a module since it's not
// part of ta 'normal' contract deployment // part of ta 'normal' contract deployment
determineArguments(suppliedArgs, contract, callback) { determineArguments(suppliedArgs, contract, accounts, callback) {
const self = this; const self = this;
let args = suppliedArgs; let args = suppliedArgs;
@ -34,20 +34,27 @@ class ContractDeployer {
} }
} }
async.map(args, (arg, nextEachCb) => { function parseArg(arg, cb) {
if (arg[0] === "$") { 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); let contractName = arg.substr(1);
self.events.request('contracts:contract', contractName, (referedContract) => { self.events.request('contracts:contract', contractName, (referedContract) => {
nextEachCb(null, referedContract.deployedAddress); cb(null, referedContract.deployedAddress);
}); });
}
async.map(args, (arg, nextEachCb) => {
if (arg[0] === "$") {
parseArg(arg, nextEachCb);
} else if (Array.isArray(arg)) { } else if (Array.isArray(arg)) {
async.map(arg, (sub_arg, nextSubEachCb) => { async.map(arg, (sub_arg, nextSubEachCb) => {
if (sub_arg[0] === "$") { if (sub_arg[0] === "$") {
let contractName = sub_arg.substr(1); parseArg(sub_arg, nextSubEachCb);
self.events.request('contracts:contract', contractName, (referedContract) => {
nextSubEachCb(null, referedContract.deployedAddress);
});
} else { } else {
nextSubEachCb(null, sub_arg); nextSubEachCb(null, sub_arg);
} }
@ -63,6 +70,8 @@ class ContractDeployer {
checkAndDeployContract(contract, params, callback) { checkAndDeployContract(contract, params, callback) {
let self = this; let self = this;
contract.error = false; contract.error = false;
let accounts = [];
let deploymentAccount;
if (contract.deploy === false) { if (contract.deploy === false) {
self.events.emit("deploy:contract:undeployed", contract); 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) { function _determineArguments(next) {
self.determineArguments(params || contract.args, contract, (err, realArgs) => { self.determineArguments(params || contract.args, contract, accounts, (err, realArgs) => {
if (err) { if (err) {
return next(err); return next(err);
} }
@ -141,40 +178,11 @@ class ContractDeployer {
deployContract(contract, callback) { deployContract(contract, callback) {
let self = this; let self = this;
let accounts = [];
let contractParams = (contract.realArgs || contract.args).slice(); let contractParams = (contract.realArgs || contract.args).slice();
let deploymentAccount = self.blockchain.defaultAccount();
let deployObject; let deployObject;
const logFunction = contract.silent ? self.logger.trace.bind(self.logger) : self.logger.info.bind(self.logger); const logFunction = contract.silent ? self.logger.trace.bind(self.logger) : self.logger.info.bind(self.logger);
async.waterfall([ 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) { function doLinking(next) {
let contractCode = contract.code; let contractCode = contract.code;
self.events.request('contracts:list', (_err, contracts) => { self.events.request('contracts:list', (_err, contracts) => {

View File

@ -1,14 +1,10 @@
/*global contract, config, it*/ /*global contract, config, it, web3*/
const assert = require('assert'); const assert = require('assert');
const SomeContract = require('Embark/contracts/SomeContract'); const SomeContract = require('Embark/contracts/SomeContract');
const SimpleStorage = require('Embark/contracts/SimpleStorage');
const MyToken2 = require('Embark/contracts/MyToken2'); const MyToken2 = require('Embark/contracts/MyToken2');
config({ config({
contracts: { contracts: {
"SimpleStorage": {
args: [100]
},
"Token": { "Token": {
deploy: false, deploy: false,
args: [1000] args: [1000]
@ -19,7 +15,7 @@ config({
}, },
"SomeContract": { "SomeContract": {
"args": [ "args": [
["$MyToken2", "$SimpleStorage"], ["$MyToken2", "$accounts[0]"],
100 100
] ]
} }
@ -34,9 +30,9 @@ contract("SomeContract", function() {
assert.strictEqual(address, MyToken2.options.address); 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(); let address = await SomeContract.methods.addr_2().call();
assert.strictEqual(address, SimpleStorage.options.address); assert.strictEqual(address, web3.eth.defaultAccount);
}); });
}); });