From 56890862028cc1e6d0fb58db9ada358bf4384de0 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Sat, 31 Jan 2015 01:52:36 +0100 Subject: formatters separated --- lib/abi.js | 142 ++++++++++--------------------------------------------------- 1 file changed, 23 insertions(+), 119 deletions(-) (limited to 'lib/abi.js') diff --git a/lib/abi.js b/lib/abi.js index a0c862593..fbf72b12d 100644 --- a/lib/abi.js +++ b/lib/abi.js @@ -21,12 +21,12 @@ * @date 2014 */ -// TODO: is these line is supposed to be here? if (process.env.NODE_ENV !== 'build') { var BigNumber = require('bignumber.js'); // jshint ignore:line } -var web3 = require('./web3'); // jshint ignore:line +var web3 = require('./web3'); +var f = require('./formatters'); BigNumber.config({ ROUNDING_MODE: BigNumber.ROUND_DOWN }); @@ -85,6 +85,7 @@ var filterEvents = function (json) { /// @param number of characters that result string should have /// @param sign, by default 0 /// @returns right aligned string +/// TODO: remove, it was moved to formatters.js var padLeft = function (string, chars, sign) { return new Array(chars - string.length + 1).join(sign ? sign : "0") + string; }; @@ -105,57 +106,16 @@ var namedType = function (name) { }; }; +/// This method should be called if we want to check if givent type is an array type +/// @returns true if it is, otherwise false var arrayType = function (type) { return type.slice(-2) === '[]'; }; -/// Formats input value to byte representation of int -/// If value is negative, return it's two's complement -/// If the value is floating point, round it down -/// @returns right-aligned byte representation of int -var formatInputInt = function (value) { - var padding = ETH_PADDING * 2; - if (value instanceof BigNumber || typeof value === 'number') { - if (typeof value === 'number') - value = new BigNumber(value); - value = value.round(); - - if (value.lessThan(0)) - value = new BigNumber("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 16).plus(value).plus(1); - value = value.toString(16); - } - else if (value.indexOf('0x') === 0) - value = value.substr(2); - else if (typeof value === 'string') - value = formatInputInt(new BigNumber(value)); - else - value = (+value).toString(16); - return padLeft(value, padding); -}; - -/// Formats input value to byte representation of string -/// @returns left-algined byte representation of string -var formatInputString = function (value) { - return web3.fromAscii(value, ETH_PADDING).substr(2); -}; - -/// Formats input value to byte representation of bool -/// @returns right-aligned byte representation bool -var formatInputBool = function (value) { - return '000000000000000000000000000000000000000000000000000000000000000' + (value ? '1' : '0'); -}; - -/// Formats input value to byte representation of real -/// Values are multiplied by 2^m and encoded as integers -/// @returns byte representation of real -var formatInputReal = function (value) { - return formatInputInt(new BigNumber(value).times(new BigNumber(2).pow(128))); -}; - var dynamicTypeBytes = function (type, value) { // TODO: decide what to do with array of strings if (arrayType(type) || type === 'string') // only string itself that is dynamic; stringX is static length. - return formatInputInt(value.length); + return f.formatInputInt(value.length); return ""; }; @@ -164,14 +124,14 @@ var dynamicTypeBytes = function (type, value) { var setupInputTypes = function () { return [ - { type: prefixedType('uint'), format: formatInputInt }, - { type: prefixedType('int'), format: formatInputInt }, - { type: prefixedType('hash'), format: formatInputInt }, - { type: prefixedType('string'), format: formatInputString }, - { type: prefixedType('real'), format: formatInputReal }, - { type: prefixedType('ureal'), format: formatInputReal }, - { type: namedType('address'), format: formatInputInt }, - { type: namedType('bool'), format: formatInputBool } + { type: prefixedType('uint'), format: f.formatInputInt }, + { type: prefixedType('int'), format: f.formatInputInt }, + { type: prefixedType('hash'), format: f.formatInputInt }, + { type: prefixedType('string'), format: f.formatInputString }, + { type: prefixedType('real'), format: f.formatInputReal }, + { type: prefixedType('ureal'), format: f.formatInputReal }, + { type: namedType('address'), format: f.formatInputInt }, + { type: namedType('bool'), format: f.formatInputBool } ]; }; @@ -217,62 +177,6 @@ var toAbiInput = function (json, methodName, params) { return bytes; }; -/// Check if input value is negative -/// @param value is hex format -/// @returns true if it is negative, otherwise false -var signedIsNegative = function (value) { - return (new BigNumber(value.substr(0, 1), 16).toString(2).substr(0, 1)) === '1'; -}; - -/// Formats input right-aligned input bytes to int -/// @returns right-aligned input bytes formatted to int -var formatOutputInt = function (value) { - value = value || "0"; - // check if it's negative number - // it it is, return two's complement - if (signedIsNegative(value)) { - return new BigNumber(value, 16).minus(new BigNumber('ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff', 16)).minus(1); - } - return new BigNumber(value, 16); -}; - -/// Formats big right-aligned input bytes to uint -/// @returns right-aligned input bytes formatted to uint -var formatOutputUInt = function (value) { - value = value || "0"; - return new BigNumber(value, 16); -}; - -/// @returns input bytes formatted to real -var formatOutputReal = function (value) { - return formatOutputInt(value).dividedBy(new BigNumber(2).pow(128)); -}; - -/// @returns input bytes formatted to ureal -var formatOutputUReal = function (value) { - return formatOutputUInt(value).dividedBy(new BigNumber(2).pow(128)); -}; - -/// @returns right-aligned input bytes formatted to hex -var formatOutputHash = function (value) { - return "0x" + value; -}; - -/// @returns right-aligned input bytes formatted to bool -var formatOutputBool = function (value) { - return value === '0000000000000000000000000000000000000000000000000000000000000001' ? true : false; -}; - -/// @returns left-aligned input bytes formatted to ascii string -var formatOutputString = function (value) { - return web3.toAscii(value); -}; - -/// @returns right-aligned input bytes formatted to address -var formatOutputAddress = function (value) { - return "0x" + value.slice(value.length - 40, value.length); -}; - var dynamicBytesLength = function (type) { if (arrayType(type) || type === 'string') // only string itself that is dynamic; stringX is static length. return ETH_PADDING * 2; @@ -284,14 +188,14 @@ var dynamicBytesLength = function (type) { var setupOutputTypes = function () { return [ - { type: prefixedType('uint'), format: formatOutputUInt }, - { type: prefixedType('int'), format: formatOutputInt }, - { type: prefixedType('hash'), format: formatOutputHash }, - { type: prefixedType('string'), format: formatOutputString }, - { type: prefixedType('real'), format: formatOutputReal }, - { type: prefixedType('ureal'), format: formatOutputUReal }, - { type: namedType('address'), format: formatOutputAddress }, - { type: namedType('bool'), format: formatOutputBool } + { type: prefixedType('uint'), format: f.formatOutputUInt }, + { type: prefixedType('int'), format: f.formatOutputInt }, + { type: prefixedType('hash'), format: f.formatOutputHash }, + { type: prefixedType('string'), format: f.formatOutputString }, + { type: prefixedType('real'), format: f.formatOutputReal }, + { type: prefixedType('ureal'), format: f.formatOutputUReal }, + { type: namedType('address'), format: f.formatOutputAddress }, + { type: namedType('bool'), format: f.formatOutputBool } ]; }; @@ -328,7 +232,7 @@ var fromAbiOutput = function (json, methodName, output) { var formatter = outputTypes[j - 1].format; if (arrayType(method.outputs[i].type)) { - var size = formatOutputUInt(dynamicPart.slice(0, padding)); + var size = f.formatOutputUInt(dynamicPart.slice(0, padding)); dynamicPart = dynamicPart.slice(padding); var array = []; for (var k = 0; k < size; k++) { -- cgit v1.2.3 From 2491c99b37241b8770bca516d5641b2d00a7a660 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Sat, 31 Jan 2015 02:54:17 +0100 Subject: abi.js cleanup && new types.js, utils.js --- lib/abi.js | 85 +++++++------------------------------------------------------- 1 file changed, 9 insertions(+), 76 deletions(-) (limited to 'lib/abi.js') diff --git a/lib/abi.js b/lib/abi.js index fbf72b12d..fcf787419 100644 --- a/lib/abi.js +++ b/lib/abi.js @@ -26,6 +26,8 @@ if (process.env.NODE_ENV !== 'build') { } var web3 = require('./web3'); +var utils = require('./utils'); +var types = require('./types'); var f = require('./formatters'); BigNumber.config({ ROUNDING_MODE: BigNumber.ROUND_DOWN }); @@ -35,22 +37,9 @@ var ETH_PADDING = 32; /// method signature length in bytes var ETH_METHOD_SIGNATURE_LENGTH = 4; -/// Finds first index of array element matching pattern -/// @param array -/// @param callback pattern -/// @returns index of element -var findIndex = function (array, callback) { - var end = false; - var i = 0; - for (; i < array.length && !end; i++) { - end = callback(array[i]); - } - return end ? i - 1 : -1; -}; - /// @returns a function that is used as a pattern for 'findIndex' var findMethodIndex = function (json, methodName) { - return findIndex(json, function (method) { + return utils.findIndex(json, function (method) { return method.name === methodName; }); }; @@ -81,31 +70,6 @@ var filterEvents = function (json) { }); }; -/// @param string string to be padded -/// @param number of characters that result string should have -/// @param sign, by default 0 -/// @returns right aligned string -/// TODO: remove, it was moved to formatters.js -var padLeft = function (string, chars, sign) { - return new Array(chars - string.length + 1).join(sign ? sign : "0") + string; -}; - -/// @param expected type prefix (string) -/// @returns function which checks if type has matching prefix. if yes, returns true, otherwise false -var prefixedType = function (prefix) { - return function (type) { - return type.indexOf(prefix) === 0; - }; -}; - -/// @param expected type name (string) -/// @returns function which checks if type is matching expected one. if yes, returns true, otherwise false -var namedType = function (name) { - return function (type) { - return name === type; - }; -}; - /// This method should be called if we want to check if givent type is an array type /// @returns true if it is, otherwise false var arrayType = function (type) { @@ -119,23 +83,7 @@ var dynamicTypeBytes = function (type, value) { return ""; }; -/// Setups input formatters for solidity types -/// @returns an array of input formatters -var setupInputTypes = function () { - - return [ - { type: prefixedType('uint'), format: f.formatInputInt }, - { type: prefixedType('int'), format: f.formatInputInt }, - { type: prefixedType('hash'), format: f.formatInputInt }, - { type: prefixedType('string'), format: f.formatInputString }, - { type: prefixedType('real'), format: f.formatInputReal }, - { type: prefixedType('ureal'), format: f.formatInputReal }, - { type: namedType('address'), format: f.formatInputInt }, - { type: namedType('bool'), format: f.formatInputBool } - ]; -}; - -var inputTypes = setupInputTypes(); +var inputTypes = types.inputTypes(); /// Formats input params to bytes /// @param contract json abi @@ -183,23 +131,7 @@ var dynamicBytesLength = function (type) { return 0; }; -/// Setups output formaters for solidity types -/// @returns an array of output formatters -var setupOutputTypes = function () { - - return [ - { type: prefixedType('uint'), format: f.formatOutputUInt }, - { type: prefixedType('int'), format: f.formatOutputInt }, - { type: prefixedType('hash'), format: f.formatOutputHash }, - { type: prefixedType('string'), format: f.formatOutputString }, - { type: prefixedType('real'), format: f.formatOutputReal }, - { type: prefixedType('ureal'), format: f.formatOutputUReal }, - { type: namedType('address'), format: f.formatOutputAddress }, - { type: namedType('bool'), format: f.formatOutputBool } - ]; -}; - -var outputTypes = setupOutputTypes(); +var outputTypes = types.outputTypes(); /// Formats output bytes back to param list /// @param contract json abi @@ -241,7 +173,7 @@ var fromAbiOutput = function (json, methodName, output) { } result.push(array); } - else if (prefixedType('string')(method.outputs[i].type)) { + else if (types.prefixedType('string')(method.outputs[i].type)) { dynamicPart = dynamicPart.slice(padding); result.push(formatter(output.slice(0, padding))); output = output.slice(padding); @@ -269,9 +201,10 @@ var methodTypeName = function (method) { /// @param json abi for contract /// @returns input parser object for given json abi +/// TODO: refactor creating the parser, do not double logic from contract var inputParser = function (json) { var parser = {}; - filterFunctions(json).forEach(function (method) { + json.forEach(function (method) { var displayName = methodDisplayName(method.name); var typeName = methodTypeName(method.name); @@ -294,7 +227,7 @@ var inputParser = function (json) { /// @returns output parser for given json abi var outputParser = function (json) { var parser = {}; - filterFunctions(json).forEach(function (method) { + json.forEach(function (method) { var displayName = methodDisplayName(method.name); var typeName = methodTypeName(method.name); -- cgit v1.2.3 From 4bdf52fc1e5030d53a8b7337051e12ebd0509009 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Sat, 31 Jan 2015 13:54:39 +0100 Subject: toAscii && fromAscii moved to utils --- lib/abi.js | 37 +++++++------------------------------ 1 file changed, 7 insertions(+), 30 deletions(-) (limited to 'lib/abi.js') diff --git a/lib/abi.js b/lib/abi.js index fcf787419..1fd3a58fc 100644 --- a/lib/abi.js +++ b/lib/abi.js @@ -37,23 +37,6 @@ var ETH_PADDING = 32; /// method signature length in bytes var ETH_METHOD_SIGNATURE_LENGTH = 4; -/// @returns a function that is used as a pattern for 'findIndex' -var findMethodIndex = function (json, methodName) { - return utils.findIndex(json, function (method) { - return method.name === methodName; - }); -}; - -/// @returns method with given method name -var getMethodWithName = function (json, methodName) { - var index = findMethodIndex(json, methodName); - if (index === -1) { - console.error('method ' + methodName + ' not found in the abi'); - return undefined; - } - return json[index]; -}; - /// Filters all function from input abi /// @returns abi array with filtered objects of type 'function' var filterFunctions = function (json) { @@ -86,14 +69,11 @@ var dynamicTypeBytes = function (type, value) { var inputTypes = types.inputTypes(); /// Formats input params to bytes -/// @param contract json abi -/// @param name of the method that we want to use +/// @param abi contract method /// @param array of params that will be formatted to bytes /// @returns bytes representation of input params -var toAbiInput = function (json, methodName, params) { +var toAbiInput = function (method, params) { var bytes = ""; - - var method = getMethodWithName(json, methodName); var padding = ETH_PADDING * 2; /// first we iterate in search for dynamic @@ -134,15 +114,13 @@ var dynamicBytesLength = function (type) { var outputTypes = types.outputTypes(); /// Formats output bytes back to param list -/// @param contract json abi -/// @param name of the method that we want to use +/// @param contract abi method /// @param bytes representtion of output /// @returns array of output params -var fromAbiOutput = function (json, methodName, output) { +var fromAbiOutput = function (method, output) { output = output.slice(2); var result = []; - var method = getMethodWithName(json, methodName); var padding = ETH_PADDING * 2; var dynamicPartLength = method.outputs.reduce(function (acc, curr) { @@ -194,7 +172,7 @@ var methodDisplayName = function (method) { /// @returns overloaded part of method's name var methodTypeName = function (method) { - /// TODO: make it not vulnerable + /// TODO: make it invulnerable var length = method.indexOf('('); return length !== -1 ? method.substr(length + 1, method.length - 1 - (length + 1)) : ""; }; @@ -210,7 +188,7 @@ var inputParser = function (json) { var impl = function () { var params = Array.prototype.slice.call(arguments); - return toAbiInput(json, method.name, params); + return toAbiInput(method, params); }; if (parser[displayName] === undefined) { @@ -233,7 +211,7 @@ var outputParser = function (json) { var typeName = methodTypeName(method.name); var impl = function (output) { - return fromAbiOutput(json, method.name, output); + return fromAbiOutput(method, output); }; if (parser[displayName] === undefined) { @@ -258,7 +236,6 @@ module.exports = { methodSignature: methodSignature, methodDisplayName: methodDisplayName, methodTypeName: methodTypeName, - getMethodWithName: getMethodWithName, filterFunctions: filterFunctions, filterEvents: filterEvents }; -- cgit v1.2.3 From a8a2e3231c2ced50989dc5d23659f7482a667f69 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Sat, 31 Jan 2015 14:05:48 +0100 Subject: constants separated to const.js file --- lib/abi.js | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) (limited to 'lib/abi.js') diff --git a/lib/abi.js b/lib/abi.js index 1fd3a58fc..01d2debb7 100644 --- a/lib/abi.js +++ b/lib/abi.js @@ -21,22 +21,12 @@ * @date 2014 */ -if (process.env.NODE_ENV !== 'build') { - var BigNumber = require('bignumber.js'); // jshint ignore:line -} - var web3 = require('./web3'); var utils = require('./utils'); var types = require('./types'); +var c = require('./const'); var f = require('./formatters'); -BigNumber.config({ ROUNDING_MODE: BigNumber.ROUND_DOWN }); - -var ETH_PADDING = 32; - -/// method signature length in bytes -var ETH_METHOD_SIGNATURE_LENGTH = 4; - /// Filters all function from input abi /// @returns abi array with filtered objects of type 'function' var filterFunctions = function (json) { @@ -74,7 +64,7 @@ var inputTypes = types.inputTypes(); /// @returns bytes representation of input params var toAbiInput = function (method, params) { var bytes = ""; - var padding = ETH_PADDING * 2; + var padding = c.ETH_PADDING * 2; /// first we iterate in search for dynamic method.inputs.forEach(function (input, index) { @@ -107,7 +97,7 @@ var toAbiInput = function (method, params) { var dynamicBytesLength = function (type) { if (arrayType(type) || type === 'string') // only string itself that is dynamic; stringX is static length. - return ETH_PADDING * 2; + return c.ETH_PADDING * 2; return 0; }; @@ -121,7 +111,7 @@ var fromAbiOutput = function (method, output) { output = output.slice(2); var result = []; - var padding = ETH_PADDING * 2; + var padding = c.ETH_PADDING * 2; var dynamicPartLength = method.outputs.reduce(function (acc, curr) { return acc + dynamicBytesLength(curr.type); @@ -227,7 +217,7 @@ var outputParser = function (json) { /// @param method name for which we want to get method signature /// @returns (promise) contract method signature for method with given name var methodSignature = function (name) { - return web3.sha3(web3.fromAscii(name)).slice(0, 2 + ETH_METHOD_SIGNATURE_LENGTH * 2); + return web3.sha3(web3.fromAscii(name)).slice(0, 2 + c.ETH_METHOD_SIGNATURE_LENGTH * 2); }; module.exports = { -- cgit v1.2.3 From b20e972bec52781de806fb050e72d44b729c6541 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Sat, 31 Jan 2015 15:22:05 +0100 Subject: few methods moved to utils --- lib/abi.js | 51 +++++++++------------------------------------------ 1 file changed, 9 insertions(+), 42 deletions(-) (limited to 'lib/abi.js') diff --git a/lib/abi.js b/lib/abi.js index 01d2debb7..8121c1a05 100644 --- a/lib/abi.js +++ b/lib/abi.js @@ -27,22 +27,6 @@ var types = require('./types'); var c = require('./const'); var f = require('./formatters'); -/// Filters all function from input abi -/// @returns abi array with filtered objects of type 'function' -var filterFunctions = function (json) { - return json.filter(function (current) { - return current.type === 'function'; - }); -}; - -/// Filters all events form input abi -/// @returns abi array with filtered objects of type 'event' -var filterEvents = function (json) { - return json.filter(function (current) { - return current.type === 'event'; - }); -}; - /// This method should be called if we want to check if givent type is an array type /// @returns true if it is, otherwise false var arrayType = function (type) { @@ -154,27 +138,14 @@ var fromAbiOutput = function (method, output) { return result; }; -/// @returns display name for method eg. multiply(uint256) -> multiply -var methodDisplayName = function (method) { - var length = method.indexOf('('); - return length !== -1 ? method.substr(0, length) : method; -}; - -/// @returns overloaded part of method's name -var methodTypeName = function (method) { - /// TODO: make it invulnerable - var length = method.indexOf('('); - return length !== -1 ? method.substr(length + 1, method.length - 1 - (length + 1)) : ""; -}; - /// @param json abi for contract /// @returns input parser object for given json abi /// TODO: refactor creating the parser, do not double logic from contract var inputParser = function (json) { var parser = {}; json.forEach(function (method) { - var displayName = methodDisplayName(method.name); - var typeName = methodTypeName(method.name); + var displayName = utils.extractDisplayName(method.name); + var typeName = utils.extractTypeName(method.name); var impl = function () { var params = Array.prototype.slice.call(arguments); @@ -197,8 +168,8 @@ var outputParser = function (json) { var parser = {}; json.forEach(function (method) { - var displayName = methodDisplayName(method.name); - var typeName = methodTypeName(method.name); + var displayName = utils.extractDisplayName(method.name); + var typeName = utils.extractTypeName(method.name); var impl = function (output) { return fromAbiOutput(method, output); @@ -214,19 +185,15 @@ var outputParser = function (json) { return parser; }; -/// @param method name for which we want to get method signature -/// @returns (promise) contract method signature for method with given name -var methodSignature = function (name) { - return web3.sha3(web3.fromAscii(name)).slice(0, 2 + c.ETH_METHOD_SIGNATURE_LENGTH * 2); +/// @param function/event name for which we want to get signature +/// @returns signature of function/event with given name +var signatureFromAscii = function (name) { + return web3.sha3(web3.fromAscii(name)).slice(0, 2 + c.ETH_SIGNATURE_LENGTH * 2); }; module.exports = { inputParser: inputParser, outputParser: outputParser, - methodSignature: methodSignature, - methodDisplayName: methodDisplayName, - methodTypeName: methodTypeName, - filterFunctions: filterFunctions, - filterEvents: filterEvents + signatureFromAscii: signatureFromAscii }; -- cgit v1.2.3 From 589c4fb30f2e68972b898c5ce084cda5b0831266 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Sat, 31 Jan 2015 15:48:49 +0100 Subject: formatInput && formatOutput simplified --- lib/abi.js | 40 +++++++++++++++++++++++----------------- 1 file changed, 23 insertions(+), 17 deletions(-) (limited to 'lib/abi.js') diff --git a/lib/abi.js b/lib/abi.js index 8121c1a05..ecff1e5d6 100644 --- a/lib/abi.js +++ b/lib/abi.js @@ -27,6 +27,10 @@ var types = require('./types'); var c = require('./const'); var f = require('./formatters'); +var displayTypeError = function (type) { + console.error('parser does not support type: ' + type); +}; + /// This method should be called if we want to check if givent type is an array type /// @returns true if it is, otherwise false var arrayType = function (type) { @@ -43,31 +47,31 @@ var dynamicTypeBytes = function (type, value) { var inputTypes = types.inputTypes(); /// Formats input params to bytes -/// @param abi contract method +/// @param abi contract method inputs /// @param array of params that will be formatted to bytes /// @returns bytes representation of input params -var toAbiInput = function (method, params) { +var formatInput = function (inputs, params) { var bytes = ""; var padding = c.ETH_PADDING * 2; /// first we iterate in search for dynamic - method.inputs.forEach(function (input, index) { + inputs.forEach(function (input, index) { bytes += dynamicTypeBytes(input.type, params[index]); }); - method.inputs.forEach(function (input, i) { + inputs.forEach(function (input, i) { var typeMatch = false; for (var j = 0; j < inputTypes.length && !typeMatch; j++) { - typeMatch = inputTypes[j].type(method.inputs[i].type, params[i]); + typeMatch = inputTypes[j].type(inputs[i].type, params[i]); } if (!typeMatch) { - console.error('input parser does not support type: ' + method.inputs[i].type); + displayTypeError(inputs[i].type); } var formatter = inputTypes[j - 1].format; var toAppend = ""; - if (arrayType(method.inputs[i].type)) + if (arrayType(inputs[i].type)) toAppend = params[i].reduce(function (acc, curr) { return acc + formatter(curr); }, ""); @@ -88,34 +92,34 @@ var dynamicBytesLength = function (type) { var outputTypes = types.outputTypes(); /// Formats output bytes back to param list -/// @param contract abi method +/// @param contract abi method outputs /// @param bytes representtion of output /// @returns array of output params -var fromAbiOutput = function (method, output) { +var formatOutput = function (outs, output) { output = output.slice(2); var result = []; var padding = c.ETH_PADDING * 2; - var dynamicPartLength = method.outputs.reduce(function (acc, curr) { + var dynamicPartLength = outs.reduce(function (acc, curr) { return acc + dynamicBytesLength(curr.type); }, 0); var dynamicPart = output.slice(0, dynamicPartLength); output = output.slice(dynamicPartLength); - method.outputs.forEach(function (out, i) { + outs.forEach(function (out, i) { var typeMatch = false; for (var j = 0; j < outputTypes.length && !typeMatch; j++) { - typeMatch = outputTypes[j].type(method.outputs[i].type); + typeMatch = outputTypes[j].type(outs[i].type); } if (!typeMatch) { - console.error('output parser does not support type: ' + method.outputs[i].type); + displayTypeError(outs[i].type); } var formatter = outputTypes[j - 1].format; - if (arrayType(method.outputs[i].type)) { + if (arrayType(outs[i].type)) { var size = f.formatOutputUInt(dynamicPart.slice(0, padding)); dynamicPart = dynamicPart.slice(padding); var array = []; @@ -125,7 +129,7 @@ var fromAbiOutput = function (method, output) { } result.push(array); } - else if (types.prefixedType('string')(method.outputs[i].type)) { + else if (types.prefixedType('string')(outs[i].type)) { dynamicPart = dynamicPart.slice(padding); result.push(formatter(output.slice(0, padding))); output = output.slice(padding); @@ -149,7 +153,7 @@ var inputParser = function (json) { var impl = function () { var params = Array.prototype.slice.call(arguments); - return toAbiInput(method, params); + return formatInput(method.inputs, params); }; if (parser[displayName] === undefined) { @@ -172,7 +176,7 @@ var outputParser = function (json) { var typeName = utils.extractTypeName(method.name); var impl = function (output) { - return fromAbiOutput(method, output); + return formatOutput(method.outputs, output); }; if (parser[displayName] === undefined) { @@ -194,6 +198,8 @@ var signatureFromAscii = function (name) { module.exports = { inputParser: inputParser, outputParser: outputParser, + formatInput: formatInput, + formatOutput: formatOutput, signatureFromAscii: signatureFromAscii }; -- cgit v1.2.3