From 97954ead32918b7ce234be3db16702c9de30933d Mon Sep 17 00:00:00 2001 From: Iuri Matias Date: Sun, 2 Oct 2016 11:07:56 -0400 Subject: [PATCH] refactor contract builder --- demo/chains.json | 14 +++++- lib/contracts.js | 113 ++++++++++++++++++++++++++++++----------------- lib/index.js | 1 - 3 files changed, 86 insertions(+), 42 deletions(-) diff --git a/demo/chains.json b/demo/chains.json index 07338e7c..536a213b 100644 --- a/demo/chains.json +++ b/demo/chains.json @@ -6,13 +6,25 @@ "address": "0x123", "name": "token" }, + "577bcb0c85129a6ff9e4dcde08f04e6f094e94c74a4423fc90e5947df9a21b82": { + "address": "0xb2f17f39c8a7d8f1745a68525a8450519f50b91c", + "name": "SimpleStorage" + }, + "708fa6b699f419627ab3c4c2d9c82f8f1a6fab03c122d0a9ee55d2d0d0ad1e4b": { + "address": "0x176a7f21ecdb8f88559b5a1e444821b2f9c5cf96", + "name": "token" + }, "e0d35d6564373021d9749a7a8815cf58cc5ca7b7edaf4740c1913898561531c3": { - "address": "0x9e3b27a53318d4dc0b6716afc5ad146480b86b64", + "address": "0x1cc76358b7e5a8debb43bd83f84718d3c1d98836", "name": "SimpleStorage2" }, "f3765f8b702ccb44eb19f1adecbf5a216175713fbd41d9fae100d8e3dfc5e74f": { "address": "0x6ecb595483da2c264ea5e039743340ebce8af0da", "name": "SimpleStorage" + }, + "f3e14e1cd853fc03ed37f669b211591ef53a6e1b5e82e8bf08d04eed8dc6a12e": { + "address": "0x391ae9a75817e11d4dcb208431d3196fd50f1cc6", + "name": "SimpleStorage" } } } diff --git a/lib/contracts.js b/lib/contracts.js index c93b25f8..592e2d6e 100644 --- a/lib/contracts.js +++ b/lib/contracts.js @@ -12,27 +12,36 @@ var ContractsManager = function(options) { this.contractDependencies = {}; }; -ContractsManager.prototype.init = function() { - this.compiledContracts = this.compileContracts(); -}; - ContractsManager.prototype.compileContracts = function() { var compiler = new Compiler(); return compiler.compile_solidity(this.contractFiles); }; ContractsManager.prototype.build = function() { + this.compiledContracts = this.compileContracts(); - // ======================= - // ======================= - // TODO: this should be going through the contract config, not just the - // compiled list - // ======================= - // ======================= + // go through config file first + for(var className in this.contractsConfig.contracts) { + var contract = this.contractsConfig.contracts[className]; + contract.className = className; + contract.args = contract.args || []; + + this.contracts[className] = contract; + } + + // compile contracts for(var className in this.compiledContracts) { - var contract = this.compiledContracts[className]; - var contractConfig = this.contractsConfig.contracts[className]; + var compiledContract = this.compiledContracts[className]; + var contractConfig = this.contractsConfig.contracts[className]; + + var contract = this.contracts[className] || {className: className, args: []}; + + contract.code = compiledContract.code; + contract.runtimeBytecode = compiledContract.runtimeBytecode; + contract.gasEstimates = compiledContract.gasEstimates; + contract.functionHashes = compiledContract.functionHashes; + contract.abiDefinition = compiledContract.abiDefinition; if (this.contractsConfig.gas === 'auto') { var maxGas = Math.max(contract.gasEstimates.creation[0], contract.gasEstimates.creation[1], 500000); @@ -42,49 +51,73 @@ ContractsManager.prototype.build = function() { contract.gas = this.contractsConfig.gas; } contract.gasPrice = this.contractsConfig.gasPrice; - - if (contractConfig === undefined) { - contract.args = []; - } else { - contract.args = contractConfig.args || []; - } - contract.type = 'file'; - contract.className = className; - contract.address = contractConfig.address; this.contracts[className] = contract; } - for(var className in this.contractsConfig.contracts) { - var contractConfig = this.contractsConfig.contracts[className]; - var contract; + // deal with special configs + for(var className in this.contracts) { + var contract = this.contracts[className]; - if (contractConfig.instanceOf !== undefined) { - // TODO: should merge with parent object - var parentContractName = contractConfig.instanceOf; - var parentContract = this.contractsConfig.contracts[parentContractName]; - var parentContractObject = this.contracts[parentContractName]; - contract = JSON.parse(JSON.stringify(parentContractObject)); + // if deploy intention is not specified default is true + if (contract.deploy === undefined) { contract.deploy = true; - contract.className = className; - contract.args = (contractConfig.args || parentContract.args); - contract.gas = (contractConfig.gas || parentContract.gas); - contract.gasPrice = (contractConfig.gasPrice || parentContract.gasPrice); + } - this.contracts[className] = contract; + if (contract.instanceOf !== undefined) { + var parentContractName = contract.instanceOf; + var parentContract = this.contracts[parentContractName]; + + if (parentContract === className) { + this.logger.error(className + ": instanceOf is set to itself"); + continue; + } + + if (parentContract === undefined) { + this.logger.error(className + ": couldn't find instanceOf contract " + parentContractName); + continue; + } + + if (parentContract.args && parentContract.args.length > 0 && contract.args === []) { + contract.args = parentContract.args; + } + + if (contract.code !== undefined) { + this.logger.error(className + " has code associated to it but it's configured as an instanceOf " + parentContractName); + } + + contract.code = parentContract.code; + contract.runtimeBytecode = parentContract.runtimeBytecode; + contract.gasEstimates = parentContract.gasEstimates; + contract.functionHashes = parentContract.functionHashes; + contract.abiDefinition = parentContract.abiDefinition; + + contract.gas = contract.gas || parentContract.gas; + contract.gasPrice = contract.gasPrice || parentContract.gasPrice; } } + // remove contracts that don't have code + for(var className in this.contracts) { + var contract = this.contracts[className]; + + if (contract.code === undefined) { + this.logger.error(className + " has no code associated"); + delete this.contracts[className]; + } + } + + this.logger.trace(this.contracts); + // determine dependencies - for (var className in this.compiledContracts) { - var contract = this.compiledContracts[className]; - var contractConfig = this.contractsConfig.contracts[className]; + for(var className in this.contracts) { + var contract = this.contracts[className]; - if (this.contractsConfig.args === null || this.contractsConfig.args === []) continue; + if (contract.args === []) continue; - var ref = contractConfig.args; //get arguments + var ref = contract.args; for (var j = 0; j < ref.length; j++) { var arg = ref[j]; if (arg[0] === "$") { diff --git a/lib/index.js b/lib/index.js index b719b115..48d0acf9 100644 --- a/lib/index.js +++ b/lib/index.js @@ -193,7 +193,6 @@ var Embark = { contractsConfig: self.config.contractsConfig, logger: Embark.logger }); - contractsManager.init(); contractsManager.build(); callback(null, contractsManager); },