web3.js/lib/formatters.js

330 lines
9.3 KiB
JavaScript
Raw Normal View History

2015-01-31 00:52:36 +00:00
/*
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
}
2015-01-31 12:54:39 +00:00
var utils = require('./utils');
2015-03-03 10:11:52 +00:00
var c = require('./config');
2015-01-31 00:52:36 +00:00
/// @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) {
2015-02-25 14:53:28 +00:00
/*jshint maxcomplexity:7 */
2015-01-31 13:05:48 +00:00
var padding = c.ETH_PADDING * 2;
2015-03-07 16:43:51 +00:00
if (utils.isBigNumber(value) || typeof value === 'number') {
2015-01-31 00:52:36 +00:00
if (typeof value === 'number')
value = new BigNumber(value);
2015-01-31 13:05:48 +00:00
BigNumber.config(c.ETH_BIGNUMBER_ROUNDING_MODE);
2015-01-31 00:52:36 +00:00
value = value.round();
if (value.lessThan(0))
value = new BigNumber("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 16).plus(value).plus(1);
value = value.toString(16);
}
2015-03-07 16:43:51 +00:00
else if (typeof value === 'string') {
if (value.indexOf('0x') === 0) {
value = value.substr(2);
} else {
value = formatInputInt(new BigNumber(value));
}
}
2015-01-31 00:52:36 +00:00
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) {
2015-01-31 13:05:48 +00:00
return utils.fromAscii(value, c.ETH_PADDING).substr(2);
2015-01-31 00:52:36 +00:00
};
/// 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) {
2015-02-23 16:05:53 +00:00
2015-01-31 00:52:36 +00:00
value = value || "0";
2015-02-23 16:05:53 +00:00
2015-01-31 00:52:36 +00:00
// 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);
};
2015-02-23 16:05:53 +00:00
2015-01-31 00:52:36 +00:00
/// 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) {
2015-01-31 12:54:39 +00:00
return utils.toAscii(value);
2015-01-31 00:52:36 +00:00
};
/// @returns right-aligned input bytes formatted to address
var formatOutputAddress = function (value) {
return "0x" + value.slice(value.length - 40, value.length);
};
2015-02-23 16:05:53 +00:00
/// Formats the input to a big number
/// @returns a BigNumber object
var convertToBigNumber = function (value) {
// remove the leading 0x
if(typeof value === 'string')
value = value.replace('0x', '');
value = value || "0";
return new BigNumber(value, 16);
};
2015-02-25 15:30:23 +00:00
/**
Formats the input of a transaction and converts all values to HEX
@returns object
*/
2015-02-24 12:00:24 +00:00
var inputTransactionFormatter = function(options){
// make code -> data
if(options.code) {
options.data = options.code;
delete options.code;
}
// make endowment -> value
if(options.endowment) {
options.value = options.endowment;
delete options.endowment;
}
// format the following options
2015-02-26 09:56:04 +00:00
/*jshint maxcomplexity:5 */
2015-02-26 14:54:49 +00:00
['gasPrice', 'gas', 'value'].forEach(function(key){
2015-02-24 12:00:24 +00:00
// if hex or string integer
if(typeof options[key] === 'string') {
// if not hex assume its a number string
if(options[key].indexOf('0x') === -1)
options[key] = utils.fromDecimal(options[key]);
// if number
} else if(typeof options[key] === 'number') {
2015-02-25 15:31:09 +00:00
options[key] = utils.fromDecimal(options[key]);
2015-02-24 12:00:24 +00:00
// if bignumber
} else if(options[key] instanceof BigNumber) {
options[key] = '0x'+ options[key].toString(16);
}
});
return options;
};
2015-02-25 15:30:23 +00:00
/**
Formats the output of a transaction to its proper values
@returns object
*/
var outputTransactionFormatter = function(tx){
// transform to number
2015-02-26 15:20:46 +00:00
tx.gas = utils.toDecimal(tx.gas);
2015-02-25 15:30:23 +00:00
2015-02-26 15:20:46 +00:00
tx.gasPrice = utils.toBigNumber(tx.gasPrice);
tx.value = utils.toBigNumber(tx.value);
2015-02-25 15:30:23 +00:00
return tx;
};
/**
Formats the output of a block to its proper values
@returns object
*/
var outputBlockFormatter = function(block){
2015-02-26 09:56:04 +00:00
2015-02-25 15:30:23 +00:00
// transform to number
2015-02-26 14:54:49 +00:00
block.gasLimit = utils.toDecimal(block.gasLimit);
block.gasUsed = utils.toDecimal(block.gasUsed);
block.size = utils.toDecimal(block.size);
block.timestamp = utils.toDecimal(block.timestamp);
block.number = utils.toDecimal(block.number);
2015-02-26 15:20:46 +00:00
2015-02-26 14:54:49 +00:00
block.minGasPrice = utils.toBigNumber(block.minGasPrice);
block.difficulty = utils.toBigNumber(block.difficulty);
block.totalDifficulty = utils.toBigNumber(block.totalDifficulty);
2015-02-25 15:30:23 +00:00
return block;
};
2015-02-24 12:00:24 +00:00
2015-02-27 11:41:07 +00:00
/**
Formats the output of a log
@returns object
*/
var outputLogFormatter = function(log){
log.number = utils.toDecimal(log.number);
return log;
};
/**
Formats the input of a whisper post and converts all values to HEX
@returns object
*/
var inputPostFormatter = function(post){
post.payload = utils.toHex(post.payload);
post.ttl = utils.toHex(post.ttl);
post.workToProve = utils.toHex(post.workToProve);
if(!(post.topic instanceof Array))
post.topic = [post.topic];
// format the following options
post.topic = post.topic.map(function(topic){
return utils.toHex(topic);
});
return post;
};
/**
Formats the output of a received post message
@returns object
*/
var outputPostFormatter = function(post){
post.expiry = utils.toDecimal(post.expiry);
post.sent = utils.toDecimal(post.sent);
post.ttl = utils.toDecimal(post.ttl);
post.payloadRaw = post.payload;
2015-02-27 11:41:07 +00:00
post.payload = utils.toAscii(post.payload);
if(post.payload.indexOf('{') === 0 || post.payload.indexOf('[') === 0) {
try {
post.payload = JSON.parse(post.payload);
} catch (e) { }
}
// format the following options
post.topic = post.topic.map(function(topic){
return utils.toAscii(topic);
});
return post;
};
2015-02-23 16:05:53 +00:00
2015-01-31 00:52:36 +00:00
module.exports = {
formatInputInt: formatInputInt,
formatInputString: formatInputString,
formatInputBool: formatInputBool,
formatInputReal: formatInputReal,
formatOutputInt: formatOutputInt,
formatOutputUInt: formatOutputUInt,
formatOutputReal: formatOutputReal,
formatOutputUReal: formatOutputUReal,
formatOutputHash: formatOutputHash,
formatOutputBool: formatOutputBool,
formatOutputString: formatOutputString,
2015-02-23 16:05:53 +00:00
formatOutputAddress: formatOutputAddress,
2015-02-24 12:00:24 +00:00
convertToBigNumber: convertToBigNumber,
2015-02-25 15:30:23 +00:00
inputTransactionFormatter: inputTransactionFormatter,
outputTransactionFormatter: outputTransactionFormatter,
2015-02-27 11:41:07 +00:00
outputBlockFormatter: outputBlockFormatter,
outputLogFormatter: outputLogFormatter,
inputPostFormatter: inputPostFormatter,
outputPostFormatter: outputPostFormatter
2015-01-31 00:52:36 +00:00
};