diff --git a/demo/config/contracts.json b/demo/config/contracts.json new file mode 100644 index 00000000..6dc28c05 --- /dev/null +++ b/demo/config/contracts.json @@ -0,0 +1,7 @@ +{ + "SimpleStorage": { + "args": [ + 100 + ] + } +} diff --git a/lib/deploy.js b/lib/deploy.js index 49a91427..0f48f157 100644 --- a/lib/deploy.js +++ b/lib/deploy.js @@ -1,239 +1,33 @@ -var web3 = require('web3'); -var fs = require('fs'); -var grunt = require('grunt'); -var readYaml = require('read-yaml'); -var Config = require('./config/config.js'); -var BigNumber = require('bignumber.js'); +var async = require('async'); -Deploy = function(env, contractFiles, blockchainConfig, contractsConfig, chainManager, withProvider, withChain, _web3) { - if (_web3 !== undefined) { - web3 = _web3; - } - this.contractsManager = contractsConfig; - this.contractsConfig = this.contractsManager.config(env); - this.deployedContracts = {}; - this.blockchainConfig = blockchainConfig; +// needs: +// compile the contract -> file location +// gas -> config +contractObject = { + compiledCode, + abiDefinition, + gas, + gasPrice +} - try { - if (withProvider) { - web3.setProvider(new web3.providers.HttpProvider("http://" + this.blockchainConfig.rpcHost + ":" + this.blockchainConfig.rpcPort)); - } - primaryAddress = web3.eth.coinbase; - web3.eth.defaultAccount = primaryAddress; - } catch (e) { - throw new Error("==== can't connect to " + this.blockchainConfig.rpcHost + ":" + this.blockchainConfig.rpcPort + " check if an ethereum node is running"); - } +function deployContract(web3, contractObject, params) { + var contractObject = web3.eth.contract(contract.compiled.info.abiDefinition); - this.chainManager = chainManager; - this.chainManager.init(env, this.blockchainConfig, web3); - this.withChain = withChain; - - console.log("primary account address is : " + primaryAddress); -}; - -Deploy.waitForContract = function(transactionHash, cb) { - web3.eth.getTransactionReceipt(transactionHash, function(e, receipt) { - if (!e && receipt && receipt.contractAddress !== undefined) { - cb(receipt.contractAddress); - } - else { - Deploy.waitForContract(transactionHash, cb); - } + var contractParams = params; + contractParams.push({ + from: primaryAddress, + data: contract.compiled.code, + gas: contract.gasLimit, + gasPrice: contract.gasPrice }); -}; - -Deploy.prototype.deploy_contract = function(contractObject, contractParams, cb) { - var callback = function(e, contract) { - if(!e && contract.address !== undefined) { - cb(contract.address); - } - else { - Deploy.waitForContract(contract.transactionHash, cb); - } - }; - contractParams.push(callback); + contractObject["new"].apply(contractObject, contractParams); -} +}; -Deploy.prototype.deploy_contracts = function(env, cb) { - this.contractsManager.compileContracts(env); - var all_contracts = this.contractsManager.all_contracts; - this.contractDB = this.contractsManager.contractDB; - this.deployedContracts = {}; - - if(this.blockchainConfig.deploy_synchronously) - this.deploy_contract_list_synchronously(env, all_contracts, cb); - else - this.deploy_contract_list(all_contracts.length, env, all_contracts, cb); -} - -Deploy.prototype.deploy_contract_list = function(index, env, all_contracts, cb) { - if(index === 0) { - cb(); - } - else { - var _this = this; - this.deploy_contract_list(index - 1, env, all_contracts, function() { - var className = all_contracts[index - 1]; - _this.deploy_a_contract(env, className, cb); - }); +function buildContractObject(contractCode, gas, gasPrice) { + var compiledContract = compiler.compile(contractCode); + return { } } -Deploy.prototype.deploy_contract_list_synchronously = function(env, all_contracts, cb) { - - var _this = this - ,deployed_contracts_count = 0 - - all_contracts.forEach(function(className){ - _this.deploy_a_contract(env, className, function(){ - mark_contract_as_deployed() - }); - }) - - function mark_contract_as_deployed(){ - deployed_contracts_count ++; - - if(deployed_contracts_count === all_contracts.length) - cb() - } -} - -Deploy.prototype.deploy_a_contract = function(env, className, cb) { - var contractDependencies = this.contractsManager.contractDependencies; - var contract = this.contractDB[className]; - - if (contract.deploy === false) { - console.log("skipping " + className); - cb(); - return; - } - - var realArgs = []; - for (var l = 0; l < contract.args.length; l++) { - arg = contract.args[l]; - if (arg[0] === "$") { - realArgs.push(this.deployedContracts[arg.substr(1)]); - } else { - realArgs.push(arg); - } - } - - if (contract.address !== undefined) { - this.deployedContracts[className] = contract.address; - - console.log("contract " + className + " at " + contract.address); - cb(); - } - else { - var chainContract = this.chainManager.getContract(className, contract.compiled.code, realArgs); - - if (chainContract != undefined && web3.eth.getCode(chainContract.address) !== "0x") { - console.log("contract " + className + " is unchanged and already deployed at " + chainContract.address); - this.deployedContracts[className] = chainContract.address; - this.execute_cmds(contract.onDeploy); - cb(); - } - else { - - contractObject = web3.eth.contract(contract.compiled.info.abiDefinition); - - contractParams = realArgs.slice(); - contractParams.push({ - from: primaryAddress, - data: contract.compiled.code, - gas: contract.gasLimit, - gasPrice: contract.gasPrice - }); - - console.log('trying to obtain ' + className + ' address...'); - - var _this = this; - this.deploy_contract(contractObject, contractParams, function(contractAddress) { - if (web3.eth.getCode(contractAddress) === "0x") { - console.log("========="); - console.log("contract was deployed at " + contractAddress + " but doesn't seem to be working"); - console.log("try adjusting your gas values"); - console.log("========="); - } - else { - console.log("deployed " + className + " at " + contractAddress); - _this.chainManager.addContract(className, contract.compiled.code, realArgs, contractAddress); - if (_this.withChain) { - _this.chainManager.save(); - } - } - - _this.deployedContracts[className] = contractAddress; - - _this.execute_cmds(contract.onDeploy); - - cb(); - }); - - } - } -}; - -Deploy.prototype.execute_cmds = function(cmds) { - if (cmds == undefined || cmds.length === 0) return; - - eval(this.generate_abi_file()); - for (var i = 0; i < cmds.length; i++) { - var cmd = cmds[i]; - - for(className in this.deployedContracts) { - var contractAddress = this.deployedContracts[className]; - - var re = new RegExp("\\$" + className, 'g'); - cmd = cmd.replace(re, '"' + contractAddress + '"'); - } - - console.log("executing: " + cmd); - eval(cmd); - } -}; - -Deploy.prototype.generate_provider_file = function() { - var result = ""; - - result += "if (typeof web3 !== 'undefined' && typeof Web3 !== 'undefined') {"; - result += 'web3 = new Web3(web3.currentProvider);'; - result += "} else if (typeof Web3 !== 'undefined') {"; - result += 'web3 = new Web3(new Web3.providers.HttpProvider("http://' + this.blockchainConfig.rpcHost + ':' + this.blockchainConfig.rpcPort + '"));'; - result += '}'; - result += "web3.eth.defaultAccount = web3.eth.accounts[0];"; - - return result; -}; - -Deploy.prototype.generate_abi_file = function() { - var result = ""; - - result += 'blockchain = '+JSON.stringify(this.blockchainConfig)+';'; - - for(className in this.deployedContracts) { - var deployedContract = this.deployedContracts[className]; - var contract = this.contractDB[className]; - - var abi = JSON.stringify(contract.compiled.info.abiDefinition); - var contractAddress = deployedContract; - - console.log('address is ' + contractAddress); - - result += className + "Abi = " + abi + ";"; - result += className + "Contract = web3.eth.contract(" + className + "Abi);"; - result += className + " = " + className + "Contract.at('" + contractAddress + "');"; - } - result += 'contractDB = '+JSON.stringify(this.contractDB)+';' - - return result; -}; - -Deploy.prototype.generate_and_write_abi_file = function(destFile) { - var result = this.generate_abi_file(); - grunt.file.write(destFile, result); -}; - -module.exports = Deploy; diff --git a/lib/index.js b/lib/index.js index 2bf3fb06..6fc81efb 100644 --- a/lib/index.js +++ b/lib/index.js @@ -1,96 +1,6 @@ -var readYaml = require('read-yaml'); -var shelljs = require('shelljs'); -var shelljs_global = require('shelljs/global'); -var Web3 = require('web3'); -var commander = require('commander'); -var wrench = require('wrench'); -var grunt = require('grunt'); +var async = require('async'); -//var Tests = require('./test.js'); -var Blockchain = require('./blockchain.js'); -var Deploy = require('./deploy.js'); -var SingleDeploy = require('./single_deploy.js'); -var Release = require('./ipfs.js'); -var Config = require('./config/config.js'); -var Compiler = require('./compiler.js'); -var ChainManager = require('./chain_manager.js'); -var Test = require('./test.js'); - -Embark = { - init: function(_web3) { - this.blockchainConfig = (new Config.Blockchain()); - this.compiler = (new Compiler(this.blockchainConfig)); - this.contractsConfig = (new Config.Contracts(this.blockchainConfig, this.compiler)); - if (_web3 !== undefined) { - this.web3 = _web3; - } - else { - this.web3 = new Web3(); - } - this.chainManager = (new ChainManager()); - }, - - startBlockchain: function(env, use_tmp) { - var chain = new Blockchain(this.blockchainConfig.config(env)); - chain.startChain(use_tmp); - }, - - copyMinerJavascriptToTemp: function(){ - //TODO: better with --exec, but need to fix console bug first - wrench.copyDirSyncRecursive(__dirname + "/../js", "/tmp/js", {forceDelete: true}); - }, - - getStartBlockchainCommand: function(env, use_tmp) { - var chain = new Blockchain(this.blockchainConfig.config(env)); - return chain.getStartChainCommand(use_tmp); - }, - - deployContracts: function(env, contractFiles, destFile, chainFile, withProvider, withChain, cb) { - this.contractsConfig.init(contractFiles, env); - - this.chainManager.loadConfigFile(chainFile) - var deploy = new Deploy(env, contractFiles, this.blockchainConfig.config(env), this.contractsConfig, this.chainManager, withProvider, withChain, this.web3); - deploy.deploy_contracts(env, function() { - console.log("contracts deployed; generating abi file"); - var result = "" - if (withProvider) { - result += deploy.generate_provider_file(); - } - result += deploy.generate_abi_file(); - cb(result); - }); - }, - - geth: function(env, args) { - var chain = new Blockchain(this.blockchainConfig.config(env)); - chain.execGeth(args); - }, - - deployContract: function(contractFiles, className, args, cb) { - var compiledContracts = this.compiler.compile_solidity(contractFiles); - var config = this.blockchainConfig.config('development'); - - var deploy = new SingleDeploy(compiledContracts, config.gasLimit, config.gasPrice, this.web3); - deploy.deploy_a_contract(className, args, function() { - var result = ""; - result += deploy.generate_abi_file(); - cb(result); - }); - }, - - release: Release, - - initTests: function() { - var embarkConfig = readYaml.sync("./embark.yml"); - var fileExpression = embarkConfig.contracts || ["app/contracts/**/*.sol", "app/contracts/**/*.se"]; - var contractFiles = grunt.file.expand(fileExpression); - var blockchainFile = embarkConfig.blockchainConfig || 'config/blockchain.yml'; - var contractFile = embarkConfig.contractsConfig || 'config/contracts.yml'; - - var tests = new Test(contractFiles, blockchainFile, contractFile, 'development'); - - return tests; - } -} +var Embark = { +}; module.exports = Embark; diff --git a/lib/blockchain.js b/old_lib/blockchain.js similarity index 100% rename from lib/blockchain.js rename to old_lib/blockchain.js diff --git a/lib/chain_manager.js b/old_lib/chain_manager.js similarity index 100% rename from lib/chain_manager.js rename to old_lib/chain_manager.js diff --git a/lib/compiler.js b/old_lib/compiler.js similarity index 100% rename from lib/compiler.js rename to old_lib/compiler.js diff --git a/lib/config/blockchain.js b/old_lib/config/blockchain.js similarity index 100% rename from lib/config/blockchain.js rename to old_lib/config/blockchain.js diff --git a/lib/config/config.js b/old_lib/config/config.js similarity index 100% rename from lib/config/config.js rename to old_lib/config/config.js diff --git a/lib/config/contracts.js b/old_lib/config/contracts.js similarity index 100% rename from lib/config/contracts.js rename to old_lib/config/contracts.js diff --git a/old_lib/deploy.js b/old_lib/deploy.js new file mode 100644 index 00000000..49a91427 --- /dev/null +++ b/old_lib/deploy.js @@ -0,0 +1,239 @@ +var web3 = require('web3'); +var fs = require('fs'); +var grunt = require('grunt'); +var readYaml = require('read-yaml'); +var Config = require('./config/config.js'); +var BigNumber = require('bignumber.js'); + +Deploy = function(env, contractFiles, blockchainConfig, contractsConfig, chainManager, withProvider, withChain, _web3) { + if (_web3 !== undefined) { + web3 = _web3; + } + this.contractsManager = contractsConfig; + this.contractsConfig = this.contractsManager.config(env); + this.deployedContracts = {}; + this.blockchainConfig = blockchainConfig; + + try { + if (withProvider) { + web3.setProvider(new web3.providers.HttpProvider("http://" + this.blockchainConfig.rpcHost + ":" + this.blockchainConfig.rpcPort)); + } + primaryAddress = web3.eth.coinbase; + web3.eth.defaultAccount = primaryAddress; + } catch (e) { + throw new Error("==== can't connect to " + this.blockchainConfig.rpcHost + ":" + this.blockchainConfig.rpcPort + " check if an ethereum node is running"); + } + + this.chainManager = chainManager; + this.chainManager.init(env, this.blockchainConfig, web3); + this.withChain = withChain; + + console.log("primary account address is : " + primaryAddress); +}; + +Deploy.waitForContract = function(transactionHash, cb) { + web3.eth.getTransactionReceipt(transactionHash, function(e, receipt) { + if (!e && receipt && receipt.contractAddress !== undefined) { + cb(receipt.contractAddress); + } + else { + Deploy.waitForContract(transactionHash, cb); + } + }); +}; + +Deploy.prototype.deploy_contract = function(contractObject, contractParams, cb) { + var callback = function(e, contract) { + if(!e && contract.address !== undefined) { + cb(contract.address); + } + else { + Deploy.waitForContract(contract.transactionHash, cb); + } + }; + + contractParams.push(callback); + contractObject["new"].apply(contractObject, contractParams); +} + +Deploy.prototype.deploy_contracts = function(env, cb) { + this.contractsManager.compileContracts(env); + var all_contracts = this.contractsManager.all_contracts; + this.contractDB = this.contractsManager.contractDB; + this.deployedContracts = {}; + + if(this.blockchainConfig.deploy_synchronously) + this.deploy_contract_list_synchronously(env, all_contracts, cb); + else + this.deploy_contract_list(all_contracts.length, env, all_contracts, cb); +} + +Deploy.prototype.deploy_contract_list = function(index, env, all_contracts, cb) { + if(index === 0) { + cb(); + } + else { + var _this = this; + this.deploy_contract_list(index - 1, env, all_contracts, function() { + var className = all_contracts[index - 1]; + _this.deploy_a_contract(env, className, cb); + }); + } +} + +Deploy.prototype.deploy_contract_list_synchronously = function(env, all_contracts, cb) { + + var _this = this + ,deployed_contracts_count = 0 + + all_contracts.forEach(function(className){ + _this.deploy_a_contract(env, className, function(){ + mark_contract_as_deployed() + }); + }) + + function mark_contract_as_deployed(){ + deployed_contracts_count ++; + + if(deployed_contracts_count === all_contracts.length) + cb() + } +} + +Deploy.prototype.deploy_a_contract = function(env, className, cb) { + var contractDependencies = this.contractsManager.contractDependencies; + var contract = this.contractDB[className]; + + if (contract.deploy === false) { + console.log("skipping " + className); + cb(); + return; + } + + var realArgs = []; + for (var l = 0; l < contract.args.length; l++) { + arg = contract.args[l]; + if (arg[0] === "$") { + realArgs.push(this.deployedContracts[arg.substr(1)]); + } else { + realArgs.push(arg); + } + } + + if (contract.address !== undefined) { + this.deployedContracts[className] = contract.address; + + console.log("contract " + className + " at " + contract.address); + cb(); + } + else { + var chainContract = this.chainManager.getContract(className, contract.compiled.code, realArgs); + + if (chainContract != undefined && web3.eth.getCode(chainContract.address) !== "0x") { + console.log("contract " + className + " is unchanged and already deployed at " + chainContract.address); + this.deployedContracts[className] = chainContract.address; + this.execute_cmds(contract.onDeploy); + cb(); + } + else { + + contractObject = web3.eth.contract(contract.compiled.info.abiDefinition); + + contractParams = realArgs.slice(); + contractParams.push({ + from: primaryAddress, + data: contract.compiled.code, + gas: contract.gasLimit, + gasPrice: contract.gasPrice + }); + + console.log('trying to obtain ' + className + ' address...'); + + var _this = this; + this.deploy_contract(contractObject, contractParams, function(contractAddress) { + if (web3.eth.getCode(contractAddress) === "0x") { + console.log("========="); + console.log("contract was deployed at " + contractAddress + " but doesn't seem to be working"); + console.log("try adjusting your gas values"); + console.log("========="); + } + else { + console.log("deployed " + className + " at " + contractAddress); + _this.chainManager.addContract(className, contract.compiled.code, realArgs, contractAddress); + if (_this.withChain) { + _this.chainManager.save(); + } + } + + _this.deployedContracts[className] = contractAddress; + + _this.execute_cmds(contract.onDeploy); + + cb(); + }); + + } + } +}; + +Deploy.prototype.execute_cmds = function(cmds) { + if (cmds == undefined || cmds.length === 0) return; + + eval(this.generate_abi_file()); + for (var i = 0; i < cmds.length; i++) { + var cmd = cmds[i]; + + for(className in this.deployedContracts) { + var contractAddress = this.deployedContracts[className]; + + var re = new RegExp("\\$" + className, 'g'); + cmd = cmd.replace(re, '"' + contractAddress + '"'); + } + + console.log("executing: " + cmd); + eval(cmd); + } +}; + +Deploy.prototype.generate_provider_file = function() { + var result = ""; + + result += "if (typeof web3 !== 'undefined' && typeof Web3 !== 'undefined') {"; + result += 'web3 = new Web3(web3.currentProvider);'; + result += "} else if (typeof Web3 !== 'undefined') {"; + result += 'web3 = new Web3(new Web3.providers.HttpProvider("http://' + this.blockchainConfig.rpcHost + ':' + this.blockchainConfig.rpcPort + '"));'; + result += '}'; + result += "web3.eth.defaultAccount = web3.eth.accounts[0];"; + + return result; +}; + +Deploy.prototype.generate_abi_file = function() { + var result = ""; + + result += 'blockchain = '+JSON.stringify(this.blockchainConfig)+';'; + + for(className in this.deployedContracts) { + var deployedContract = this.deployedContracts[className]; + var contract = this.contractDB[className]; + + var abi = JSON.stringify(contract.compiled.info.abiDefinition); + var contractAddress = deployedContract; + + console.log('address is ' + contractAddress); + + result += className + "Abi = " + abi + ";"; + result += className + "Contract = web3.eth.contract(" + className + "Abi);"; + result += className + " = " + className + "Contract.at('" + contractAddress + "');"; + } + result += 'contractDB = '+JSON.stringify(this.contractDB)+';' + + return result; +}; + +Deploy.prototype.generate_and_write_abi_file = function(destFile) { + var result = this.generate_abi_file(); + grunt.file.write(destFile, result); +}; + +module.exports = Deploy; diff --git a/old_lib/index.js b/old_lib/index.js new file mode 100644 index 00000000..754c13de --- /dev/null +++ b/old_lib/index.js @@ -0,0 +1,97 @@ +var readYaml = require('read-yaml'); +var shelljs = require('shelljs'); +var shelljs_global = require('shelljs/global'); +var Web3 = require('web3'); +var commander = require('commander'); +var wrench = require('wrench'); +var grunt = require('grunt'); +var async = require('async'); + +//var Tests = require('./test.js'); +var Blockchain = require('./blockchain.js'); +var Deploy = require('./deploy.js'); +var SingleDeploy = require('./single_deploy.js'); +var Release = require('./ipfs.js'); +var Config = require('./config/config.js'); +var Compiler = require('./compiler.js'); +var ChainManager = require('./chain_manager.js'); +var Test = require('./test.js'); + +Embark = { + init: function(_web3) { + this.blockchainConfig = (new Config.Blockchain()); + this.compiler = (new Compiler(this.blockchainConfig)); + this.contractsConfig = (new Config.Contracts(this.blockchainConfig, this.compiler)); + if (_web3 !== undefined) { + this.web3 = _web3; + } + else { + this.web3 = new Web3(); + } + this.chainManager = (new ChainManager()); + }, + + startBlockchain: function(env, use_tmp) { + var chain = new Blockchain(this.blockchainConfig.config(env)); + chain.startChain(use_tmp); + }, + + copyMinerJavascriptToTemp: function(){ + //TODO: better with --exec, but need to fix console bug first + wrench.copyDirSyncRecursive(__dirname + "/../js", "/tmp/js", {forceDelete: true}); + }, + + getStartBlockchainCommand: function(env, use_tmp) { + var chain = new Blockchain(this.blockchainConfig.config(env)); + return chain.getStartChainCommand(use_tmp); + }, + + deployContracts: function(env, contractFiles, destFile, chainFile, withProvider, withChain, cb) { + this.contractsConfig.init(contractFiles, env); + + this.chainManager.loadConfigFile(chainFile) + var deploy = new Deploy(env, contractFiles, this.blockchainConfig.config(env), this.contractsConfig, this.chainManager, withProvider, withChain, this.web3); + deploy.deploy_contracts(env, function() { + console.log("contracts deployed; generating abi file"); + var result = "" + if (withProvider) { + result += deploy.generate_provider_file(); + } + result += deploy.generate_abi_file(); + cb(result); + }); + }, + + geth: function(env, args) { + var chain = new Blockchain(this.blockchainConfig.config(env)); + chain.execGeth(args); + }, + + deployContract: function(contractFiles, className, args, cb) { + var compiledContracts = this.compiler.compile_solidity(contractFiles); + var config = this.blockchainConfig.config('development'); + + var deploy = new SingleDeploy(compiledContracts, config.gasLimit, config.gasPrice, this.web3); + deploy.deploy_a_contract(className, args, function() { + var result = ""; + result += deploy.generate_abi_file(); + cb(result); + }); + }, + + release: Release, + + initTests: function() { + var embarkConfig = readYaml.sync("./embark.yml"); + var fileExpression = embarkConfig.contracts || ["app/contracts/**/*.sol", "app/contracts/**/*.se"]; + var contractFiles = grunt.file.expand(fileExpression); + var blockchainFile = embarkConfig.blockchainConfig || 'config/blockchain.yml'; + var contractFile = embarkConfig.contractsConfig || 'config/contracts.yml'; + + var tests = new Test(contractFiles, blockchainFile, contractFile, 'development'); + + return tests; + } +} + +module.exports = Embark; diff --git a/lib/ipfs.js b/old_lib/ipfs.js similarity index 100% rename from lib/ipfs.js rename to old_lib/ipfs.js diff --git a/lib/single_deploy.js b/old_lib/single_deploy.js similarity index 100% rename from lib/single_deploy.js rename to old_lib/single_deploy.js diff --git a/lib/test.js b/old_lib/test.js similarity index 100% rename from lib/test.js rename to old_lib/test.js diff --git a/package.json b/package.json index cf407e74..87471d62 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,8 @@ "lib": "./lib" }, "dependencies": { + "async": "^2.0.1", + "bignumber.js": "debris/bignumber.js#master", "commander": "^2.8.1", "grunt": "^0.4.5", "js-sha3": "^0.3.1", @@ -23,7 +25,6 @@ "solc": "^0.4.1", "toposort": "^0.2.10", "web3": "^0.15.0", - "bignumber.js": "debris/bignumber.js#master", "wrench": "^1.5.8" }, "author": "Iuri Matias ",