diff options
author | Marek Kotewicz <marek.kotewicz@gmail.com> | 2015-01-17 20:39:19 +0800 |
---|---|---|
committer | Marek Kotewicz <marek.kotewicz@gmail.com> | 2015-01-17 20:39:19 +0800 |
commit | 1e2c1ae98a610d346c9ebe50fa00c4eb08955abd (patch) | |
tree | 7ea342677edbe2b7c66582eff56787b4542db0e1 /lib/abi.js | |
parent | b457e88cd0fbc5724cbca68ecebf5e829c65bf98 (diff) | |
download | go-tangerine-1e2c1ae98a610d346c9ebe50fa00c4eb08955abd.tar go-tangerine-1e2c1ae98a610d346c9ebe50fa00c4eb08955abd.tar.gz go-tangerine-1e2c1ae98a610d346c9ebe50fa00c4eb08955abd.tar.bz2 go-tangerine-1e2c1ae98a610d346c9ebe50fa00c4eb08955abd.tar.lz go-tangerine-1e2c1ae98a610d346c9ebe50fa00c4eb08955abd.tar.xz go-tangerine-1e2c1ae98a610d346c9ebe50fa00c4eb08955abd.tar.zst go-tangerine-1e2c1ae98a610d346c9ebe50fa00c4eb08955abd.zip |
output parser string support
Diffstat (limited to 'lib/abi.js')
-rw-r--r-- | lib/abi.js | 128 |
1 files changed, 78 insertions, 50 deletions
diff --git a/lib/abi.js b/lib/abi.js index 2c0fe92e0..319b06066 100644 --- a/lib/abi.js +++ b/lib/abi.js @@ -186,57 +186,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 +265,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; }; |