diff --git a/.codeclimate.yml b/.codeclimate.yml new file mode 100644 index 000000000..1f42030a3 --- /dev/null +++ b/.codeclimate.yml @@ -0,0 +1,19 @@ +engines: + eslint: + enabled: true + checks: + no-eval: + enabled: false + no-process-exit: + enabled: false + global-require: + enabled: false +ratings: + paths: + - "lib/**/*" +exclude_paths: +- "tests/" +- "old_test/" +- "boilerplate/" +- "demo/" +- "js/" diff --git a/.nycrc b/.nycrc new file mode 100644 index 000000000..fddd0ceb9 --- /dev/null +++ b/.nycrc @@ -0,0 +1,9 @@ +{ + "reporter": [ + "lcov", + "text-summary" + ], + "include": [ + "lib/**/*.js" + ] +} diff --git a/.travis.yml b/.travis.yml index 3a9c633a1..af4c1c194 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,3 +3,6 @@ node_js: - "6" - "5" - "4" +addons: + code_climate: + repo_token: 7454b1a666015e244c384d19f48c34e35d1ae58c3aa428ec542f10bbcb848358 diff --git a/README.md b/README.md index 6bc1f8410..e1e0e014b 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,7 @@ [![Join the chat at https://gitter.im/iurimatias/embark-framework](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iurimatias/embark-framework?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Build Status](https://travis-ci.org/iurimatias/embark-framework.svg?branch=develop)](https://travis-ci.org/iurimatias/embark-framework) +[![Code Climate](https://codeclimate.com/github/iurimatias/embark-framework/badges/gpa.svg)](https://codeclimate.com/github/iurimatias/embark-framework) What is Embark ====== @@ -23,6 +24,7 @@ Table of Contents * [Usage Demo](#usage---demo) * [Dashboard](#dashboard) * [Creating a new DApp](#creating-a-new-dapp) +* [Libraries and APIs available](#libraries-and-languages-available) * [Using and Configuring Contracts](#dapp-structure) * [EmbarkJS](#embarkjs) * [EmbarkJS - Storage (IPFS)](#embarkjs---storage) @@ -75,7 +77,7 @@ Alternatively, to use an ethereum rpc simulator simply run: $ embark simulator ``` -By default embark blockchain will mine a minimum amount of ether and will only mine when new transactions come in. This is quite usefull to keep a low CPU. The option can be configured at config/blockchain.json +By default embark blockchain will mine a minimum amount of ether and will only mine when new transactions come in. This is quite usefull to keep a low CPU. The option can be configured at ```config/blockchain.json```. Note that running a real node requires at least 2GB of free ram, please take this into account if running it in a VM. Then, in another command line: @@ -131,6 +133,16 @@ DApp Structure Solidity/Serpent files in the contracts directory will automatically be deployed with embark run. Changes in any files will automatically be reflected in app, changes to contracts will result in a redeployment and update of their JS Bindings +Libraries and languages available +====== + +Embark can build and deploy contracts coded in Solidity or Serpent. It will make them available on the client side using EmbarkJS and Web3.js. + +Further documentation for these can be found below: + +* Smart Contracts: [Solidity](https://solidity.readthedocs.io/en/develop/) and [Serpent](https://github.com/ethereum/wiki/wiki/Serpent) +* Client Side: [Web3.js](https://github.com/ethereum/wiki/wiki/JavaScript-API) and [EmbarkJS](#embarkjs) + Using Contracts ====== Embark will automatically take care of deployment for you and set all needed JS bindings. For example, the contract below: diff --git a/boilerplate/chain.json b/boilerplate/chains.json similarity index 100% rename from boilerplate/chain.json rename to boilerplate/chains.json diff --git a/boilerplate/package.json b/boilerplate/package.json index f33d1da55..7fd1f3dcd 100644 --- a/boilerplate/package.json +++ b/boilerplate/package.json @@ -10,7 +10,7 @@ "license": "ISC", "homepage": "", "devDependencies": { - "embark": "^2.0.1", + "embark": "^2.1.2", "mocha": "^2.2.5" } } diff --git a/demo/package.json b/demo/package.json index f33d1da55..7fd1f3dcd 100644 --- a/demo/package.json +++ b/demo/package.json @@ -10,7 +10,7 @@ "license": "ISC", "homepage": "", "devDependencies": { - "embark": "^2.0.1", + "embark": "^2.1.2", "mocha": "^2.2.5" } } diff --git a/js/build/embark.bundle.js b/js/build/embark.bundle.js index 380fc0cbf..94503606f 100644 --- a/js/build/embark.bundle.js +++ b/js/build/embark.bundle.js @@ -76,7 +76,7 @@ var EmbarkJS = var self = this; var contractParams; - contractParams = args; + contractParams = args || []; contractParams.push({ from: this.web3.eth.accounts[0], @@ -5907,83 +5907,14 @@ var EmbarkJS = /***/ function(module, exports) { // shim for using process in browser + var process = module.exports = {}; - - // cached from whatever global is present so that test runners that stub it - // don't break things. But we need to wrap it in a try catch in case it is - // wrapped in strict mode code which doesn't define any globals. It's inside a - // function because try/catches deoptimize in certain engines. - - var cachedSetTimeout; - var cachedClearTimeout; - - (function () { - try { - cachedSetTimeout = setTimeout; - } catch (e) { - cachedSetTimeout = function () { - throw new Error('setTimeout is not defined'); - } - } - try { - cachedClearTimeout = clearTimeout; - } catch (e) { - cachedClearTimeout = function () { - throw new Error('clearTimeout is not defined'); - } - } - } ()) - function runTimeout(fun) { - if (cachedSetTimeout === setTimeout) { - //normal enviroments in sane situations - return setTimeout(fun, 0); - } - try { - // when when somebody has screwed with setTimeout but no I.E. maddness - return cachedSetTimeout(fun, 0); - } catch(e){ - try { - // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally - return cachedSetTimeout.call(null, fun, 0); - } catch(e){ - // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error - return cachedSetTimeout.call(this, fun, 0); - } - } - - - } - function runClearTimeout(marker) { - if (cachedClearTimeout === clearTimeout) { - //normal enviroments in sane situations - return clearTimeout(marker); - } - try { - // when when somebody has screwed with setTimeout but no I.E. maddness - return cachedClearTimeout(marker); - } catch (e){ - try { - // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally - return cachedClearTimeout.call(null, marker); - } catch (e){ - // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error. - // Some versions of I.E. have different rules for clearTimeout vs setTimeout - return cachedClearTimeout.call(this, marker); - } - } - - - - } var queue = []; var draining = false; var currentQueue; var queueIndex = -1; function cleanUpNextTick() { - if (!draining || !currentQueue) { - return; - } draining = false; if (currentQueue.length) { queue = currentQueue.concat(queue); @@ -5999,7 +5930,7 @@ var EmbarkJS = if (draining) { return; } - var timeout = runTimeout(cleanUpNextTick); + var timeout = setTimeout(cleanUpNextTick); draining = true; var len = queue.length; @@ -6016,7 +5947,7 @@ var EmbarkJS = } currentQueue = null; draining = false; - runClearTimeout(timeout); + clearTimeout(timeout); } process.nextTick = function (fun) { @@ -6028,7 +5959,7 @@ var EmbarkJS = } queue.push(new Item(fun, args)); if (queue.length === 1 && !draining) { - runTimeout(drainQueue); + setTimeout(drainQueue, 0); } }; diff --git a/js/embark.js b/js/embark.js index c222cbfc7..1b4d8d573 100644 --- a/js/embark.js +++ b/js/embark.js @@ -29,7 +29,7 @@ EmbarkJS.Contract.prototype.deploy = function(args) { var self = this; var contractParams; - contractParams = args; + contractParams = args || []; contractParams.push({ from: this.web3.eth.accounts[0], diff --git a/lib/cmd.js b/lib/cmd.js index a8ea614b8..781737589 100644 --- a/lib/cmd.js +++ b/lib/cmd.js @@ -3,7 +3,7 @@ var colors = require('colors'); var Cmd = function(Embark) { this.Embark = Embark; - program.version('2.0.1'); + program.version('2.1.2'); }; Cmd.prototype.process = function(args) { @@ -62,12 +62,13 @@ Cmd.prototype.run = function() { var self = this; program .command('run [environment]') + .option('-p, --port [port]', 'port to run the dev webserver') .description('run dapp (default: development)') .action(function(env, options) { self.Embark.initConfig(env || 'development', { embarkConfig: 'embark.json' }); - self.Embark.run(env || 'development'); + self.Embark.run({env: env || 'development', serverPort: options.port}); }); }; diff --git a/lib/contracts.js b/lib/contracts.js index 8f51480f5..c8f5c2456 100644 --- a/lib/contracts.js +++ b/lib/contracts.js @@ -143,7 +143,7 @@ ContractsManager.prototype.build = function() { }; ContractsManager.prototype.getContract = function(className) { - return this.compiledContracts[className]; + return this.contracts[className]; }; ContractsManager.prototype.sortContracts = function(contractList) { diff --git a/lib/index.js b/lib/index.js index 57c85e247..74c7150ff 100644 --- a/lib/index.js +++ b/lib/index.js @@ -53,41 +53,15 @@ var Embark = { self.config.reloadConfig(); callback(); }, - function deployAndBuildContractsManager(callback) { - Embark.monitor.setStatus("Redeploying changed Contracts"); - Embark.buildAndDeploy(function(contractsManager) { - callback(null, contractsManager); - }); - }, - function generateConsoleABI(contractsManager, callback) { - var abiGenerator = new ABIGenerator(self.config.blockchainConfig, contractsManager); - var consoleABI = abiGenerator.generateABI({useEmbarkJS: false}); - Embark.console.runCode(consoleABI); - callback(null, contractsManager); - }, - function generateABI(contractsManager, callback) { - var abiGenerator = new ABIGenerator(self.config.blockchainConfig, contractsManager); - callback(null, abiGenerator.generateABI({useEmbarkJS: true})); - }, - function buildPipeline(abi, callback) { - Embark.monitor.setStatus("Building Assets"); - var pipeline = new Pipeline({ - buildDir: self.config.buildDir, - contractsFiles: self.config.contractsFiles, - assetFiles: self.config.assetFiles, - logger: self.logger - }); - pipeline.build(abi); - callback(); - } + self.buildDeployGenerate.bind(self) ], function(err, result) { - Embark.monitor.setStatus("Ready"); self.logger.trace("finished".underline); }); }, - run: function(env) { + run: function(options) { var self = this; + var env = options.env; async.waterfall([ function startConsole(callback) { Embark.console = new Console(); @@ -105,41 +79,16 @@ var Embark = { function monitorServices(callback) { Embark.servicesMonitor = new ServicesMonitor({ logger: Embark.logger, - config: Embark.config + config: Embark.config, + serverPort: options.serverPort }); Embark.servicesMonitor.startMonitor(); callback(); }, - function deployAndBuildContractsManager(callback) { - Embark.monitor.setStatus("Deploying Contracts"); - Embark.buildAndDeploy(function(contractsManager) { - callback(null, contractsManager); - }); - }, - function generateConsoleABI(contractsManager, callback) { - var abiGenerator = new ABIGenerator(self.config.blockchainConfig, contractsManager); - var consoleABI = abiGenerator.generateABI({useEmbarkJS: false}); - Embark.console.runCode(consoleABI); - callback(null, contractsManager); - }, - function generateABI(contractsManager, callback) { - var abiGenerator = new ABIGenerator(self.config.blockchainConfig, contractsManager); - callback(null, abiGenerator.generateABI({useEmbarkJS: true})); - }, - function buildPipeline(abi, callback) { - Embark.monitor.setStatus("Building Assets"); - var pipeline = new Pipeline({ - buildDir: self.config.buildDir, - contractsFiles: self.config.contractsFiles, - assetFiles: self.config.assetFiles, - logger: self.logger - }); - pipeline.build(abi); - callback(); - }, + self.buildDeployGenerate.bind(self), function startAssetServer(callback) { Embark.monitor.setStatus("Starting Server"); - var server = new Server({logger: self.logger}); + var server = new Server({logger: self.logger, port: options.serverPort}); server.start(callback); }, function watchFilesForChanges(callback) { @@ -158,7 +107,7 @@ var Embark = { callback(); } ], function(err, result) { - Embark.monitor.setStatus("Ready"); + Embark.monitor.setStatus("Ready".green); self.logger.trace("finished".underline); }); }, @@ -194,8 +143,12 @@ var Embark = { contractsConfig: self.config.contractsConfig, logger: Embark.logger }); - contractsManager.build(); - callback(null, contractsManager); + try { + contractsManager.build(); + callback(null, contractsManager); + } catch(err) { + callback(new Error(err.message)); + } }, function deployContracts(contractsManager, callback) { @@ -229,7 +182,11 @@ var Embark = { } ], function(err, result) { - done(result); + if (err) { + done(err, null); + } else { + done(null, result); + } }); }, @@ -244,12 +201,60 @@ var Embark = { function generateABI(contractsManager, callback) { var abiGenerator = new ABIGenerator(self.config.blockchainConfig, contractsManager); callback(null, abiGenerator.generateABI({useEmbarkJS: true})); - }, + } ], function(err, result) { done(result); }); }, + + buildDeployGenerate: function(done) { + var self = this; + + Embark.monitor.setStatus("Deploying...".magenta.underline); + async.waterfall([ + function deployAndBuildContractsManager(callback) { + Embark.buildAndDeploy(function(err, contractsManager) { + if (err) { + callback(err); + } else { + callback(null, contractsManager); + } + }); + }, + function generateConsoleABI(contractsManager, callback) { + var abiGenerator = new ABIGenerator(self.config.blockchainConfig, contractsManager); + var consoleABI = abiGenerator.generateABI({useEmbarkJS: false}); + Embark.console.runCode(consoleABI); + callback(null, contractsManager); + }, + function generateABI(contractsManager, callback) { + var abiGenerator = new ABIGenerator(self.config.blockchainConfig, contractsManager); + callback(null, abiGenerator.generateABI({useEmbarkJS: true})); + }, + function buildPipeline(abi, callback) { + Embark.monitor.setStatus("Building Assets"); + var pipeline = new Pipeline({ + buildDir: self.config.buildDir, + contractsFiles: self.config.contractsFiles, + assetFiles: self.config.assetFiles, + logger: self.logger + }); + pipeline.build(abi); + callback(); + } + ], function(err, result) { + if (err) { + self.logger.error("error deploying"); + self.logger.error(err.message); + Embark.monitor.setStatus("Deployment Error".red); + } else { + Embark.monitor.setStatus("Ready".green); + } + done(result); + }); + }, + initTests: function(options) { return new Test(options); }, diff --git a/lib/monitor.js b/lib/monitor.js index ad9288620..94e94aaf0 100644 --- a/lib/monitor.js +++ b/lib/monitor.js @@ -101,14 +101,14 @@ Dashboard.prototype.layoutLog = function() { left: "0%", top: "42%", border: { - type: "line", + type: "line" }, style: { fg: -1, border: { - fg: this.color, - }, - }, + fg: this.color + } + } }); this.logText = blessed.log({ @@ -141,14 +141,14 @@ Dashboard.prototype.layoutModules = function() { left: "0%", top: "0", border: { - type: "line", + type: "line" }, style: { fg: -1, border: { - fg: this.color, - }, - }, + fg: this.color + } + } }); this.moduleTable = blessed.table({ @@ -184,14 +184,14 @@ Dashboard.prototype.layoutAssets = function() { left: "50%", top: "42%", border: { - type: "line", + type: "line" }, style: { fg: -1, border: { - fg: this.color, - }, - }, + fg: this.color + } + } }); this.assetTable = blessed.table({ @@ -230,20 +230,20 @@ Dashboard.prototype.layoutStatus = function() { label: "Environment", tags: true, padding: { - left: 1, + left: 1 }, width: "100%", height: "20%", valign: "middle", border: { - type: "line", + type: "line" }, style: { fg: -1, border: { - fg: this.color, - }, - }, + fg: this.color + } + } }); this.operations = blessed.box({ @@ -251,20 +251,20 @@ Dashboard.prototype.layoutStatus = function() { label: "Status", tags: true, padding: { - left: 1, + left: 1 }, width: "100%", height: "20%", valign: "middle", border: { - type: "line", + type: "line" }, style: { fg: -1, border: { - fg: this.color, - }, - }, + fg: this.color + } + } }); this.progress = blessed.box({ @@ -283,9 +283,9 @@ Dashboard.prototype.layoutStatus = function() { style: { fg: -1, border: { - fg: this.color, - }, - }, + fg: this.color + } + } }); this.screen.append(this.wrapper); @@ -302,14 +302,14 @@ Dashboard.prototype.layoutCmd = function() { left: '0%', top: '95%', border: { - type: 'line', + type: 'line' }, style: { fg: 'black', border: { - fg: this.color, - }, - }, + fg: this.color + } + } }); this.input = blessed.textbox({ diff --git a/lib/services.js b/lib/services.js index 48f5bf3cf..5e4f2f504 100644 --- a/lib/services.js +++ b/lib/services.js @@ -6,6 +6,7 @@ var ServicesMonitor = function(options) { this.logger = options.logger; this.interval = options.interval || 5000; this.config = options.config; + this.serverPort = options.serverPort || 8000; }; ServicesMonitor.prototype.startMonitor = function() { @@ -27,7 +28,7 @@ ServicesMonitor.prototype.check = function() { }, function addEmbarkVersion(web3, result, callback) { self.logger.trace('addEmbarkVersion'); - result.push('Embark 2.1.0'.green); + result.push('Embark 2.1.2'.green); callback(null, web3, result); }, function checkEthereum(web3, result, callback) { @@ -63,7 +64,7 @@ ServicesMonitor.prototype.check = function() { }, function checkDevServer(result, callback) { self.logger.trace('checkDevServer'); - result.push('dev server (http://localhost:8000)'.green); + result.push(('dev server (http://localhost:' + self.serverPort + ')').green); callback(null, result); } ], function(err, result) { diff --git a/package.json b/package.json index ec4a605b1..b20579327 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "embark", - "version": "2.0.1", + "version": "2.1.2", "description": "Embark is a framework that allows you to easily develop and deploy DApps", "scripts": { "test": "grunt jshint && mocha test/ --no-timeouts" diff --git a/test/compiler.js b/test/compiler.js index e53319566..c86e19168 100644 --- a/test/compiler.js +++ b/test/compiler.js @@ -19,7 +19,7 @@ describe('embark.Compiler', function() { var expectedObject = {}; expectedObject["SimpleStorage"] = {"code":"6060604052604051602080608983395060806040525160008190555060628060276000396000f3606060405260e060020a60003504632a1afcd98114603057806360fe47b114603c5780636d4ce63c146048575b6002565b34600257605060005481565b34600257600435600055005b346002576000545b60408051918252519081900360200190f3","runtimeBytecode":"606060405260e060020a60003504632a1afcd98114603057806360fe47b114603c5780636d4ce63c146048575b6002565b34600257605060005481565b34600257600435600055005b346002576000545b60408051918252519081900360200190f3","gasEstimates":{"creation":[20100,19600],"external":{"get()":236,"set(uint256)":20124,"storedData()":206},"internal":{}},"functionHashes":{"get()":"6d4ce63c","set(uint256)":"60fe47b1","storedData()":"2a1afcd9"},"abiDefinition":[{"constant":true,"inputs":[],"name":"storedData","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"x","type":"uint256"}],"name":"set","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"get","outputs":[{"name":"retVal","type":"uint256"}],"payable":false,"type":"function"},{"inputs":[{"name":"initialValue","type":"uint256"}],"type":"constructor"}]}; - expectedObject["Token"] = {"code":"60606040526040516020806103a3833950608060405251600160a060020a033316600090815260208190526040902081905560028190555061035e806100456000396000f3606060405236156100565760e060020a6000350463095ea7b3811461005b57806318160ddd146100d557806323b872dd146100f057806370a0823114610127578063a9059cbb1461014c578063dd62ed3e14610180575b610002565b34610002576101b960043560243533600160a060020a03908116600081815260016020908152604080832094871680845294825280832086905580518681529051929493927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925929181900390910190a35060015b92915050565b34610002576002545b60408051918252519081900360200190f35b34610002576101b9600435602435604435600160a060020a038316600090815260208190526040812054829010156101cd57610002565b3461000257600160a060020a03600435166000908152602081905260409020546100de565b34610002576101b960043560243533600160a060020a0316600090815260208190526040812054829010156102c257610002565b34610002576100de600435602435600160a060020a038281166000908152600160209081526040808320938516835292905220546100cf565b604080519115158252519081900360200190f35b600160a060020a03848116600090815260016020908152604080832033909416835292905220548290101561020157610002565b600160a060020a03831660009081526020819052604090205461022c90835b818101829010156100cf565b151561023757610002565b600160a060020a038481166000818152600160209081526040808320338616845282528083208054889003905583835282825280832080548890039055938716808352918490208054870190558351868152935191937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929081900390910190a35060019392505050565b600160a060020a0383166000908152602081905260409020546102e59083610220565b15156102f057610002565b33600160a060020a0390811660008181526020818152604080832080548890039055938716808352918490208054870190558351868152935191937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929081900390910190a35060016100cf56","runtimeBytecode":"606060405236156100565760e060020a6000350463095ea7b3811461005b57806318160ddd146100d557806323b872dd146100f057806370a0823114610127578063a9059cbb1461014c578063dd62ed3e14610180575b610002565b34610002576101b960043560243533600160a060020a03908116600081815260016020908152604080832094871680845294825280832086905580518681529051929493927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925929181900390910190a35060015b92915050565b34610002576002545b60408051918252519081900360200190f35b34610002576101b9600435602435604435600160a060020a038316600090815260208190526040812054829010156101cd57610002565b3461000257600160a060020a03600435166000908152602081905260409020546100de565b34610002576101b960043560243533600160a060020a0316600090815260208190526040812054829010156102c257610002565b34610002576100de600435602435600160a060020a038281166000908152600160209081526040808320938516835292905220546100cf565b604080519115158252519081900360200190f35b600160a060020a03848116600090815260016020908152604080832033909416835292905220548290101561020157610002565b600160a060020a03831660009081526020819052604090205461022c90835b818101829010156100cf565b151561023757610002565b600160a060020a038481166000818152600160209081526040808320338616845282528083208054889003905583835282825280832080548890039055938716808352918490208054870190558351868152935191937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929081900390910190a35060019392505050565b600160a060020a0383166000908152602081905260409020546102e59083610220565b15156102f057610002565b33600160a060020a0390811660008181526020818152604080832080548890039055938716808352918490208054870190558351868152935191937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929081900390910190a35060016100cf56","gasEstimates":{"creation":[40354,172400],"external":{"allowance(address,address)":547,"approve(address,uint256)":22223,"balanceOf(address)":397,"totalSupply()":232,"transfer(address,uint256)":null,"transferFrom(address,address,uint256)":63271},"internal":{"safeToAdd(uint256,uint256)":52}},"functionHashes":{"allowance(address,address)":"dd62ed3e","approve(address,uint256)":"095ea7b3","balanceOf(address)":"70a08231","totalSupply()":"18160ddd","transfer(address,uint256)":"a9059cbb","transferFrom(address,address,uint256)":"23b872dd"},"abiDefinition":[{"constant":false,"inputs":[{"name":"spender","type":"address"},{"name":"value","type":"uint256"}],"name":"approve","outputs":[{"name":"ok","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"supply","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"from","type":"address"},{"name":"to","type":"address"},{"name":"value","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"ok","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"who","type":"address"}],"name":"balanceOf","outputs":[{"name":"value","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"to","type":"address"},{"name":"value","type":"uint256"}],"name":"transfer","outputs":[{"name":"ok","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"owner","type":"address"},{"name":"spender","type":"address"}],"name":"allowance","outputs":[{"name":"_allowance","type":"uint256"}],"payable":false,"type":"function"},{"inputs":[{"name":"initial_balance","type":"uint256"}],"type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"owner","type":"address"},{"indexed":true,"name":"spender","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Approval","type":"event"}]}; + expectedObject["Token"] = {"code":"60606040526040516020806103a1833950608060405251600160a060020a033316600090815260208190526040902081905560028190555061035c806100456000396000f3606060405236156100565760e060020a6000350463095ea7b3811461005b57806318160ddd146100d457806323b872dd146100ef57806370a0823114610126578063a9059cbb1461014b578063dd62ed3e1461017f575b610002565b34610002576101b8600435602435600160a060020a03338116600081815260016020908152604080832094871680845294825280832086905580518681529051929493927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925929181900390910190a35060015b92915050565b34610002576002545b60408051918252519081900360200190f35b34610002576101b8600435602435604435600160a060020a038316600090815260208190526040812054829010156101cc57610002565b3461000257600160a060020a03600435166000908152602081905260409020546100dd565b34610002576101b8600435602435600160a060020a033316600090815260208190526040812054829010156102c157610002565b34610002576100dd600435602435600160a060020a038083166000908152600160209081526040808320938516835292905220546100ce565b604080519115158252519081900360200190f35b600160a060020a03808516600090815260016020908152604080832033909416835292905220548290101561020057610002565b600160a060020a03831660009081526020819052604090205461022b90835b808201829010156100ce565b151561023657610002565b600160a060020a038085166000818152600160209081526040808320338616845282528083208054889003905583835282825280832080548890039055938716808352918490208054870190558351868152935191937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929081900390910190a35060019392505050565b600160a060020a0383166000908152602081905260409020546102e4908361021f565b15156102ef57610002565b600160a060020a0333811660008181526020818152604080832080548890039055938716808352918490208054870190558351868152935191937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929081900390910190a35060016100ce56","runtimeBytecode":"606060405236156100565760e060020a6000350463095ea7b3811461005b57806318160ddd146100d457806323b872dd146100ef57806370a0823114610126578063a9059cbb1461014b578063dd62ed3e1461017f575b610002565b34610002576101b8600435602435600160a060020a03338116600081815260016020908152604080832094871680845294825280832086905580518681529051929493927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925929181900390910190a35060015b92915050565b34610002576002545b60408051918252519081900360200190f35b34610002576101b8600435602435604435600160a060020a038316600090815260208190526040812054829010156101cc57610002565b3461000257600160a060020a03600435166000908152602081905260409020546100dd565b34610002576101b8600435602435600160a060020a033316600090815260208190526040812054829010156102c157610002565b34610002576100dd600435602435600160a060020a038083166000908152600160209081526040808320938516835292905220546100ce565b604080519115158252519081900360200190f35b600160a060020a03808516600090815260016020908152604080832033909416835292905220548290101561020057610002565b600160a060020a03831660009081526020819052604090205461022b90835b808201829010156100ce565b151561023657610002565b600160a060020a038085166000818152600160209081526040808320338616845282528083208054889003905583835282825280832080548890039055938716808352918490208054870190558351868152935191937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929081900390910190a35060019392505050565b600160a060020a0383166000908152602081905260409020546102e4908361021f565b15156102ef57610002565b600160a060020a0333811660008181526020818152604080832080548890039055938716808352918490208054870190558351868152935191937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929081900390910190a35060016100ce56","gasEstimates":{"creation":[40354,172000],"external":{"allowance(address,address)":547,"approve(address,uint256)":22220,"balanceOf(address)":397,"totalSupply()":232,"transfer(address,uint256)":null,"transferFrom(address,address,uint256)":63271},"internal":{"safeToAdd(uint256,uint256)":52}},"functionHashes":{"allowance(address,address)":"dd62ed3e","approve(address,uint256)":"095ea7b3","balanceOf(address)":"70a08231","totalSupply()":"18160ddd","transfer(address,uint256)":"a9059cbb","transferFrom(address,address,uint256)":"23b872dd"},"abiDefinition":[{"constant":false,"inputs":[{"name":"spender","type":"address"},{"name":"value","type":"uint256"}],"name":"approve","outputs":[{"name":"ok","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"supply","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"from","type":"address"},{"name":"to","type":"address"},{"name":"value","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"ok","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"who","type":"address"}],"name":"balanceOf","outputs":[{"name":"value","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"to","type":"address"},{"name":"value","type":"uint256"}],"name":"transfer","outputs":[{"name":"ok","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"owner","type":"address"},{"name":"spender","type":"address"}],"name":"allowance","outputs":[{"name":"_allowance","type":"uint256"}],"payable":false,"type":"function"},{"inputs":[{"name":"initial_balance","type":"uint256"}],"type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"owner","type":"address"},{"indexed":true,"name":"spender","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Approval","type":"event"}]}; it('should generate compiled code and abi', function() { assert.deepEqual(compiledContracts, expectedObject);