implement contract dependencies

This commit is contained in:
Iuri Matias 2016-09-27 00:55:35 -04:00
parent d21f385fc0
commit 2a8f0635b9
6 changed files with 87 additions and 26 deletions

View File

@ -1,8 +1,10 @@
contract SimpleStorage { contract SimpleStorage {
uint public storedData; uint public storedData;
address public foo;
function SimpleStorage(uint initialValue) { function SimpleStorage(uint initialValue, address addr) {
storedData = initialValue; storedData = initialValue;
foo = addr;
} }
function set(uint x) { function set(uint x) {

View File

@ -1,25 +1,14 @@
{ {
"0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3": { "0xb6cfeab83614da04c03db0fb8a6787a45d0be8d576fcc6f8f457a5a816d22ab3": {
"name": "livenet", "name": "development",
"contracts": { "contracts": {
"5a52b16abb7dfccfc675550d0daba1683a3cf7e80fb5f0e199301f7dd57237fb": { "2ac097aa929aece4724cc229cc7bd26c7dfa153f3274b5623936cb4a4dc12fa1": {
"address": "0x58a580ca43e04e82716c528bc134144042d99ff6", "address": "0xc55a44f8971248db2d0503e81a7d45a1a4a486c3",
"name": "SimpleStorage"
},
"708fa6b699f419627ab3c4c2d9c82f8f1a6fab03c122d0a9ee55d2d0d0ad1e4b": {
"address": "0x717ceee627be5e18b3cd0386d104281688f91cef",
"name": "token" "name": "token"
}
}
},
"0xeb9f1658ba4415557d3952c22cb6aadd416c6d803a47f7ab6c21acb7e758483c": {
"name": "livenet",
"contracts": {
"5a52b16abb7dfccfc675550d0daba1683a3cf7e80fb5f0e199301f7dd57237fb": {
"name": "SimpleStorage"
}, },
"708fa6b699f419627ab3c4c2d9c82f8f1a6fab03c122d0a9ee55d2d0d0ad1e4b": { "769b12e03a7cbca8ad232b5aa5c15b453d3e9332aaf3c468ce29026b34606a05": {
"name": "token" "address": "0x26ee9ba44458921c20cdeecfbb5ab2f96d00b3f7",
"name": "SimpleStorage"
} }
} }
} }

View File

@ -2,10 +2,16 @@
"default": { "default": {
"gas": "auto", "gas": "auto",
"contracts": { "contracts": {
"SimpleStorage": { "token": {
"args": [ "args": [
100 100
] ]
},
"SimpleStorage": {
"args": [
100,
"$token"
]
} }
} }
} }

View File

@ -1,10 +1,13 @@
var Compiler = require('./compiler.js'); var Compiler = require('./compiler.js');
var toposort = require('toposort');
var ContractsManager = function(options) { var ContractsManager = function(options) {
this.contractFiles = options.contractFiles; this.contractFiles = options.contractFiles;
this.contractsConfig = options.contractsConfig; this.contractsConfig = options.contractsConfig;
this.contracts = {}; this.contracts = {};
this.logger = options.logger; this.logger = options.logger;
this.contractDependencies = {};
}; };
ContractsManager.prototype.init = function() { ContractsManager.prototype.init = function() {
@ -17,6 +20,26 @@ ContractsManager.prototype.compileContracts = function() {
}; };
ContractsManager.prototype.build = function() { ContractsManager.prototype.build = function() {
// determine dependencies
for (var className in this.compiledContracts) {
var contract = this.compiledContracts[className];
var contractConfig = this.contractsConfig.contracts[className];
if (this.contractsConfig.args === null || this.contractsConfig.args === []) continue;
var ref = contractConfig.args; //get arguments
for (var j = 0; j < ref.length; j++) {
var arg = ref[j];
if (arg[0] === "$") {
if (this.contractDependencies[className] === void 0) {
this.contractDependencies[className] = [];
}
this.contractDependencies[className].push(arg.substr(1));
}
}
}
for(var className in this.compiledContracts) { for(var className in this.compiledContracts) {
var contract = this.compiledContracts[className]; var contract = this.compiledContracts[className];
var contractConfig = this.contractsConfig.contracts[className]; var contractConfig = this.contractsConfig.contracts[className];
@ -41,6 +64,31 @@ ContractsManager.prototype.build = function() {
} }
}; };
ContractsManager.prototype.getContract = function(className) {
return this.compiledContracts[className];
};
ContractsManager.prototype.sortContracts = function(contractList) {
var converted_dependencies = [], i;
for(var contract in this.contractDependencies) {
var dependencies = this.contractDependencies[contract];
for(var i=0; i < dependencies.length; i++) {
converted_dependencies.push([contract, dependencies[i]]);
}
}
var orderedDependencies = toposort(converted_dependencies).reverse();
var newList = contractList.sort(function(a,b) {
var order_a = orderedDependencies.indexOf(a.className);
var order_b = orderedDependencies.indexOf(b.className);
return order_a - order_b;
});
return newList;
};
// TODO: should be built contracts // TODO: should be built contracts
ContractsManager.prototype.listContracts = function() { ContractsManager.prototype.listContracts = function() {
var contracts = []; var contracts = [];
@ -48,7 +96,7 @@ ContractsManager.prototype.listContracts = function() {
var contract = this.compiledContracts[className]; var contract = this.compiledContracts[className];
contracts.push(contract); contracts.push(contract);
} }
return contracts; return this.sortContracts(contracts);
}; };
ContractsManager.prototype.contractsState = function() { ContractsManager.prototype.contractsState = function() {

View File

@ -23,9 +23,24 @@ Deploy.prototype.checkAndDeployContract = function(contract, params, callback) {
self.logger.contractsState(self.contractsManager.contractsState()); self.logger.contractsState(self.contractsManager.contractsState());
callback(); callback();
} else { } else {
this.deployContract(contract, params, function(err, address) {
self.logger.info("not deployed"); // determine arguments
self.deployTracker.trackContract(contract.className, contract.code, contract.args, address); var suppliedArgs = (params || contract.args);
var realArgs = [];
for (var l = 0; l < suppliedArgs.length; l++) {
var arg = suppliedArgs[l];
if (arg[0] === "$") {
var contractName = arg.substr(1);
var referedContract = this.contractsManager.getContract(contractName);
realArgs.push(referedContract.deployedAddress);
} else {
realArgs.push(arg);
}
}
this.deployContract(contract, realArgs, function(err, address) {
self.deployTracker.trackContract(contract.className, contract.code, realArgs, address);
self.deployTracker.save(); self.deployTracker.save();
self.logger.contractsState(self.contractsManager.contractsState()); self.logger.contractsState(self.contractsManager.contractsState());
callback(); callback();
@ -40,7 +55,7 @@ Deploy.prototype.deployContract = function(contract, params, callback) {
var contractParams = (params || contract.args).slice(); var contractParams = (params || contract.args).slice();
console.log("using address" + this.web3.eth.accounts[0]); //console.log("using address" + this.web3.eth.accounts[0]);
// TODO: probably needs to be defaultAccoun // TODO: probably needs to be defaultAccoun
// TODO: it wouldn't necessary be the first address // TODO: it wouldn't necessary be the first address

View File

@ -39,6 +39,7 @@
"grunt-mocha-test": "^0.12.7", "grunt-mocha-test": "^0.12.7",
"mocha": "^2.2.5", "mocha": "^2.2.5",
"mocha-sinon": "^1.1.4", "mocha-sinon": "^1.1.4",
"sinon": "^1.15.4" "sinon": "^1.15.4",
"toposort": "^0.2.12"
} }
} }