diff --git a/ci/makeMockCompiler.js b/ci/makeMockCompiler.js index 3ced9b3084..df472c4060 100644 --- a/ci/makeMockCompiler.js +++ b/ci/makeMockCompiler.js @@ -63,6 +63,7 @@ function replaceSolCompiler (results) { process.exit(1) return } + data = data + '\n\nvar mockCompilerVersion = \'' + compiler.version() + '\'' data = data + '\n\nvar mockData = ' + JSON.stringify(results) + ';\n' fs.writeFile('./soljson.js', data, 'utf8', function (error) { if (error) { diff --git a/src/app/compiler.js b/src/app/compiler.js index 46fb6ba427..0dcb077297 100644 --- a/src/app/compiler.js +++ b/src/app/compiler.js @@ -1,6 +1,7 @@ 'use strict' var solc = require('solc/wrapper') +var solcABI = require('solc/abi') var webworkify = require('webworkify') var utils = require('./utils') @@ -20,6 +21,8 @@ function Compiler (editor, handleGithubCall) { var cachedRemoteFiles = {} var worker = null + var currentVersion + var optimize = false this.setOptimize = function (_optimize) { @@ -53,6 +56,7 @@ function Compiler (editor, handleGithubCall) { this.setCompileJSON = setCompileJSON // this is exposed for testing function onCompilerLoaded (version) { + currentVersion = version self.event.trigger('compilerLoaded', [version]) } @@ -123,6 +127,8 @@ function Compiler (editor, handleGithubCall) { // try compiling again with the new set of inputs internalCompile(source.sources, missingInputs) } else { + data = updateInterface(data) + self.lastCompilationResult = { data: data, source: source @@ -270,6 +276,24 @@ function Compiler (editor, handleGithubCall) { } while (reloop) cb(null, { 'sources': files }) } + + function truncateVersion (version) { + var tmp = /^(\d+.\d+.\d+)/.exec(version) + if (tmp) { + return tmp[1] + } + return version + } + + function updateInterface (data) { + for (var contract in data.contracts) { + var abi = JSON.parse(data.contracts[contract].interface) + abi = solcABI.update(truncateVersion(currentVersion), abi) + data.contracts[contract].interface = JSON.stringify(abi) + } + + return data + } } module.exports = Compiler diff --git a/src/universal-dapp.js b/src/universal-dapp.js index bb9362745c..85b79d1dc1 100644 --- a/src/universal-dapp.js +++ b/src/universal-dapp.js @@ -196,6 +196,10 @@ UniversalDApp.prototype.getCreateInterface = function ($container, contract) { $createInterface.append($atButton) var $newButton = self.getInstanceInterface(contract) + if (!$newButton) { + return $createInterface + } + $createInterface.append($newButton) // Only display creation interface for non-abstract contracts. @@ -228,7 +232,12 @@ UniversalDApp.prototype.getInstanceInterface = function (contract, address, $tar return 1 } }) + var funABI = self.getConstructorInterface(abi) + if (!funABI) { + return + } + var $createInterface = $('
') var appendFunctions = function (address, $el) { @@ -307,13 +316,16 @@ UniversalDApp.prototype.getInstanceInterface = function (contract, address, $tar $instance.append($title) // Add the fallback function - $instance.append(self.getCallButton({ - abi: { constant: false, inputs: [], name: '(fallback)', outputs: [], type: 'function' }, - encode: function (args) { - return '' - }, - address: address - })) + var fallback = self.getFallbackInterface(abi) + if (fallback) { + $instance.append(self.getCallButton({ + abi: fallback, + encode: function (args) { + return '' + }, + address: address + })) + } $.each(abi, function (i, funABI) { if (funABI.type !== 'function') { @@ -362,16 +374,22 @@ UniversalDApp.prototype.getInstanceInterface = function (contract, address, $tar return $createInterface } -// either return the supplied constructor or a mockup (we assume everything can be instantiated) UniversalDApp.prototype.getConstructorInterface = function (abi) { - var funABI = { 'name': '', 'inputs': [], 'type': 'constructor', 'outputs': [] } for (var i = 0; i < abi.length; i++) { if (abi[i].type === 'constructor') { - funABI.inputs = abi[i].inputs || [] - break + return abi[i] + } + } + + return { 'type': 'constructor', 'payable': false, 'inputs': [] } +} + +UniversalDApp.prototype.getFallbackInterface = function (abi) { + for (var i = 0; i < abi.length; i++) { + if (abi[i].type === 'fallback') { + return abi[i] } } - return funABI } UniversalDApp.prototype.getCallButton = function (args) { @@ -382,12 +400,14 @@ UniversalDApp.prototype.getCallButton = function (args) { var lookupOnly = (args.abi.constant && !isConstructor) var inputs = '' - $.each(args.abi.inputs, function (i, inp) { - if (inputs !== '') { - inputs += ', ' - } - inputs += inp.type + ' ' + inp.name - }) + if (args.abi.inputs) { + $.each(args.abi.inputs, function (i, inp) { + if (inputs !== '') { + inputs += ', ' + } + inputs += inp.type + ' ' + inp.name + }) + } var inputField = $('').attr('placeholder', inputs).attr('title', inputs) var $outputOverride = $('
') var outputSpan = $('
') @@ -517,7 +537,7 @@ UniversalDApp.prototype.getCallButton = function (args) { var decodeResponse = function (response) { // Only decode if there supposed to be fields - if (args.abi.outputs.length > 0) { + if (args.abi.outputs && args.abi.outputs.length > 0) { try { var i @@ -548,7 +568,7 @@ UniversalDApp.prototype.getCallButton = function (args) { } var decoded - self.runTx({ to: args.address, data: data, useCall: args.abi.constant && !isConstructor }, function (err, txResult) { + self.runTx({ to: args.address, data: data, useCall: lookupOnly }, function (err, txResult) { if (!txResult) { replaceOutput($result, $('').text('callback contain no result ' + err).addClass('error')) return @@ -577,12 +597,12 @@ UniversalDApp.prototype.getCallButton = function (args) { if (decoded) { $result.append(decoded) } - if (args.abi.constant) { + if (lookupOnly) { $result.append(getDebugCall(txResult)) } else { $result.append(getDebugTransaction(txResult)) } - } else if (args.abi.constant && !isConstructor) { + } else if (lookupOnly) { clearOutput($result) $result.append(getReturnOutput(result)).append(getGasUsedOutput({})) @@ -598,10 +618,19 @@ UniversalDApp.prototype.getCallButton = function (args) { }) } + var title + if (isConstructor) { + title = 'Create' + } else if (args.abi.name) { + title = args.abi.name + } else { + title = '(fallback)' + } + var button = $('