formatters separated
This commit is contained in:
parent
995861de4d
commit
5689086202
142
lib/abi.js
142
lib/abi.js
|
@ -21,12 +21,12 @@
|
||||||
* @date 2014
|
* @date 2014
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// TODO: is these line is supposed to be here?
|
|
||||||
if (process.env.NODE_ENV !== 'build') {
|
if (process.env.NODE_ENV !== 'build') {
|
||||||
var BigNumber = require('bignumber.js'); // jshint ignore:line
|
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 });
|
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 number of characters that result string should have
|
||||||
/// @param sign, by default 0
|
/// @param sign, by default 0
|
||||||
/// @returns right aligned string
|
/// @returns right aligned string
|
||||||
|
/// TODO: remove, it was moved to formatters.js
|
||||||
var padLeft = function (string, chars, sign) {
|
var padLeft = function (string, chars, sign) {
|
||||||
return new Array(chars - string.length + 1).join(sign ? sign : "0") + string;
|
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) {
|
var arrayType = function (type) {
|
||||||
return type.slice(-2) === '[]';
|
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) {
|
var dynamicTypeBytes = function (type, value) {
|
||||||
// TODO: decide what to do with array of strings
|
// TODO: decide what to do with array of strings
|
||||||
if (arrayType(type) || type === 'string') // only string itself that is dynamic; stringX is static length.
|
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 "";
|
return "";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -164,14 +124,14 @@ var dynamicTypeBytes = function (type, value) {
|
||||||
var setupInputTypes = function () {
|
var setupInputTypes = function () {
|
||||||
|
|
||||||
return [
|
return [
|
||||||
{ type: prefixedType('uint'), format: formatInputInt },
|
{ type: prefixedType('uint'), format: f.formatInputInt },
|
||||||
{ type: prefixedType('int'), format: formatInputInt },
|
{ type: prefixedType('int'), format: f.formatInputInt },
|
||||||
{ type: prefixedType('hash'), format: formatInputInt },
|
{ type: prefixedType('hash'), format: f.formatInputInt },
|
||||||
{ type: prefixedType('string'), format: formatInputString },
|
{ type: prefixedType('string'), format: f.formatInputString },
|
||||||
{ type: prefixedType('real'), format: formatInputReal },
|
{ type: prefixedType('real'), format: f.formatInputReal },
|
||||||
{ type: prefixedType('ureal'), format: formatInputReal },
|
{ type: prefixedType('ureal'), format: f.formatInputReal },
|
||||||
{ type: namedType('address'), format: formatInputInt },
|
{ type: namedType('address'), format: f.formatInputInt },
|
||||||
{ type: namedType('bool'), format: formatInputBool }
|
{ type: namedType('bool'), format: f.formatInputBool }
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -217,62 +177,6 @@ var toAbiInput = function (json, methodName, params) {
|
||||||
return bytes;
|
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) {
|
var dynamicBytesLength = function (type) {
|
||||||
if (arrayType(type) || type === 'string') // only string itself that is dynamic; stringX is static length.
|
if (arrayType(type) || type === 'string') // only string itself that is dynamic; stringX is static length.
|
||||||
return ETH_PADDING * 2;
|
return ETH_PADDING * 2;
|
||||||
|
@ -284,14 +188,14 @@ var dynamicBytesLength = function (type) {
|
||||||
var setupOutputTypes = function () {
|
var setupOutputTypes = function () {
|
||||||
|
|
||||||
return [
|
return [
|
||||||
{ type: prefixedType('uint'), format: formatOutputUInt },
|
{ type: prefixedType('uint'), format: f.formatOutputUInt },
|
||||||
{ type: prefixedType('int'), format: formatOutputInt },
|
{ type: prefixedType('int'), format: f.formatOutputInt },
|
||||||
{ type: prefixedType('hash'), format: formatOutputHash },
|
{ type: prefixedType('hash'), format: f.formatOutputHash },
|
||||||
{ type: prefixedType('string'), format: formatOutputString },
|
{ type: prefixedType('string'), format: f.formatOutputString },
|
||||||
{ type: prefixedType('real'), format: formatOutputReal },
|
{ type: prefixedType('real'), format: f.formatOutputReal },
|
||||||
{ type: prefixedType('ureal'), format: formatOutputUReal },
|
{ type: prefixedType('ureal'), format: f.formatOutputUReal },
|
||||||
{ type: namedType('address'), format: formatOutputAddress },
|
{ type: namedType('address'), format: f.formatOutputAddress },
|
||||||
{ type: namedType('bool'), format: formatOutputBool }
|
{ type: namedType('bool'), format: f.formatOutputBool }
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -328,7 +232,7 @@ var fromAbiOutput = function (json, methodName, output) {
|
||||||
|
|
||||||
var formatter = outputTypes[j - 1].format;
|
var formatter = outputTypes[j - 1].format;
|
||||||
if (arrayType(method.outputs[i].type)) {
|
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);
|
dynamicPart = dynamicPart.slice(padding);
|
||||||
var array = [];
|
var array = [];
|
||||||
for (var k = 0; k < size; k++) {
|
for (var k = 0; k < size; k++) {
|
||||||
|
|
|
@ -0,0 +1,156 @@
|
||||||
|
/*
|
||||||
|
This file is part of ethereum.js.
|
||||||
|
|
||||||
|
ethereum.js is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
ethereum.js is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public License
|
||||||
|
along with ethereum.js. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
/** @file formatters.js
|
||||||
|
* @authors:
|
||||||
|
* Marek Kotewicz <marek@ethdev.com>
|
||||||
|
* @date 2015
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (process.env.NODE_ENV !== 'build') {
|
||||||
|
var BigNumber = require('bignumber.js'); // jshint ignore:line
|
||||||
|
}
|
||||||
|
|
||||||
|
var web3 = require('./web3');
|
||||||
|
|
||||||
|
BigNumber.config({ ROUNDING_MODE: BigNumber.ROUND_DOWN });
|
||||||
|
|
||||||
|
var ETH_PADDING = 32;
|
||||||
|
|
||||||
|
/// @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, sign) {
|
||||||
|
return new Array(chars - string.length + 1).join(sign ? sign : "0") + string;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// 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)));
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/// 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);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
formatInputInt: formatInputInt,
|
||||||
|
formatInputString: formatInputString,
|
||||||
|
formatInputBool: formatInputBool,
|
||||||
|
formatInputReal: formatInputReal,
|
||||||
|
formatOutputInt: formatOutputInt,
|
||||||
|
formatOutputUInt: formatOutputUInt,
|
||||||
|
formatOutputReal: formatOutputReal,
|
||||||
|
formatOutputUReal: formatOutputUReal,
|
||||||
|
formatOutputHash: formatOutputHash,
|
||||||
|
formatOutputBool: formatOutputBool,
|
||||||
|
formatOutputString: formatOutputString,
|
||||||
|
formatOutputAddress: formatOutputAddress
|
||||||
|
};
|
||||||
|
|
Loading…
Reference in New Issue