From 1e2c1ae98a610d346c9ebe50fa00c4eb08955abd Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Sat, 17 Jan 2015 13:39:19 +0100 Subject: output parser string support --- dist/ethereum.js | 129 ++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 79 insertions(+), 50 deletions(-) (limited to 'dist/ethereum.js') diff --git a/dist/ethereum.js b/dist/ethereum.js index 8a396c21f..8062c7daf 100644 --- a/dist/ethereum.js +++ b/dist/ethereum.js @@ -158,6 +158,7 @@ var toAbiInput = function (json, methodName, params) { var method = json[index]; var padding = ETH_PADDING * 2; + /// first we iterate in search for dynamic method.inputs.forEach(function (input, index) { bytes += dynamicTypeBytes(input.type, params[index]); }); @@ -186,57 +187,63 @@ var toAbiInput = function (json, methodName, params) { return bytes; }; -/// Setups output formaters for solidity types -/// @returns an array of output formatters -var setupOutputTypes = function () { +/// Formats input right-aligned input bytes to int +/// @returns right-aligned input bytes formatted to int +var formatOutputInt = function (value) { + // check if it's negative number + // it it is, return two's complement + var firstBit = new BigNumber(value.substr(0, 1), 16).toString(2).substr(0, 1); + if (firstBit === '1') { + return new BigNumber(value, 16).minus(new BigNumber('ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff', 16)).minus(1); + } + return new BigNumber(value, 16); +}; - /// Formats input right-aligned input bytes to int - /// @returns right-aligned input bytes formatted to int - var formatInt = function (value) { - // check if it's negative number - // it it is, return two's complement - var firstBit = new BigNumber(value.substr(0, 1), 16).toString(2).substr(0, 1); - if (firstBit === '1') { - 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) { + return new BigNumber(value, 16); +}; - /// Formats big right-aligned input bytes to uint - /// @returns right-aligned input bytes formatted to uint - var formatUInt = function (value) { - return new BigNumber(value, 16); - }; +/// @returns right-aligned input bytes formatted to hex +var formatOutputHash = function (value) { + return "0x" + value; +}; - /// @returns right-aligned input bytes formatted to hex - var formatHash = function (value) { - return "0x" + value; - }; +/// @returns right-aligned input bytes formatted to bool +var formatOutputBool = function (value) { + return value === '0000000000000000000000000000000000000000000000000000000000000001' ? true : false; +}; - /// @returns right-aligned input bytes formatted to bool - var formatBool = 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 left-aligned input bytes formatted to ascii string - var formatString = 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); +}; - /// @returns right-aligned input bytes formatted to address - var formatAddress = function (value) { - return "0x" + value.slice(value.length - 40, value.length); - }; +var dynamicBytesLength = function (type) { + if (arrayType(type) || prefixedType('string')(type)) + return ETH_PADDING * 2; + return 0; +}; + +/// Setups output formaters for solidity types +/// @returns an array of output formatters +var setupOutputTypes = function () { return [ - { type: prefixedType('uint'), format: formatUInt }, - { type: prefixedType('int'), format: formatInt }, - { type: prefixedType('hash'), format: formatHash }, - { type: prefixedType('string'), format: formatString }, - { type: prefixedType('real'), format: formatInt }, - { type: prefixedType('ureal'), format: formatInt }, - { type: namedType('address'), format: formatAddress }, - { type: namedType('bool'), format: formatBool } + { type: prefixedType('uint'), format: formatOutputUInt }, + { type: prefixedType('int'), format: formatOutputInt }, + { type: prefixedType('hash'), format: formatOutputHash }, + { type: prefixedType('string'), format: formatOutputString }, + { type: prefixedType('real'), format: formatOutputInt }, + { type: prefixedType('ureal'), format: formatOutputInt }, + { type: namedType('address'), format: formatOutputAddress }, + { type: namedType('bool'), format: formatOutputBool } ]; }; @@ -259,22 +266,44 @@ var fromAbiOutput = function (json, methodName, output) { var result = []; var method = json[index]; var padding = ETH_PADDING * 2; - for (var i = 0; i < method.outputs.length; i++) { + + var dynamicPartLength = method.outputs.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) { var typeMatch = false; for (var j = 0; j < outputTypes.length && !typeMatch; j++) { typeMatch = outputTypes[j].type(method.outputs[i].type); } if (!typeMatch) { - // not found output parsing console.error('output parser does not support type: ' + method.outputs[i].type); - continue; } - var res = output.slice(0, padding); + var formatter = outputTypes[j - 1].format; - result.push(formatter ? formatter(res) : ("0x" + res)); - output = output.slice(padding); - } + if (arrayType(method.outputs[i].type)) { + var size = formatOutputUInt(dynamicPart.slice(0, padding)); + dynamicPart = dynamicPart.slice(padding); + var array = []; + for (var k = 0; k < size; k++) { + array.push(formatter(output.slice(0, padding))); + output = output.slice(padding); + } + result.push(array); + } + else if (prefixedType('string')(method.outputs[i].type)) { + dynamicPart = dynamicPart.slice(padding); + result.push(formatter(output.slice(0, padding))); + output = output.slice(padding); + } else { + result.push(formatter(output.slice(0, padding))); + output = output.slice(padding); + } + }); return result; }; -- cgit v1.2.3