From 7595a5dfcbd8eb58e1ab384ea412877d0f387ef4 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Tue, 13 Jan 2015 11:15:44 +0100 Subject: removed padding calculation from ethereum.js, padding is always 32 --- lib/abi.js | 83 ++++++++++++++++++-------------------------------------------- 1 file changed, 24 insertions(+), 59 deletions(-) (limited to 'lib/abi.js') diff --git a/lib/abi.js b/lib/abi.js index cae4f7519..49126338a 100644 --- a/lib/abi.js +++ b/lib/abi.js @@ -54,47 +54,16 @@ var padLeft = function (string, chars) { return new Array(chars - string.length + 1).join("0") + string; }; -var calcBitPadding = function (type, expected) { - var value = type.slice(expected.length); - if (value === "") { - return 32; - } - return parseInt(value) / 8; -}; - -var calcBytePadding = function (type, expected) { - var value = type.slice(expected.length); - if (value === "") { - return 32; - } - return parseInt(value); -}; - -var calcRealPadding = function (type, expected) { - var value = type.slice(expected.length); - if (value === "") { - return 32; - } - var sizes = value.split('x'); - for (var padding = 0, i = 0; i < sizes; i++) { - padding += (sizes[i] / 8); - } - return padding; -}; - var setupInputTypes = function () { - var prefixedType = function (prefix, calcPadding) { + var prefixedType = function (prefix) { return function (type, value) { var expected = prefix; if (type.indexOf(expected) !== 0) { return false; } - var padding = calcPadding(type, expected); - if (padding > 32) - return false; // not allowed to be so big. - padding = 32; // override as per the new ABI. + var padding = 32; // override as per the new ABI. if (prefix === "string") return web3.fromAscii(value, padding).substr(2); @@ -110,13 +79,13 @@ var setupInputTypes = function () { }; }; - var namedType = function (name, padding, formatter) { + var namedType = function (name, formatter) { return function (type, value) { if (type !== name) { return false; } - padding = 32; //override as per the new ABI. + var padding = 32; //override as per the new ABI. return padLeft(formatter ? formatter(value) : value, padding * 2); }; @@ -127,14 +96,14 @@ var setupInputTypes = function () { }; return [ - prefixedType('uint', calcBitPadding), - prefixedType('int', calcBitPadding), - prefixedType('hash', calcBitPadding), - prefixedType('string', calcBytePadding), - prefixedType('real', calcRealPadding), - prefixedType('ureal', calcRealPadding), - namedType('address', 20), - namedType('bool', 1, formatBool), + prefixedType('uint'), + prefixedType('int'), + prefixedType('hash'), + prefixedType('string'), + prefixedType('real'), + prefixedType('ureal'), + namedType('address'), + namedType('bool', formatBool), ]; }; @@ -165,24 +134,20 @@ var toAbiInput = function (json, methodName, params) { var setupOutputTypes = function () { - var prefixedType = function (prefix, calcPadding) { + var prefixedType = function (prefix) { return function (type) { var expected = prefix; if (type.indexOf(expected) !== 0) { return -1; } - - var padding = calcPadding(type, expected); - if (padding > 32) - return -1; // not allowed to be so big. - padding = 32; // override as per the new ABI. + var padding = 32; // override as per the new ABI. return padding * 2; }; }; - var namedType = function (name, padding) { + var namedType = function (name) { return function (type) { - padding = 32; // override as per the new ABI. + var padding = 32; // override as per the new ABI. return name === type ? padding * 2 : -1; }; }; @@ -204,14 +169,14 @@ var setupOutputTypes = function () { }; return [ - { padding: prefixedType('uint', calcBitPadding), format: formatInt }, - { padding: prefixedType('int', calcBitPadding), format: formatInt }, - { padding: prefixedType('hash', calcBitPadding), format: formatHash }, - { padding: prefixedType('string', calcBytePadding), format: formatString }, - { padding: prefixedType('real', calcRealPadding), format: formatInt }, - { padding: prefixedType('ureal', calcRealPadding), format: formatInt }, - { padding: namedType('address', 20) }, - { padding: namedType('bool', 1), format: formatBool } + { padding: prefixedType('uint'), format: formatInt }, + { padding: prefixedType('int'), format: formatInt }, + { padding: prefixedType('hash'), format: formatHash }, + { padding: prefixedType('string'), format: formatString }, + { padding: prefixedType('real'), format: formatInt }, + { padding: prefixedType('ureal'), format: formatInt }, + { padding: namedType('address') }, + { padding: namedType('bool'), format: formatBool } ]; }; -- cgit v1.2.3 From ed1cb9edca8fd74dc839377ded77e8c1ed09f648 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Wed, 14 Jan 2015 13:53:40 +0100 Subject: simplifid abi.js methods --- lib/abi.js | 131 +++++++++++++++++++++++++++++++++---------------------------- 1 file changed, 72 insertions(+), 59 deletions(-) (limited to 'lib/abi.js') diff --git a/lib/abi.js b/lib/abi.js index 49126338a..680016377 100644 --- a/lib/abi.js +++ b/lib/abi.js @@ -54,56 +54,52 @@ var padLeft = function (string, chars) { return new Array(chars - string.length + 1).join("0") + string; }; +/// Setups input formatters for solidity types +/// @returns an array of input formatters var setupInputTypes = function () { var prefixedType = function (prefix) { return function (type, value) { - var expected = prefix; - if (type.indexOf(expected) !== 0) { - return false; - } - - var padding = 32; // override as per the new ABI. - - if (prefix === "string") - return web3.fromAscii(value, padding).substr(2); - if (typeof value === "number") - value = value.toString(16); - else if (typeof value === "string") - value = web3.toHex(value); - else if (value.indexOf('0x') === 0) - value = value.substr(2); - else - value = (+value).toString(16); - return padLeft(value, padding * 2); + return type.indexOf(prefix) === 0; }; }; var namedType = function (name, formatter) { return function (type, value) { - if (type !== name) { - return false; - } - - var padding = 32; //override as per the new ABI. - - return padLeft(formatter ? formatter(value) : value, padding * 2); + return type === name; }; }; + + var formatInt = function (value) { + var padding = 32 * 2; + if (typeof value === 'number') + value = value.toString(16); + else if (value.indexOf('0x') === 0) + value = value.substr(2); + else if (typeof value === 'string') + value = value.toHex(value); + else + value = (+value).toString(16); + return padLeft(value, padding); + }; + + var formatString = function (value) { + return web3.fromAscii(value, 32).substr(2); + }; var formatBool = function (value) { - return value ? '0x1' : '0x0'; + return '000000000000000000000000000000000000000000000000000000000000000' + (value ? '1' : '0'); }; return [ - prefixedType('uint'), - prefixedType('int'), - prefixedType('hash'), - prefixedType('string'), - prefixedType('real'), - prefixedType('ureal'), - namedType('address'), - namedType('bool', formatBool), + { type: prefixedType('uint'), format: formatInt }, + { type: prefixedType('int'), format: formatInt }, + { type: prefixedType('hash'), format: formatInt }, + { type: prefixedType('string'), format: formatString }, + { type: prefixedType('real'), format: formatInt }, + { type: prefixedType('ureal'), format: formatInt }, + { type: namedType('address') }, + { type: namedType('bool'), format: formatBool } ]; }; @@ -118,65 +114,73 @@ var toAbiInput = function (json, methodName, params) { } var method = json[index]; + var padding = 32 * 2; for (var i = 0; i < method.inputs.length; i++) { - var found = false; - for (var j = 0; j < inputTypes.length && !found; j++) { - found = inputTypes[j](method.inputs[i].type, params[i]); + var typeMatch = false; + for (var j = 0; j < inputTypes.length && !typeMatch; j++) { + typeMatch = inputTypes[j].type(method.inputs[i].type, params[i]); } - if (!found) { - console.error('unsupported json type: ' + method.inputs[i].type); + if (!typeMatch) { + console.error('input parser does not support type: ' + method.inputs[i].type); } - bytes += found; + + var formatter = inputTypes[j - 1].format; + bytes += (formatter ? formatter(params[i]) : params[i]); } return bytes; }; +/// Setups output formaters for solidity types +/// @returns an array of output formatters var setupOutputTypes = function () { + /// @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) { var expected = prefix; - if (type.indexOf(expected) !== 0) { - return -1; - } - var padding = 32; // override as per the new ABI. - return padding * 2; + return type.indexOf(expected) === 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) { - var padding = 32; // override as per the new ABI. - return name === type ? padding * 2 : -1; + return name === type; }; }; + /// @returns input bytes formatted to int var formatInt = function (value) { return value.length <= 8 ? +parseInt(value, 16) : hexToDec(value); }; + /// @returns input bytes formatted to hex var formatHash = function (value) { return "0x" + value; }; + /// @returns input bytes formatted to bool var formatBool = function (value) { return value === '1' ? true : false; }; + /// @returns input bytes formatted to ascii string var formatString = function (value) { return web3.toAscii(value); }; return [ - { padding: prefixedType('uint'), format: formatInt }, - { padding: prefixedType('int'), format: formatInt }, - { padding: prefixedType('hash'), format: formatHash }, - { padding: prefixedType('string'), format: formatString }, - { padding: prefixedType('real'), format: formatInt }, - { padding: prefixedType('ureal'), format: formatInt }, - { padding: namedType('address') }, - { padding: namedType('bool'), format: formatBool } + { type: prefixedType('uint'), format: formatInt }, + { 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') }, + { type: namedType('bool'), format: formatBool } ]; }; @@ -193,14 +197,16 @@ var fromAbiOutput = function (json, methodName, output) { var result = []; var method = json[index]; + var padding = 32 * 2; 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); + var typeMatch = false; + for (var j = 0; j < outputTypes.length && !typeMatch; j++) { + typeMatch = outputTypes[j].type(method.outputs[i].type); } - if (padding === -1) { + 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); @@ -212,6 +218,8 @@ var fromAbiOutput = function (json, methodName, output) { return result; }; +/// @param json abi for contract +/// @returns input parser object for given json abi var inputParser = function (json) { var parser = {}; json.forEach(function (method) { @@ -224,6 +232,8 @@ var inputParser = function (json) { return parser; }; +/// @param json abi for contract +/// @returns output parser for given json abi var outputParser = function (json) { var parser = {}; json.forEach(function (method) { @@ -235,6 +245,9 @@ var outputParser = function (json) { return parser; }; +/// @param json abi for contract +/// @param method name for which we want to get method signature +/// @returns (promise) contract method signature for method with given name var methodSignature = function (json, name) { var method = json[findMethodIndex(json, name)]; var result = name + '('; -- cgit v1.2.3 From 6b2ec231323b62f5dc81c7702940d784fac98966 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Wed, 14 Jan 2015 14:06:29 +0100 Subject: formatting bool tests and fixes --- lib/abi.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/abi.js') diff --git a/lib/abi.js b/lib/abi.js index 680016377..cde725ff1 100644 --- a/lib/abi.js +++ b/lib/abi.js @@ -164,7 +164,7 @@ var setupOutputTypes = function () { /// @returns input bytes formatted to bool var formatBool = function (value) { - return value === '1' ? true : false; + return value === '0000000000000000000000000000000000000000000000000000000000000001' ? true : false; }; /// @returns input bytes formatted to ascii string -- cgit v1.2.3 From b0a9bbf33a022a5763e62a78dbd7f32af250726c Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Wed, 14 Jan 2015 14:19:54 +0100 Subject: next part of abi.js docs --- lib/abi.js | 63 +++++++++++++++++++++++++++++++++----------------------------- 1 file changed, 34 insertions(+), 29 deletions(-) (limited to 'lib/abi.js') diff --git a/lib/abi.js b/lib/abi.js index cde725ff1..674ad8288 100644 --- a/lib/abi.js +++ b/lib/abi.js @@ -35,6 +35,10 @@ var decToHex = function (dec) { return parseInt(dec).toString(16); }; +/// 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; @@ -44,31 +48,39 @@ var findIndex = function (array, callback) { 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 method.name === methodName; }); }; +/// @param string string to be padded +/// @param number of characters that result string should have +/// @returns right aligned string var padLeft = function (string, chars) { return new Array(chars - string.length + 1).join("0") + string; }; -/// Setups input formatters for solidity types -/// @returns an array of input formatters -var setupInputTypes = function () { - - var prefixedType = function (prefix) { - return function (type, value) { - return type.indexOf(prefix) === 0; - }; +/// @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; }; +}; - var namedType = function (name, formatter) { - return function (type, value) { - return type === name; - }; +/// @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; }; +}; + +/// Setups input formatters for solidity types +/// @returns an array of input formatters +var setupInputTypes = function () { var formatInt = function (value) { var padding = 32 * 2; @@ -105,6 +117,11 @@ var setupInputTypes = function () { var inputTypes = setupInputTypes(); +/// Formats input params to bytes +/// @param contract json abi +/// @param name of the method that we want to use +/// @param array of params that will be formatted to bytes +/// @returns bytes representation of input params var toAbiInput = function (json, methodName, params) { var bytes = ""; var index = findMethodIndex(json, methodName); @@ -135,23 +152,6 @@ var toAbiInput = function (json, methodName, params) { /// @returns an array of output formatters var setupOutputTypes = function () { - /// @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) { - var expected = prefix; - return type.indexOf(expected) === 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; - }; - }; - /// @returns input bytes formatted to int var formatInt = function (value) { return value.length <= 8 ? +parseInt(value, 16) : hexToDec(value); @@ -186,6 +186,11 @@ var setupOutputTypes = function () { var outputTypes = setupOutputTypes(); +/// Formats output bytes back to param list +/// @param contract json abi +/// @param name of the method that we want to use +/// @param bytes representtion of output +/// @returns array of output params var fromAbiOutput = function (json, methodName, output) { var index = findMethodIndex(json, methodName); -- cgit v1.2.3 From 603c790213e7e14ad9cf51e2e170af59144f783b Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Wed, 14 Jan 2015 20:29:20 +0100 Subject: next part of abi.js parsers tests and fixes --- lib/abi.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'lib/abi.js') diff --git a/lib/abi.js b/lib/abi.js index 674ad8288..e147a3504 100644 --- a/lib/abi.js +++ b/lib/abi.js @@ -110,7 +110,7 @@ var setupInputTypes = function () { { type: prefixedType('string'), format: formatString }, { type: prefixedType('real'), format: formatInt }, { type: prefixedType('ureal'), format: formatInt }, - { type: namedType('address') }, + { type: namedType('address'), format: formatInt }, { type: namedType('bool'), format: formatBool } ]; }; @@ -172,6 +172,10 @@ var setupOutputTypes = function () { return web3.toAscii(value); }; + var formatAddress = function (value) { + return "0x" + value.slice(value.length - 40, value.length); + }; + return [ { type: prefixedType('uint'), format: formatInt }, { type: prefixedType('int'), format: formatInt }, @@ -179,7 +183,7 @@ var setupOutputTypes = function () { { type: prefixedType('string'), format: formatString }, { type: prefixedType('real'), format: formatInt }, { type: prefixedType('ureal'), format: formatInt }, - { type: namedType('address') }, + { type: namedType('address'), format: formatAddress }, { type: namedType('bool'), format: formatBool } ]; }; -- cgit v1.2.3 From 472ad43211e120bdbf1c16a8a49b297164cc4b13 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Wed, 14 Jan 2015 20:36:26 +0100 Subject: more comments --- lib/abi.js | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'lib/abi.js') diff --git a/lib/abi.js b/lib/abi.js index e147a3504..29d3e3e4b 100644 --- a/lib/abi.js +++ b/lib/abi.js @@ -82,6 +82,8 @@ var namedType = function (name) { /// @returns an array of input formatters var setupInputTypes = function () { + /// Formats input value to byte representation of int + /// @returns right-aligned byte representation of int var formatInt = function (value) { var padding = 32 * 2; if (typeof value === 'number') @@ -95,10 +97,14 @@ var setupInputTypes = function () { return padLeft(value, padding); }; + /// Formats input value to byte representation of string + /// @returns left-algined byte representation of string var formatString = function (value) { return web3.fromAscii(value, 32).substr(2); }; + /// Formats input value to byte representation of bool + /// @returns right-aligned byte representation bool var formatBool = function (value) { return '000000000000000000000000000000000000000000000000000000000000000' + (value ? '1' : '0'); }; @@ -152,26 +158,28 @@ var toAbiInput = function (json, methodName, params) { /// @returns an array of output formatters var setupOutputTypes = function () { - /// @returns input bytes formatted to int + /// Formats input right-aligned input bytes to int + /// @returns right-aligned input bytes formatted to int var formatInt = function (value) { return value.length <= 8 ? +parseInt(value, 16) : hexToDec(value); }; - /// @returns input bytes formatted to hex + /// @returns right-aligned input bytes formatted to hex var formatHash = function (value) { return "0x" + value; }; - /// @returns input bytes formatted to bool + /// @returns right-aligned input bytes formatted to bool var formatBool = function (value) { return value === '0000000000000000000000000000000000000000000000000000000000000001' ? true : false; }; - /// @returns input bytes formatted to ascii string + /// @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 formatAddress = function (value) { return "0x" + value.slice(value.length - 40, value.length); }; -- cgit v1.2.3 From 46b932ccc03b0251d97084bbbde5193532b5618f Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Thu, 15 Jan 2015 15:51:25 +0100 Subject: negative integers support --- lib/abi.js | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) (limited to 'lib/abi.js') diff --git a/lib/abi.js b/lib/abi.js index 29d3e3e4b..d779944d2 100644 --- a/lib/abi.js +++ b/lib/abi.js @@ -57,9 +57,10 @@ var findMethodIndex = function (json, methodName) { /// @param string string to be padded /// @param number of characters that result string should have +/// @param sign, by default 0 /// @returns right aligned string -var padLeft = function (string, chars) { - return new Array(chars - string.length + 1).join("0") + string; +var padLeft = function (string, chars, sign) { + return new Array(chars - string.length + 1).join(sign ? sign : "0") + string; }; /// @param expected type prefix (string) @@ -86,8 +87,17 @@ var setupInputTypes = function () { /// @returns right-aligned byte representation of int var formatInt = function (value) { var padding = 32 * 2; - if (typeof value === 'number') + if (typeof value === 'number') { + if (value < 0) { + + // two's complement + // TODO: fix big numbers support + value = ((value) >>> 0).toString(16) + return padLeft(value, padding, 'f'); + } value = value.toString(16); + + } else if (value.indexOf('0x') === 0) value = value.substr(2); else if (typeof value === 'string') -- cgit v1.2.3 From ec74fc05d438806ece64fe34b0f28c8f45f5167e Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Thu, 15 Jan 2015 16:01:58 +0100 Subject: gulp --- lib/abi.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/abi.js') diff --git a/lib/abi.js b/lib/abi.js index d779944d2..b51fbab59 100644 --- a/lib/abi.js +++ b/lib/abi.js @@ -92,7 +92,7 @@ var setupInputTypes = function () { // two's complement // TODO: fix big numbers support - value = ((value) >>> 0).toString(16) + value = ((value) >>> 0).toString(16); return padLeft(value, padding, 'f'); } value = value.toString(16); -- cgit v1.2.3