From d99fea2db682c454581e1f9f60b2cea27d02c36e Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Thu, 13 Nov 2014 04:21:51 +0100 Subject: [PATCH] abi output formatting --- dist/ethereum.js | 2 +- dist/ethereum.js.map | 2 +- dist/ethereum.min.js | 2 +- example/index.html | 53 ++++++++++------------ lib/abi.js | 102 +++++++++++++++++++++++++++++++++++++------ 5 files changed, 115 insertions(+), 46 deletions(-) diff --git a/dist/ethereum.js b/dist/ethereum.js index 8e7d5536bb..decf71e53e 100644 --- a/dist/ethereum.js +++ b/dist/ethereum.js @@ -1,5 +1,5 @@ require=(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;oi&&(code=hex.charCodeAt(i),0!==code);i+=2)str+=String.fromCharCode(parseInt(hex.substr(i,2),16));return str},toDecimal:function(val){return parseInt(val,16)},fromAscii:function(str,pad){pad=void 0===pad?32:pad;for(var hex=this.toHex(str);hex.length<2*pad;)hex+=\"00\";return\"0x\"+hex},eth:{prototype:Object(),watch:function(params){return new Filter(params,ethWatch)}},db:{prototype:Object()},shh:{prototype:Object(),watch:function(params){return new Filter(params,shhWatch)}},on:function(event,id,cb){return void 0===web3._events[event]&&(web3._events[event]={}),web3._events[event][id]=cb,this},off:function(event,id){return void 0!==web3._events[event]&&delete web3._events[event][id],this},trigger:function(event,id,data){var cb,callbacks=web3._events[event];callbacks&&callbacks[id]&&(cb=callbacks[id])(data)}},eth=web3.eth;setupMethods(eth,ethMethods()),setupProperties(eth,ethProperties()),setupMethods(web3.db,dbMethods()),setupMethods(web3.shh,shhMethods()),ethWatch={changed:\"eth_changed\"},setupMethods(ethWatch,ethWatchMethods()),shhWatch={changed:\"shh_changed\"},setupMethods(shhWatch,shhWatchMethods()),ProviderManager=function(){var self,poll;this.queued=[],this.polls=[],this.ready=!1,this.provider=void 0,this.id=1,self=this,(poll=function(){self.provider&&self.provider.poll&&self.polls.forEach(function(data){data.data._id=self.id,self.id++,self.provider.poll(data.data,data.id)}),setTimeout(poll,12e3)})()},ProviderManager.prototype.send=function(data,cb){data._id=this.id,cb&&(web3._callbacks[data._id]=cb),data.args=data.args||[],this.id++,void 0!==this.provider?this.provider.send(data):(console.warn(\"provider is not set\"),this.queued.push(data))},ProviderManager.prototype.set=function(provider){void 0!==this.provider&&void 0!==this.provider.unload&&this.provider.unload(),this.provider=provider,this.ready=!0},ProviderManager.prototype.sendQueued=function(){for(var i=0;this.queued.length;i++)this.send(this.queued[i])},ProviderManager.prototype.installed=function(){return void 0!==this.provider},ProviderManager.prototype.startPolling=function(data,pollId){this.provider&&this.provider.poll&&this.polls.push({data:data,id:pollId})},ProviderManager.prototype.stopPolling=function(pollId){var i,poll;for(i=this.polls.length;i--;)poll=this.polls[i],poll.id===pollId&&this.polls.splice(i,1)},web3.provider=new ProviderManager,web3.setProvider=function(provider){provider.onmessage=messageHandler,web3.provider.set(provider),web3.provider.sendQueued()},web3.haveProvider=function(){return!!web3.provider.provider},Filter=function(options,impl){this.impl=impl,this.callbacks=[];var self=this;this.promise=impl.newFilter(options),this.promise.then(function(id){self.id=id,web3.on(impl.changed,id,self.trigger.bind(self)),web3.provider.startPolling({call:impl.changed,args:[id]},id)})},Filter.prototype.arrived=function(callback){this.changed(callback)},Filter.prototype.changed=function(callback){var self=this;this.promise.then(function(id){self.callbacks.push(callback)})},Filter.prototype.trigger=function(messages){for(var i=0;ir&&(t=e.charCodeAt(r),0!==t);r+=2)n+=String.fromCharCode(parseInt(e.substr(r,2),16));return n},toDecimal:function(e){return parseInt(e,16)},fromAscii:function(e,t){t=void 0===t?32:t;for(var n=this.toHex(e);n.length<2*t;)n+="00";return"0x"+n},eth:{prototype:Object(),watch:function(e){return new a(e,o)}},db:{prototype:Object()},shh:{prototype:Object(),watch:function(e){return new a(e,i)}},on:function(e,t,n){return void 0===g._events[e]&&(g._events[e]={}),g._events[e][t]=n,this},off:function(e,t){return void 0!==g._events[e]&&delete g._events[e][t],this},trigger:function(e,t,n){var r,o=g._events[e];o&&o[t]&&(r=o[t])(n)}},m=g.eth;f(m,c()),v(m,u()),f(g.db,l()),f(g.shh,h()),o={changed:"eth_changed"},f(o,d()),i={changed:"shh_changed"},f(i,p()),s=function(){var e,t;this.queued=[],this.polls=[],this.ready=!1,this.provider=void 0,this.id=1,e=this,(t=function(){e.provider&&e.provider.poll&&e.polls.forEach(function(t){t.data._id=e.id,e.id++,e.provider.poll(t.data,t.id)}),setTimeout(t,12e3)})()},s.prototype.send=function(e,t){e._id=this.id,t&&(g._callbacks[e._id]=t),e.args=e.args||[],this.id++,void 0!==this.provider?this.provider.send(e):(console.warn("provider is not set"),this.queued.push(e))},s.prototype.set=function(e){void 0!==this.provider&&void 0!==this.provider.unload&&this.provider.unload(),this.provider=e,this.ready=!0},s.prototype.sendQueued=function(){for(var e=0;this.queued.length;e++)this.send(this.queued[e])},s.prototype.installed=function(){return void 0!==this.provider},s.prototype.startPolling=function(e,t){this.provider&&this.provider.poll&&this.polls.push({data:e,id:t})},s.prototype.stopPolling=function(e){var t,n;for(t=this.polls.length;t--;)n=this.polls[t],n.id===e&&this.polls.splice(t,1)},g.provider=new s,g.setProvider=function(e){e.onmessage=r,g.provider.set(e),g.provider.sendQueued()},g.haveProvider=function(){return!!g.provider.provider},a=function(e,t){this.impl=t,this.callbacks=[];var n=this;this.promise=t.newFilter(e),this.promise.then(function(e){n.id=e,g.on(t.changed,e,n.trigger.bind(n)),g.provider.startPolling({call:t.changed,args:[e]},e)})},a.prototype.arrived=function(e){this.changed(e)},a.prototype.changed=function(e){var t=this;this.promise.then(function(){t.callbacks.push(e)})},a.prototype.trigger=function(e){for(var t=0;tr&&(t=e.charCodeAt(r),0!==t);r+=2)n+=String.fromCharCode(parseInt(e.substr(r,2),16));return n},toDecimal:function(e){return parseInt(e,16)},fromAscii:function(e,t){t=void 0===t?32:t;for(var n=this.toHex(e);n.length<2*t;)n+="00";return"0x"+n},eth:{prototype:Object(),watch:function(e){return new a(e,o)}},db:{prototype:Object()},shh:{prototype:Object(),watch:function(e){return new a(e,i)}},on:function(e,t,n){return void 0===g._events[e]&&(g._events[e]={}),g._events[e][t]=n,this},off:function(e,t){return void 0!==g._events[e]&&delete g._events[e][t],this},trigger:function(e,t,n){var r,o=g._events[e];o&&o[t]&&(r=o[t])(n)}},m=g.eth;f(m,c()),v(m,u()),f(g.db,l()),f(g.shh,h()),o={changed:"eth_changed"},f(o,d()),i={changed:"shh_changed"},f(i,p()),s=function(){var e,t;this.queued=[],this.polls=[],this.ready=!1,this.provider=void 0,this.id=1,e=this,(t=function(){e.provider&&e.provider.poll&&e.polls.forEach(function(t){t.data._id=e.id,e.id++,e.provider.poll(t.data,t.id)}),setTimeout(t,12e3)})()},s.prototype.send=function(e,t){e._id=this.id,t&&(g._callbacks[e._id]=t),e.args=e.args||[],this.id++,void 0!==this.provider?this.provider.send(e):(console.warn("provider is not set"),this.queued.push(e))},s.prototype.set=function(e){void 0!==this.provider&&void 0!==this.provider.unload&&this.provider.unload(),this.provider=e,this.ready=!0},s.prototype.sendQueued=function(){for(var e=0;this.queued.length;e++)this.send(this.queued[e])},s.prototype.installed=function(){return void 0!==this.provider},s.prototype.startPolling=function(e,t){this.provider&&this.provider.poll&&this.polls.push({data:e,id:t})},s.prototype.stopPolling=function(e){var t,n;for(t=this.polls.length;t--;)n=this.polls[t],n.id===e&&this.polls.splice(t,1)},g.provider=new s,g.setProvider=function(e){e.onmessage=r,g.provider.set(e),g.provider.sendQueued()},g.haveProvider=function(){return!!g.provider.provider},a=function(e,t){this.impl=t,this.callbacks=[];var n=this;this.promise=t.newFilter(e),this.promise.then(function(e){n.id=e,g.on(t.changed,e,n.trigger.bind(n)),g.provider.startPolling({call:t.changed,args:[e]},e)})},a.prototype.arrived=function(e){this.changed(e)},a.prototype.changed=function(e){var t=this;this.promise.then(function(){t.callbacks.push(e)})},a.prototype.trigger=function(e){for(var t=0;t + } + - -

std::name_reg

- - - -
-result:
- +

std::name_reg

+ + +
+ result: +
- + diff --git a/lib/abi.js b/lib/abi.js index 9102454b06..0ac27e6b8a 100644 --- a/lib/abi.js +++ b/lib/abi.js @@ -8,11 +8,17 @@ var findIndex = function (array, callback) { return end ? i - 1 : -1; }; +var findMethodIndex = function (json, methodName) { + return findIndex(json, function (method) { + return method.name === methodName; + }); +}; + var padLeft = function (number, n) { return (new Array(n * 2 - number.toString().length + 1)).join("0") + number; }; -var setupTypes = function () { +var setupInputTypes = function () { var prefixedType = function (prefix) { return function (type, value) { var expected = prefix; @@ -25,32 +31,34 @@ var setupTypes = function () { }; }; - var namedType = function (name, padding) { + var namedType = function (name, padding, formatter) { return function (type, value) { if (type !== name) { return false; } - return padLeft(value, padding); + return padLeft(formatter ? value : formatter(value), padding); }; }; + var formatBool = function (value) { + return value ? '1' : '0'; + }; + return [ prefixedType('uint'), prefixedType('int'), namedType('address', 20), - namedType('bool', 1), + namedType('bool', 1, formatBool), ]; }; -var types = setupTypes(); +var inputTypes = setupInputTypes(); -var toBytes = function (json, methodName, params) { +var toAbiInput = function (json, methodName, params) { var bytes = ""; - var index = findIndex(json, function (method) { - return method.name === methodName; - }); - + var index = findMethodIndex(json, methodName); + if (index === -1) { return; } @@ -62,8 +70,8 @@ var toBytes = function (json, methodName, params) { for (var i = 0; i < method.inputs.length; i++) { var found = false; - for (var j = 0; j < types.length && !found; j++) { - found = types[j](method.inputs[i].type, params[i]); + for (var j = 0; j < inputTypes.length && !found; j++) { + found = inputTypes[j](method.inputs[i].type, params[i]); } if (!found) { console.error('unsupported json type: ' + method.inputs[i].type); @@ -73,7 +81,75 @@ var toBytes = function (json, methodName, params) { return bytes; }; +var setupOutputTypes = function () { + var prefixedType = function (prefix) { + return function (type) { + var expected = prefix; + if (type.indexOf(expected) !== 0) { + return -1; + } + + var padding = parseInt(type.slice(expected.length)) / 8; + return padding * 2; + }; + }; + + var namedType = function (name, padding) { + return function (type) { + return name === type ? padding * 2: -1; + }; + }; + + var formatInt = function (value) { + return parseInt(value, 16); + }; + + var formatBool = function (value) { + return value === '1' ? true : false; + }; + + return [ + { padding: prefixedType('uint'), format: formatInt }, + { padding: prefixedType('int'), format: formatInt }, + { padding: namedType('address', 20) }, + { padding: namedType('bool', 1), format: formatBool } + ]; +}; + +var outputTypes = setupOutputTypes(); + +var fromAbiOutput = function (json, methodName, output) { + var index = findMethodIndex(json, methodName); + + if (index === -1) { + return; + } + + output = output.slice(2); + + var result = []; + var method = json[index]; + for (var i = 0; i < method.outputs.length; i++) { + var padding = -1; + for (var j = 0; j < outputTypes.length && padding === -1; j++) { + padding = outputTypes[j].padding(method.outputs[i].type); + } + + if (padding === -1) { + // not found output parsing + continue; + } + var res = output.slice(0, padding); + var formatter = outputTypes[j - 1].format; + result.push(formatter ? formatter(res): res); + output = output.slice(padding); + } + + return result; +}; + module.exports = { - toBytes: toBytes + toAbiInput: toAbiInput, + fromAbiOutput: fromAbiOutput };