mirror of https://github.com/embarklabs/embark.git
redone deployment system
This commit is contained in:
parent
b5d8df5efd
commit
2064b72ac6
|
@ -6,9 +6,13 @@ contract SimpleStorage {
|
||||||
}
|
}
|
||||||
|
|
||||||
function set(uint x) {
|
function set(uint x) {
|
||||||
storedData = x;
|
for (uint same3=0; same3 < 3; same3++) {
|
||||||
|
storedData = same3;
|
||||||
|
}
|
||||||
|
//storedData = x;
|
||||||
}
|
}
|
||||||
function get() constant returns (uint retVal) {
|
function get() constant returns (uint retVal) {
|
||||||
return storedData;
|
return storedData;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
contract token {
|
||||||
|
mapping (address => uint) public coinBalanceOf;
|
||||||
|
event CoinTransfer(address sender, address receiver, uint amount);
|
||||||
|
|
||||||
|
/* Initializes contract with initial supply tokens to the creator of the contract */
|
||||||
|
function token(uint supply) {
|
||||||
|
if (supply == 0) supply = 10000;
|
||||||
|
coinBalanceOf[msg.sender] = supply;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Very simple trade function */
|
||||||
|
function sendCoin(address receiver, uint amount) returns(bool sufficient) {
|
||||||
|
if (coinBalanceOf[msg.sender] < amount) return false;
|
||||||
|
coinBalanceOf[msg.sender] -= amount;
|
||||||
|
coinBalanceOf[receiver] += amount;
|
||||||
|
CoinTransfer(msg.sender, receiver, amount);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,7 @@
|
||||||
{
|
{
|
||||||
"default": {
|
"default": {
|
||||||
|
"gasLimit": 500000,
|
||||||
|
"gasPrice": 10000000000000,
|
||||||
"contracts": {
|
"contracts": {
|
||||||
"SimpleStorage": {
|
"SimpleStorage": {
|
||||||
"args": [
|
"args": [
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
|
||||||
|
var ABIGenerator = function(contractsManager) {
|
||||||
|
this.contractsManager = contractsManager;
|
||||||
|
this.rpcHost = 'localhost';
|
||||||
|
this.rpcPort = '8101';
|
||||||
|
};
|
||||||
|
|
||||||
|
ABIGenerator.prototype.generateProvider = function() {
|
||||||
|
var result = "";
|
||||||
|
|
||||||
|
result += "\nif (typeof web3 !== 'undefined' && typeof Web3 !== 'undefined') {";
|
||||||
|
result += '\n\tweb3 = new Web3(web3.currentProvider);';
|
||||||
|
result += "\n} else if (typeof Web3 !== 'undefined') {";
|
||||||
|
result += '\n\tweb3 = new Web3(new Web3.providers.HttpProvider("http://' + this.rpcHost + ':' + this.rpcPort + '"));';
|
||||||
|
result += '\n}';
|
||||||
|
result += "\nweb3.eth.defaultAccount = web3.eth.accounts[0];";
|
||||||
|
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
|
ABIGenerator.prototype.generateContracts = function() {
|
||||||
|
var result = "\n";
|
||||||
|
|
||||||
|
for(var className in this.contractsManager.contracts) {
|
||||||
|
var contract = this.contractsManager.contracts[className];
|
||||||
|
|
||||||
|
var abi = JSON.stringify(contract.abiDefinition);
|
||||||
|
|
||||||
|
console.log('address is ' + contract.deployedAddress);
|
||||||
|
|
||||||
|
result += "\n" + className + "Abi = " + abi + ";";
|
||||||
|
result += "\n" + className + "Contract = web3.eth.contract(" + className + "Abi);";
|
||||||
|
result += "\n" + className + " = " + className + "Contract.at('" + contract.deployedAddress + "');";
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = ABIGenerator;
|
|
@ -0,0 +1,106 @@
|
||||||
|
var shelljs = require('shelljs');
|
||||||
|
var shelljs_global = require('shelljs/global');
|
||||||
|
var fs = require('fs');
|
||||||
|
var solc = require('solc');
|
||||||
|
|
||||||
|
var Compiler = function() {
|
||||||
|
};
|
||||||
|
|
||||||
|
Compiler.prototype.compile_solidity = function(contractFiles) {
|
||||||
|
var input = {};
|
||||||
|
|
||||||
|
for (var i = 0; i < contractFiles.length; i++){
|
||||||
|
// TODO: this depends on the config
|
||||||
|
var filename = contractFiles[i].replace('app/contracts/','');
|
||||||
|
input[filename] = fs.readFileSync(contractFiles[i]).toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
var output = solc.compile({sources: input}, 1);
|
||||||
|
|
||||||
|
if (output.errors) {
|
||||||
|
throw new Error ("Solidity errors: " + output.errors);
|
||||||
|
}
|
||||||
|
|
||||||
|
var json = output.contracts;
|
||||||
|
|
||||||
|
compiled_object = {};
|
||||||
|
|
||||||
|
for (var className in json) {
|
||||||
|
var contract = json[className];
|
||||||
|
|
||||||
|
compiled_object[className] = {};
|
||||||
|
compiled_object[className].code = contract.bytecode;
|
||||||
|
compiled_object[className].runtimeBytecode = contract.runtimeBytecode;
|
||||||
|
compiled_object[className].gasEstimates = contract.gasEstimates;
|
||||||
|
compiled_object[className].functionHashes = contract.functionHashes;
|
||||||
|
compiled_object[className].abiDefinition = JSON.parse(contract.interface);
|
||||||
|
}
|
||||||
|
|
||||||
|
return compiled_object;
|
||||||
|
};
|
||||||
|
|
||||||
|
Compiler.prototype.compile_serpent = function(contractFiles) {
|
||||||
|
var cmd, result, output, json, compiled_object;
|
||||||
|
|
||||||
|
//TODO: figure out how to compile multiple files and get the correct json
|
||||||
|
var contractFile = contractFiles[0];
|
||||||
|
|
||||||
|
cmd = "serpent compile " + contractFile;
|
||||||
|
|
||||||
|
result = exec(cmd, {silent: true});
|
||||||
|
code = result.output;
|
||||||
|
|
||||||
|
if (result.code === 1) {
|
||||||
|
throw new Error(result.output);
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd = "serpent mk_full_signature " + contractFile;
|
||||||
|
result = exec(cmd, {silent: true});
|
||||||
|
|
||||||
|
if (result.code === 1) {
|
||||||
|
throw new Error(result.output);
|
||||||
|
}
|
||||||
|
|
||||||
|
json = JSON.parse(result.output.trim());
|
||||||
|
className = contractFile.split('.')[0].split("/").pop();
|
||||||
|
|
||||||
|
for (var i=0; i < json.length; i++) {
|
||||||
|
var elem = json[i];
|
||||||
|
|
||||||
|
if (elem.outputs.length > 0) {
|
||||||
|
elem.constant = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
compiled_object = {};
|
||||||
|
compiled_object[className] = {};
|
||||||
|
compiled_object[className].code = code.trim();
|
||||||
|
compiled_object[className].info = {};
|
||||||
|
compiled_object[className].abiDefinition = json;
|
||||||
|
|
||||||
|
return compiled_object;
|
||||||
|
};
|
||||||
|
|
||||||
|
Compiler.prototype.compile = function(contractFiles) {
|
||||||
|
var solidity = [], serpent = [];
|
||||||
|
|
||||||
|
for (var i = 0; i < contractFiles.length; i++) {
|
||||||
|
var contractParts = contractFiles[i].split('.'),
|
||||||
|
extension = contractParts[contractParts.length-1];
|
||||||
|
|
||||||
|
if (extension === 'sol') {
|
||||||
|
solidity.push(contractFiles[i]);
|
||||||
|
}
|
||||||
|
else if (extension === 'se') {
|
||||||
|
serpent.push(contractFiles[i]);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw new Error("extension not known, got " + extension);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//TODO: Get these compiling and returning together...problem might come with the JSON objects
|
||||||
|
if (solidity.length > 0) return this.compile_solidity(solidity);
|
||||||
|
if (serpent.length > 0) return this.compile_serpent(serpent);
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = Compiler;
|
|
@ -0,0 +1,59 @@
|
||||||
|
var fs = require('fs');
|
||||||
|
var grunt = require('grunt');
|
||||||
|
var Compiler = require('./compiler.js');
|
||||||
|
|
||||||
|
var ContractsManager = function(configDir, contractFiles, env) {
|
||||||
|
this.contractFiles = grunt.file.expand(contractFiles);
|
||||||
|
this.configDir = configDir;
|
||||||
|
this.env = env;
|
||||||
|
this.contracts = {};
|
||||||
|
};
|
||||||
|
|
||||||
|
ContractsManager.prototype.init = function() {
|
||||||
|
this.contractsConfig = this.loadConfigFiles();
|
||||||
|
this.compiledContracts = this.compileContracts();
|
||||||
|
};
|
||||||
|
|
||||||
|
ContractsManager.prototype.loadConfigFiles = function() {
|
||||||
|
var defaultContractsConfig = JSON.parse(fs.readFileSync(this.configDir + "contracts.json"))['default'];
|
||||||
|
//var envContractsConfig = JSON.parse(fs.readFileSync(this.configDir + this.env + "/contracts.json"))[this.env];
|
||||||
|
|
||||||
|
//merge.recursive(defaultContractsConfig, envContractsConfig);
|
||||||
|
return defaultContractsConfig;
|
||||||
|
};
|
||||||
|
|
||||||
|
ContractsManager.prototype.compileContracts = function() {
|
||||||
|
var compiler = new Compiler();
|
||||||
|
return compiler.compile_solidity(this.contractFiles);
|
||||||
|
};
|
||||||
|
|
||||||
|
ContractsManager.prototype.build = function() {
|
||||||
|
for(var className in this.compiledContracts) {
|
||||||
|
var contract = this.compiledContracts[className];
|
||||||
|
var contractConfig = this.contractsConfig[className];
|
||||||
|
|
||||||
|
contract.gasLimit = this.contractsConfig.gasLimit;
|
||||||
|
contract.gasPrice = this.contractsConfig.gasPrice;
|
||||||
|
|
||||||
|
if (contractConfig === undefined) {
|
||||||
|
contract.args = [];
|
||||||
|
} else {
|
||||||
|
contract.args = contractConfig.args || [];
|
||||||
|
}
|
||||||
|
|
||||||
|
contract.className = className;
|
||||||
|
this.contracts[className] = contract;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
ContractsManager.prototype.listContracts = function() {
|
||||||
|
var contracts = [];
|
||||||
|
for(var className in this.compiledContracts) {
|
||||||
|
var contract = this.compiledContracts[className];
|
||||||
|
contracts.push(contract);
|
||||||
|
}
|
||||||
|
return contracts;
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = ContractsManager;
|
||||||
|
|
|
@ -1,33 +1,54 @@
|
||||||
var async = require('async');
|
var async = require('async');
|
||||||
|
var Compiler = require('./compiler.js');
|
||||||
|
|
||||||
// needs:
|
var Deploy = function(web3, contractsManager) {
|
||||||
// compile the contract -> file location
|
this.web3 = web3;
|
||||||
// gas -> config
|
this.contractsManager = contractsManager;
|
||||||
contractObject = {
|
};
|
||||||
compiledCode,
|
|
||||||
abiDefinition,
|
|
||||||
gas,
|
|
||||||
gasPrice
|
|
||||||
}
|
|
||||||
|
|
||||||
function deployContract(web3, contractObject, params) {
|
Deploy.prototype.deployContract = function(contract, params, callback) {
|
||||||
var contractObject = web3.eth.contract(contract.compiled.info.abiDefinition);
|
var contractObject = this.web3.eth.contract(contract.abiDefinition);
|
||||||
|
|
||||||
|
var contractParams = params || contract.args;
|
||||||
|
|
||||||
var contractParams = params;
|
|
||||||
contractParams.push({
|
contractParams.push({
|
||||||
from: primaryAddress,
|
from: this.web3.eth.coinbase,
|
||||||
data: contract.compiled.code,
|
data: contract.code,
|
||||||
gas: contract.gasLimit,
|
gas: contract.gasLimit,
|
||||||
gasPrice: contract.gasPrice
|
gasPrice: contract.gasPrice
|
||||||
});
|
});
|
||||||
contractParams.push(callback);
|
|
||||||
|
contractParams.push(function(err, transaction) {
|
||||||
|
if (err) {
|
||||||
|
console.log("error");
|
||||||
|
callback(new Error(err));
|
||||||
|
} else if (transaction.address !== undefined) {
|
||||||
|
console.log("address contract: " + transaction.address);
|
||||||
|
contract.deployedAddress = transaction.address;
|
||||||
|
callback(null, transaction.address);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
contractObject["new"].apply(contractObject, contractParams);
|
contractObject["new"].apply(contractObject, contractParams);
|
||||||
};
|
};
|
||||||
|
|
||||||
function buildContractObject(contractCode, gas, gasPrice) {
|
Deploy.prototype.deployAll = function(done) {
|
||||||
var compiledContract = compiler.compile(contractCode);
|
var self = this;
|
||||||
return {
|
console.log("deployAll");
|
||||||
}
|
|
||||||
}
|
async.eachOfSeries(this.contractsManager.listContracts(),
|
||||||
|
function(contract, key, callback) {
|
||||||
|
console.log(arguments);
|
||||||
|
self.deployContract(contract, null, callback);
|
||||||
|
},
|
||||||
|
function(err, results) {
|
||||||
|
console.log("finished");
|
||||||
|
console.log(arguments);
|
||||||
|
done();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = Deploy;
|
||||||
|
|
||||||
|
|
40
lib/index.js
40
lib/index.js
|
@ -1,6 +1,44 @@
|
||||||
var async = require('async');
|
var async = require('async');
|
||||||
|
var Web3 = require('web3');
|
||||||
|
|
||||||
|
var Deploy = require('./deploy.js');
|
||||||
|
var ContractsManager = require('./contracts.js');
|
||||||
|
var ABIGenerator = require('./abi.js');
|
||||||
|
|
||||||
var Embark = {
|
var Embark = {
|
||||||
|
initConfig: function(configDir, files, env) {
|
||||||
|
this.contractsManager = new ContractsManager(configDir, files, env);
|
||||||
|
this.contractsManager.init();
|
||||||
|
return this.contractsManager;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = Embark;
|
//module.exports = Embark;
|
||||||
|
|
||||||
|
async.waterfall([
|
||||||
|
function loadConfig(callback) {
|
||||||
|
var contractsManager = Embark.initConfig('config/', 'app/contracts/**/*.sol', 'development');
|
||||||
|
callback(null, contractsManager);
|
||||||
|
},
|
||||||
|
function buildContracts(contractsManager, callback) {
|
||||||
|
contractsManager.build();
|
||||||
|
callback(null, contractsManager);
|
||||||
|
},
|
||||||
|
function deployContracts(contractsManager, callback) {
|
||||||
|
var web3 = new Web3();
|
||||||
|
web3.setProvider(new web3.providers.HttpProvider('http://localhost:8101'));
|
||||||
|
var deploy = new Deploy(web3, contractsManager);
|
||||||
|
deploy.deployAll(function() {
|
||||||
|
callback(null, contractsManager);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
function generateABI(contractsManager, callback) {
|
||||||
|
var abiGenerator = new ABIGenerator(contractsManager);
|
||||||
|
console.log(abiGenerator.generateProvider());
|
||||||
|
console.log(abiGenerator.generateContracts());
|
||||||
|
callback(null, 'done');
|
||||||
|
},
|
||||||
|
], function(err, result) {
|
||||||
|
console.log(arguments);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,6 @@
|
||||||
"mkdirp": "^0.5.1",
|
"mkdirp": "^0.5.1",
|
||||||
"read-yaml": "^1.0.0",
|
"read-yaml": "^1.0.0",
|
||||||
"shelljs": "^0.5.0",
|
"shelljs": "^0.5.0",
|
||||||
"solc": "^0.4.1",
|
|
||||||
"toposort": "^0.2.10",
|
"toposort": "^0.2.10",
|
||||||
"web3": "^0.15.0",
|
"web3": "^0.15.0",
|
||||||
"wrench": "^1.5.8"
|
"wrench": "^1.5.8"
|
||||||
|
|
Loading…
Reference in New Issue