mirror of https://github.com/embarklabs/embark.git
refactor contract build method
This commit is contained in:
parent
215a823c35
commit
9a09e206ae
255
lib/contracts.js
255
lib/contracts.js
|
@ -1,5 +1,6 @@
|
|||
var Compiler = require('./compiler.js');
|
||||
var toposort = require('toposort');
|
||||
var async = require('async');
|
||||
|
||||
// TODO: create a contract object
|
||||
|
||||
|
@ -17,129 +18,155 @@ ContractsManager.prototype.compileContracts = function() {
|
|||
return compiler.compile_solidity(this.contractFiles);
|
||||
};
|
||||
|
||||
ContractsManager.prototype.build = function() {
|
||||
this.compiledContracts = this.compileContracts();
|
||||
var className;
|
||||
var contract;
|
||||
|
||||
// go through config file first
|
||||
for(className in this.contractsConfig.contracts) {
|
||||
contract = this.contractsConfig.contracts[className];
|
||||
|
||||
contract.className = className;
|
||||
contract.args = contract.args || [];
|
||||
|
||||
this.contracts[className] = contract;
|
||||
}
|
||||
|
||||
// compile contracts
|
||||
for(className in this.compiledContracts) {
|
||||
var compiledContract = this.compiledContracts[className];
|
||||
var contractConfig = this.contractsConfig.contracts[className];
|
||||
|
||||
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;
|
||||
contract.gas = (contractConfig && contractConfig.gas) || this.contractsConfig.gas;
|
||||
|
||||
if (contract.deploy === undefined) {
|
||||
contract.deploy = true;
|
||||
}
|
||||
|
||||
if (contract.gas === 'auto') {
|
||||
var maxGas;
|
||||
if (contract.deploy) {
|
||||
maxGas = Math.max(contract.gasEstimates.creation[0], contract.gasEstimates.creation[1], 500000);
|
||||
} else {
|
||||
maxGas = 500000;
|
||||
ContractsManager.prototype.build = function(done) {
|
||||
var self = this;
|
||||
async.waterfall([
|
||||
function compileContracts(callback) {
|
||||
var compiler = new Compiler();
|
||||
try {
|
||||
self.compiledContracts = compiler.compile_solidity(self.contractFiles);
|
||||
callback();
|
||||
} catch(err) {
|
||||
callback(new Error(err.message));
|
||||
}
|
||||
// TODO: put a check so it doesn't go over the block limit
|
||||
var adjustedGas = Math.round(maxGas * 1.40);
|
||||
contract.gas = adjustedGas;
|
||||
}
|
||||
contract.gasPrice = contract.gasPrice || this.contractsConfig.gasPrice;
|
||||
contract.type = 'file';
|
||||
contract.className = className;
|
||||
},
|
||||
function prepareContractsFromConfig(callback) {
|
||||
var className, contract;
|
||||
for(className in self.contractsConfig.contracts) {
|
||||
contract = self.contractsConfig.contracts[className];
|
||||
|
||||
this.contracts[className] = contract;
|
||||
}
|
||||
contract.className = className;
|
||||
contract.args = contract.args || [];
|
||||
|
||||
// deal with special configs
|
||||
for(className in this.contracts) {
|
||||
contract = this.contracts[className];
|
||||
|
||||
// if deploy intention is not specified default is true
|
||||
if (contract.deploy === undefined) {
|
||||
contract.deploy = true;
|
||||
}
|
||||
|
||||
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;
|
||||
self.contracts[className] = contract;
|
||||
}
|
||||
callback();
|
||||
},
|
||||
function prepareContractsFromCompilation(callback) {
|
||||
var className, compiledContract, contractConfig, contract;
|
||||
var maxGas, adjustedGas;
|
||||
for(className in self.compiledContracts) {
|
||||
compiledContract = self.compiledContracts[className];
|
||||
contractConfig = self.contractsConfig.contracts[className];
|
||||
|
||||
if (parentContract === undefined) {
|
||||
this.logger.error(className + ": couldn't find instanceOf contract " + parentContractName);
|
||||
continue;
|
||||
}
|
||||
contract = self.contracts[className] || {className: className, args: []};
|
||||
|
||||
if (parentContract.args && parentContract.args.length > 0 && contract.args === []) {
|
||||
contract.args = parentContract.args;
|
||||
}
|
||||
contract.code = compiledContract.code;
|
||||
contract.runtimeBytecode = compiledContract.runtimeBytecode;
|
||||
contract.gasEstimates = compiledContract.gasEstimates;
|
||||
contract.functionHashes = compiledContract.functionHashes;
|
||||
contract.abiDefinition = compiledContract.abiDefinition;
|
||||
contract.gas = (contractConfig && contractConfig.gas) || self.contractsConfig.gas;
|
||||
|
||||
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(className in this.contracts) {
|
||||
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(className in this.contracts) {
|
||||
contract = this.contracts[className];
|
||||
|
||||
if (contract.args === []) continue;
|
||||
|
||||
var ref = contract.args;
|
||||
for (var j = 0; j < ref.length; j++) {
|
||||
var arg = ref[j];
|
||||
if (arg[0] === "$") {
|
||||
if (this.contractDependencies[className] === void 0) {
|
||||
this.contractDependencies[className] = [];
|
||||
if (contract.deploy === undefined) {
|
||||
contract.deploy = true;
|
||||
}
|
||||
this.contractDependencies[className].push(arg.substr(1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (contract.gas === 'auto') {
|
||||
if (contract.deploy) {
|
||||
maxGas = Math.max(contract.gasEstimates.creation[0], contract.gasEstimates.creation[1], 500000);
|
||||
} else {
|
||||
maxGas = 500000;
|
||||
}
|
||||
// TODO: put a check so it doesn't go over the block limit
|
||||
adjustedGas = Math.round(maxGas * 1.40);
|
||||
contract.gas = adjustedGas;
|
||||
}
|
||||
contract.gasPrice = contract.gasPrice || self.contractsConfig.gasPrice;
|
||||
contract.type = 'file';
|
||||
contract.className = className;
|
||||
|
||||
self.contracts[className] = contract;
|
||||
}
|
||||
callback();
|
||||
},
|
||||
function dealWithSpecialConfigs(callback) {
|
||||
var className, contract, parentContractName, parentContract;
|
||||
|
||||
for(className in self.contracts) {
|
||||
contract = self.contracts[className];
|
||||
|
||||
// if deploy intention is not specified default is true
|
||||
if (contract.deploy === undefined) {
|
||||
contract.deploy = true;
|
||||
}
|
||||
|
||||
if (contract.instanceOf !== undefined) {
|
||||
parentContractName = contract.instanceOf;
|
||||
parentContract = self.contracts[parentContractName];
|
||||
|
||||
if (parentContract === className) {
|
||||
self.logger.error(className + ": instanceOf is set to itself");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (parentContract === undefined) {
|
||||
slef.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) {
|
||||
self.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;
|
||||
}
|
||||
}
|
||||
callback();
|
||||
},
|
||||
function removeContractsWithNoCode(callback) {
|
||||
var className, contract;
|
||||
for(className in self.contracts) {
|
||||
contract = self.contracts[className];
|
||||
|
||||
if (contract.code === undefined) {
|
||||
self.logger.error(className + " has no code associated");
|
||||
delete self.contracts[className];
|
||||
}
|
||||
}
|
||||
self.logger.trace(self.contracts);
|
||||
callback();
|
||||
},
|
||||
function determineDependencies(callback) {
|
||||
var className, contract;
|
||||
for(className in self.contracts) {
|
||||
contract = self.contracts[className];
|
||||
|
||||
if (contract.args === []) continue;
|
||||
|
||||
var ref = contract.args;
|
||||
for (var j = 0; j < ref.length; j++) {
|
||||
var arg = ref[j];
|
||||
if (arg[0] === "$") {
|
||||
if (self.contractDependencies[className] === void 0) {
|
||||
self.contractDependencies[className] = [];
|
||||
}
|
||||
self.contractDependencies[className].push(arg.substr(1));
|
||||
}
|
||||
}
|
||||
}
|
||||
callback();
|
||||
}
|
||||
], function(err, result) {
|
||||
self.logger.trace("finished".underline);
|
||||
if (err) {
|
||||
//self.logger.debug(err.stack);
|
||||
done(err);
|
||||
} else {
|
||||
done(null, self);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
ContractsManager.prototype.getContract = function(className) {
|
||||
|
|
|
@ -143,12 +143,7 @@ var Embark = {
|
|||
contractsConfig: self.config.contractsConfig,
|
||||
logger: Embark.logger
|
||||
});
|
||||
try {
|
||||
contractsManager.build();
|
||||
callback(null, contractsManager);
|
||||
} catch(err) {
|
||||
callback(new Error(err.message));
|
||||
}
|
||||
contractsManager.build(callback);
|
||||
},
|
||||
function deployContracts(contractsManager, callback) {
|
||||
|
||||
|
|
Loading…
Reference in New Issue