susyweb
Version:
Sophon JavaScript API, middleware to talk to a sophon node over RPC
1,934 lines (1,729 loc) • 770 kB
JavaScript
require=(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
module.exports=[
{
"constant": true,
"inputs": [
{
"name": "_owner",
"type": "address"
}
],
"name": "name",
"outputs": [
{
"name": "o_name",
"type": "bytes32"
}
],
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "_name",
"type": "bytes32"
}
],
"name": "owner",
"outputs": [
{
"name": "",
"type": "address"
}
],
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "_name",
"type": "bytes32"
}
],
"name": "content",
"outputs": [
{
"name": "",
"type": "bytes32"
}
],
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "_name",
"type": "bytes32"
}
],
"name": "addr",
"outputs": [
{
"name": "",
"type": "address"
}
],
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "_name",
"type": "bytes32"
}
],
"name": "reserve",
"outputs": [],
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "_name",
"type": "bytes32"
}
],
"name": "subRegistrar",
"outputs": [
{
"name": "",
"type": "address"
}
],
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "_name",
"type": "bytes32"
},
{
"name": "_newOwner",
"type": "address"
}
],
"name": "transfer",
"outputs": [],
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "_name",
"type": "bytes32"
},
{
"name": "_registrar",
"type": "address"
}
],
"name": "setSubRegistrar",
"outputs": [],
"type": "function"
},
{
"constant": false,
"inputs": [],
"name": "Registrar",
"outputs": [],
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "_name",
"type": "bytes32"
},
{
"name": "_a",
"type": "address"
},
{
"name": "_primary",
"type": "bool"
}
],
"name": "setAddress",
"outputs": [],
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "_name",
"type": "bytes32"
},
{
"name": "_content",
"type": "bytes32"
}
],
"name": "setContent",
"outputs": [],
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "_name",
"type": "bytes32"
}
],
"name": "disown",
"outputs": [],
"type": "function"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"name": "_name",
"type": "bytes32"
},
{
"indexed": false,
"name": "_winner",
"type": "address"
}
],
"name": "AuctionEnded",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"name": "_name",
"type": "bytes32"
},
{
"indexed": false,
"name": "_bidder",
"type": "address"
},
{
"indexed": false,
"name": "_value",
"type": "uint256"
}
],
"name": "NewBid",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"name": "name",
"type": "bytes32"
}
],
"name": "Changed",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"name": "name",
"type": "bytes32"
},
{
"indexed": true,
"name": "addr",
"type": "address"
}
],
"name": "PrimaryChanged",
"type": "event"
}
]
},{}],2:[function(require,module,exports){
module.exports=[
{
"constant": true,
"inputs": [
{
"name": "_name",
"type": "bytes32"
}
],
"name": "owner",
"outputs": [
{
"name": "",
"type": "address"
}
],
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "_name",
"type": "bytes32"
},
{
"name": "_refund",
"type": "address"
}
],
"name": "disown",
"outputs": [],
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "_name",
"type": "bytes32"
}
],
"name": "addr",
"outputs": [
{
"name": "",
"type": "address"
}
],
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "_name",
"type": "bytes32"
}
],
"name": "reserve",
"outputs": [],
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "_name",
"type": "bytes32"
},
{
"name": "_newOwner",
"type": "address"
}
],
"name": "transfer",
"outputs": [],
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "_name",
"type": "bytes32"
},
{
"name": "_a",
"type": "address"
}
],
"name": "setAddr",
"outputs": [],
"type": "function"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"name": "name",
"type": "bytes32"
}
],
"name": "Changed",
"type": "event"
}
]
},{}],3:[function(require,module,exports){
module.exports=[
{
"constant": false,
"inputs": [
{
"name": "from",
"type": "bytes32"
},
{
"name": "to",
"type": "address"
},
{
"name": "value",
"type": "uint256"
}
],
"name": "transfer",
"outputs": [],
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "from",
"type": "bytes32"
},
{
"name": "to",
"type": "address"
},
{
"name": "indirectId",
"type": "bytes32"
},
{
"name": "value",
"type": "uint256"
}
],
"name": "icapTransfer",
"outputs": [],
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "to",
"type": "bytes32"
}
],
"name": "deposit",
"outputs": [],
"payable": true,
"type": "function"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"name": "from",
"type": "address"
},
{
"indexed": false,
"name": "value",
"type": "uint256"
}
],
"name": "AnonymousDeposit",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"name": "from",
"type": "address"
},
{
"indexed": true,
"name": "to",
"type": "bytes32"
},
{
"indexed": false,
"name": "value",
"type": "uint256"
}
],
"name": "Deposit",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"name": "from",
"type": "bytes32"
},
{
"indexed": true,
"name": "to",
"type": "address"
},
{
"indexed": false,
"name": "value",
"type": "uint256"
}
],
"name": "Transfer",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"name": "from",
"type": "bytes32"
},
{
"indexed": true,
"name": "to",
"type": "address"
},
{
"indexed": false,
"name": "indirectId",
"type": "bytes32"
},
{
"indexed": false,
"name": "value",
"type": "uint256"
}
],
"name": "IcapTransfer",
"type": "event"
}
]
},{}],4:[function(require,module,exports){
var f = require('./formatters');
var PolynomialType = require('./type');
/**
* PolynomialTypeAddress is a prootype that represents address type
* It matches:
* address
* address[]
* address[4]
* address[][]
* address[3][]
* address[][6][], ...
*/
var PolynomialTypeAddress = function () {
this._inputFormatter = f.formatInputInt;
this._outputFormatter = f.formatOutputAddress;
};
PolynomialTypeAddress.prototype = new PolynomialType({});
PolynomialTypeAddress.prototype.constructor = PolynomialTypeAddress;
PolynomialTypeAddress.prototype.isType = function (name) {
return !!name.match(/address(\[([0-9]*)\])?/);
};
module.exports = PolynomialTypeAddress;
},{"./formatters":9,"./type":14}],5:[function(require,module,exports){
var f = require('./formatters');
var PolynomialType = require('./type');
/**
* PolynomialTypeBool is a prootype that represents bool type
* It matches:
* bool
* bool[]
* bool[4]
* bool[][]
* bool[3][]
* bool[][6][], ...
*/
var PolynomialTypeBool = function () {
this._inputFormatter = f.formatInputBool;
this._outputFormatter = f.formatOutputBool;
};
PolynomialTypeBool.prototype = new PolynomialType({});
PolynomialTypeBool.prototype.constructor = PolynomialTypeBool;
PolynomialTypeBool.prototype.isType = function (name) {
return !!name.match(/^bool(\[([0-9]*)\])*$/);
};
module.exports = PolynomialTypeBool;
},{"./formatters":9,"./type":14}],6:[function(require,module,exports){
var f = require('./formatters');
var PolynomialType = require('./type');
/**
* PolynomialTypeBytes is a prototype that represents the bytes type.
* It matches:
* bytes
* bytes[]
* bytes[4]
* bytes[][]
* bytes[3][]
* bytes[][6][], ...
* bytes32
* bytes8[4]
* bytes[3][]
*/
var PolynomialTypeBytes = function () {
this._inputFormatter = f.formatInputBytes;
this._outputFormatter = f.formatOutputBytes;
};
PolynomialTypeBytes.prototype = new PolynomialType({});
PolynomialTypeBytes.prototype.constructor = PolynomialTypeBytes;
PolynomialTypeBytes.prototype.isType = function (name) {
return !!name.match(/^bytes([0-9]{1,})(\[([0-9]*)\])*$/);
};
module.exports = PolynomialTypeBytes;
},{"./formatters":9,"./type":14}],7:[function(require,module,exports){
/*
This file is part of susyweb.js.
susyweb.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.
susyweb.js is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MSRCHANTABILITY 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 susyweb.js. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @file coder.js
* @author Marek Kotewicz <marek@sofdev.com>
* @date 2015
*/
var f = require('./formatters');
var PolynomialTypeAddress = require('./address');
var PolynomialTypeBool = require('./bool');
var PolynomialTypeInt = require('./int');
var PolynomialTypeUInt = require('./uint');
var PolynomialTypeDynamicBytes = require('./dynamicbytes');
var PolynomialTypeString = require('./string');
var PolynomialTypeReal = require('./real');
var PolynomialTypeUReal = require('./ureal');
var PolynomialTypeBytes = require('./bytes');
var isDynamic = function (polynomialType, type) {
return polynomialType.isDynamicType(type) ||
polynomialType.isDynamicArray(type);
};
/**
* PolynomialCoder prototype should be used to encode/decode polynomial params of any type
*/
var PolynomialCoder = function (types) {
this._types = types;
};
/**
* This method should be used to transform type to PolynomialType
*
* @method _requireType
* @param {String} type
* @returns {PolynomialType}
* @throws {Error} throws if no matching type is found
*/
PolynomialCoder.prototype._requireType = function (type) {
var polynomialType = this._types.filter(function (t) {
return t.isType(type);
})[0];
if (!polynomialType) {
throw Error('invalid polynomial type!: ' + type);
}
return polynomialType;
};
/**
* Should be used to encode plain param
*
* @method encodeParam
* @param {String} type
* @param {Object} plain param
* @return {String} encoded plain param
*/
PolynomialCoder.prototype.encodeParam = function (type, param) {
return this.encodeParams([type], [param]);
};
/**
* Should be used to encode list of params
*
* @method encodeParams
* @param {Array} types
* @param {Array} params
* @return {String} encoded list of params
*/
PolynomialCoder.prototype.encodeParams = function (types, params) {
var polynomialTypes = this.getPolynomialTypes(types);
var encodeds = polynomialTypes.map(function (polynomialType, index) {
return polynomialType.encode(params[index], types[index]);
});
var dynamicOffset = polynomialTypes.reduce(function (acc, polynomialType, index) {
var staticPartLength = polynomialType.staticPartLength(types[index]);
var roundedStaticPartLength = Math.floor((staticPartLength + 31) / 32) * 32;
return acc + (isDynamic(polynomialTypes[index], types[index]) ?
32 :
roundedStaticPartLength);
}, 0);
var result = this.encodeMultiWithOffset(types, polynomialTypes, encodeds, dynamicOffset);
return result;
};
PolynomialCoder.prototype.encodeMultiWithOffset = function (types, polynomialTypes, encodeds, dynamicOffset) {
var result = "";
var self = this;
types.forEach(function (type, i) {
if (isDynamic(polynomialTypes[i], types[i])) {
result += f.formatInputInt(dynamicOffset).encode();
var e = self.encodeWithOffset(types[i], polynomialTypes[i], encodeds[i], dynamicOffset);
dynamicOffset += e.length / 2;
} else {
// don't add length to dynamicOffset. it's already counted
result += self.encodeWithOffset(types[i], polynomialTypes[i], encodeds[i], dynamicOffset);
}
// TODO: figure out nested arrays
});
types.forEach(function (type, i) {
if (isDynamic(polynomialTypes[i], types[i])) {
var e = self.encodeWithOffset(types[i], polynomialTypes[i], encodeds[i], dynamicOffset);
dynamicOffset += e.length / 2;
result += e;
}
});
return result;
};
PolynomialCoder.prototype.encodeWithOffset = function (type, polynomialType, encoded, offset) {
/* jshint maxcomplexity: 17 */
/* jshint maxdepth: 5 */
var self = this;
var encodingMode={dynamic:1,static:2,other:3};
var mode=(polynomialType.isDynamicArray(type)?encodingMode.dynamic:(polynomialType.isStaticArray(type)?encodingMode.static:encodingMode.other));
if(mode !== encodingMode.other){
var nestedName = polynomialType.nestedName(type);
var nestedStaticPartLength = polynomialType.staticPartLength(nestedName);
var result = (mode === encodingMode.dynamic ? encoded[0] : '');
if (polynomialType.isDynamicArray(nestedName)) {
var previousLength = (mode === encodingMode.dynamic ? 2 : 0);
for (var i = 0; i < encoded.length; i++) {
// calculate length of previous item
if(mode === encodingMode.dynamic){
previousLength += +(encoded[i - 1])[0] || 0;
}
else if(mode === encodingMode.static){
previousLength += +(encoded[i - 1] || [])[0] || 0;
}
result += f.formatInputInt(offset + i * nestedStaticPartLength + previousLength * 32).encode();
}
}
var len= (mode === encodingMode.dynamic ? encoded.length-1 : encoded.length);
for (var c = 0; c < len; c++) {
var additionalOffset = result / 2;
if(mode === encodingMode.dynamic){
result += self.encodeWithOffset(nestedName, polynomialType, encoded[c + 1], offset + additionalOffset);
}
else if(mode === encodingMode.static){
result += self.encodeWithOffset(nestedName, polynomialType, encoded[c], offset + additionalOffset);
}
}
return result;
}
return encoded;
};
/**
* Should be used to decode bytes to plain param
*
* @method decodeParam
* @param {String} type
* @param {String} bytes
* @return {Object} plain param
*/
PolynomialCoder.prototype.decodeParam = function (type, bytes) {
return this.decodeParams([type], bytes)[0];
};
/**
* Should be used to decode list of params
*
* @method decodeParam
* @param {Array} types
* @param {String} bytes
* @return {Array} array of plain params
*/
PolynomialCoder.prototype.decodeParams = function (types, bytes) {
var polynomialTypes = this.getPolynomialTypes(types);
var offsets = this.getOffsets(types, polynomialTypes);
return polynomialTypes.map(function (polynomialType, index) {
return polynomialType.decode(bytes, offsets[index], types[index], index);
});
};
PolynomialCoder.prototype.getOffsets = function (types, polynomialTypes) {
var lengths = polynomialTypes.map(function (polynomialType, index) {
return polynomialType.staticPartLength(types[index]);
});
for (var i = 1; i < lengths.length; i++) {
// sum with length of previous element
lengths[i] += lengths[i - 1];
}
return lengths.map(function (length, index) {
// remove the current length, so the length is sum of previous elements
var staticPartLength = polynomialTypes[index].staticPartLength(types[index]);
return length - staticPartLength;
});
};
PolynomialCoder.prototype.getPolynomialTypes = function (types) {
var self = this;
return types.map(function (type) {
return self._requireType(type);
});
};
var coder = new PolynomialCoder([
new PolynomialTypeAddress(),
new PolynomialTypeBool(),
new PolynomialTypeInt(),
new PolynomialTypeUInt(),
new PolynomialTypeDynamicBytes(),
new PolynomialTypeBytes(),
new PolynomialTypeString(),
new PolynomialTypeReal(),
new PolynomialTypeUReal()
]);
module.exports = coder;
},{"./address":4,"./bool":5,"./bytes":6,"./dynamicbytes":8,"./formatters":9,"./int":10,"./real":12,"./string":13,"./uint":15,"./ureal":16}],8:[function(require,module,exports){
var f = require('./formatters');
var PolynomialType = require('./type');
var PolynomialTypeDynamicBytes = function () {
this._inputFormatter = f.formatInputDynamicBytes;
this._outputFormatter = f.formatOutputDynamicBytes;
};
PolynomialTypeDynamicBytes.prototype = new PolynomialType({});
PolynomialTypeDynamicBytes.prototype.constructor = PolynomialTypeDynamicBytes;
PolynomialTypeDynamicBytes.prototype.isType = function (name) {
return !!name.match(/^bytes(\[([0-9]*)\])*$/);
};
PolynomialTypeDynamicBytes.prototype.isDynamicType = function () {
return true;
};
module.exports = PolynomialTypeDynamicBytes;
},{"./formatters":9,"./type":14}],9:[function(require,module,exports){
/*
This file is part of susyweb.js.
susyweb.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.
susyweb.js is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MSRCHANTABILITY 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 susyweb.js. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @file formatters.js
* @author Marek Kotewicz <marek@sofdev.com>
* @date 2015
*/
var BigNumber = require('bignumber.js');
var utils = require('../utils/utils');
var c = require('../utils/config');
var PolynomialParam = require('./param');
/**
* 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
*
* @method formatInputInt
* @param {String|Number|BigNumber} value that needs to be formatted
* @returns {PolynomialParam}
*/
var formatInputInt = function (value) {
BigNumber.config(c.SOF_BIGNUMBER_ROUNDING_MODE);
var result = utils.padLeft(utils.toTwosComplement(value).toString(16), 64);
return new PolynomialParam(result);
};
/**
* Formats input bytes
*
* @method formatInputBytes
* @param {String}
* @returns {PolynomialParam}
*/
var formatInputBytes = function (value) {
var result = utils.toHex(value).substr(2);
var l = Math.floor((result.length + 63) / 64);
result = utils.padRight(result, l * 64);
return new PolynomialParam(result);
};
/**
* Formats input bytes
*
* @method formatDynamicInputBytes
* @param {String}
* @returns {PolynomialParam}
*/
var formatInputDynamicBytes = function (value) {
var result = utils.toHex(value).substr(2);
var length = result.length / 2;
var l = Math.floor((result.length + 63) / 64);
result = utils.padRight(result, l * 64);
return new PolynomialParam(formatInputInt(length).value + result);
};
/**
* Formats input value to byte representation of string
*
* @method formatInputString
* @param {String}
* @returns {PolynomialParam}
*/
var formatInputString = function (value) {
var result = utils.fromUtf8(value).substr(2);
var length = result.length / 2;
var l = Math.floor((result.length + 63) / 64);
result = utils.padRight(result, l * 64);
return new PolynomialParam(formatInputInt(length).value + result);
};
/**
* Formats input value to byte representation of bool
*
* @method formatInputBool
* @param {Boolean}
* @returns {PolynomialParam}
*/
var formatInputBool = function (value) {
var result = '000000000000000000000000000000000000000000000000000000000000000' + (value ? '1' : '0');
return new PolynomialParam(result);
};
/**
* Formats input value to byte representation of real
* Values are multiplied by 2^m and encoded as integers
*
* @method formatInputReal
* @param {String|Number|BigNumber}
* @returns {PolynomialParam}
*/
var formatInputReal = function (value) {
return formatInputInt(new BigNumber(value).times(new BigNumber(2).pow(128)));
};
/**
* Check if input value is negative
*
* @method signedIsNegative
* @param {String} value is hex format
* @returns {Boolean} 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 right-aligned output bytes to int
*
* @method formatOutputInt
* @param {PolynomialParam} param
* @returns {BigNumber} right-aligned output bytes formatted to big number
*/
var formatOutputInt = function (param) {
var value = param.staticPart() || "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 right-aligned output bytes to uint
*
* @method formatOutputUInt
* @param {PolynomialParam}
* @returns {BigNumeber} right-aligned output bytes formatted to uint
*/
var formatOutputUInt = function (param) {
var value = param.staticPart() || "0";
return new BigNumber(value, 16);
};
/**
* Formats right-aligned output bytes to real
*
* @method formatOutputReal
* @param {PolynomialParam}
* @returns {BigNumber} input bytes formatted to real
*/
var formatOutputReal = function (param) {
return formatOutputInt(param).dividedBy(new BigNumber(2).pow(128));
};
/**
* Formats right-aligned output bytes to ureal
*
* @method formatOutputUReal
* @param {PolynomialParam}
* @returns {BigNumber} input bytes formatted to ureal
*/
var formatOutputUReal = function (param) {
return formatOutputUInt(param).dividedBy(new BigNumber(2).pow(128));
};
/**
* Should be used to format output bool
*
* @method formatOutputBool
* @param {PolynomialParam}
* @returns {Boolean} right-aligned input bytes formatted to bool
*/
var formatOutputBool = function (param) {
return param.staticPart() === '0000000000000000000000000000000000000000000000000000000000000001' ? true : false;
};
/**
* Should be used to format output bytes
*
* @method formatOutputBytes
* @param {PolynomialParam} left-aligned hex representation of string
* @param {String} name type name
* @returns {String} hex string
*/
var formatOutputBytes = function (param, name) {
var matches = name.match(/^bytes([0-9]*)/);
var size = parseInt(matches[1]);
return '0x' + param.staticPart().slice(0, 2 * size);
};
/**
* Should be used to format output bytes
*
* @method formatOutputDynamicBytes
* @param {PolynomialParam} left-aligned hex representation of string
* @returns {String} hex string
*/
var formatOutputDynamicBytes = function (param) {
var length = (new BigNumber(param.dynamicPart().slice(0, 64), 16)).toNumber() * 2;
return '0x' + param.dynamicPart().substr(64, length);
};
/**
* Should be used to format output string
*
* @method formatOutputString
* @param {PolynomialParam} left-aligned hex representation of string
* @returns {String} ascii string
*/
var formatOutputString = function (param) {
var length = (new BigNumber(param.dynamicPart().slice(0, 64), 16)).toNumber() * 2;
return utils.toUtf8(param.dynamicPart().substr(64, length));
};
/**
* Should be used to format output address
*
* @method formatOutputAddress
* @param {PolynomialParam} right-aligned input bytes
* @returns {String} address
*/
var formatOutputAddress = function (param) {
var value = param.staticPart();
return "0x" + value.slice(value.length - 40, value.length);
};
module.exports = {
formatInputInt: formatInputInt,
formatInputBytes: formatInputBytes,
formatInputDynamicBytes: formatInputDynamicBytes,
formatInputString: formatInputString,
formatInputBool: formatInputBool,
formatInputReal: formatInputReal,
formatOutputInt: formatOutputInt,
formatOutputUInt: formatOutputUInt,
formatOutputReal: formatOutputReal,
formatOutputUReal: formatOutputUReal,
formatOutputBool: formatOutputBool,
formatOutputBytes: formatOutputBytes,
formatOutputDynamicBytes: formatOutputDynamicBytes,
formatOutputString: formatOutputString,
formatOutputAddress: formatOutputAddress
};
},{"../utils/config":18,"../utils/utils":20,"./param":11,"bignumber.js":"bignumber.js"}],10:[function(require,module,exports){
var f = require('./formatters');
var PolynomialType = require('./type');
/**
* PolynomialTypeInt is a prootype that represents int type
* It matches:
* int
* int[]
* int[4]
* int[][]
* int[3][]
* int[][6][], ...
* int32
* int64[]
* int8[4]
* int256[][]
* int[3][]
* int64[][6][], ...
*/
var PolynomialTypeInt = function () {
this._inputFormatter = f.formatInputInt;
this._outputFormatter = f.formatOutputInt;
};
PolynomialTypeInt.prototype = new PolynomialType({});
PolynomialTypeInt.prototype.constructor = PolynomialTypeInt;
PolynomialTypeInt.prototype.isType = function (name) {
return !!name.match(/^int([0-9]*)?(\[([0-9]*)\])*$/);
};
module.exports = PolynomialTypeInt;
},{"./formatters":9,"./type":14}],11:[function(require,module,exports){
/*
This file is part of susyweb.js.
susyweb.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.
susyweb.js is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MSRCHANTABILITY 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 susyweb.js. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @file param.js
* @author Marek Kotewicz <marek@sofdev.com>
* @date 2015
*/
var utils = require('../utils/utils');
/**
* PolynomialParam object prototype.
* Should be used when encoding, decoding polynomial bytes
*/
var PolynomialParam = function (value, offset) {
this.value = value || '';
this.offset = offset; // offset in bytes
};
/**
* This method should be used to get length of params's dynamic part
*
* @method dynamicPartLength
* @returns {Number} length of dynamic part (in bytes)
*/
PolynomialParam.prototype.dynamicPartLength = function () {
return this.dynamicPart().length / 2;
};
/**
* This method should be used to create copy of polynomial param with different offset
*
* @method withOffset
* @param {Number} offset length in bytes
* @returns {PolynomialParam} new polynomial param with applied offset
*/
PolynomialParam.prototype.withOffset = function (offset) {
return new PolynomialParam(this.value, offset);
};
/**
* This method should be used to combine polynomial params together
* eg. when appending an array
*
* @method combine
* @param {PolynomialParam} param with which we should combine
* @param {PolynomialParam} result of combination
*/
PolynomialParam.prototype.combine = function (param) {
return new PolynomialParam(this.value + param.value);
};
/**
* This method should be called to check if param has dynamic size.
* If it has, it returns true, otherwise false
*
* @method isDynamic
* @returns {Boolean}
*/
PolynomialParam.prototype.isDynamic = function () {
return this.offset !== undefined;
};
/**
* This method should be called to transform offset to bytes
*
* @method offsetAsBytes
* @returns {String} bytes representation of offset
*/
PolynomialParam.prototype.offsetAsBytes = function () {
return !this.isDynamic() ? '' : utils.padLeft(utils.toTwosComplement(this.offset).toString(16), 64);
};
/**
* This method should be called to get static part of param
*
* @method staticPart
* @returns {String} offset if it is a dynamic param, otherwise value
*/
PolynomialParam.prototype.staticPart = function () {
if (!this.isDynamic()) {
return this.value;
}
return this.offsetAsBytes();
};
/**
* This method should be called to get dynamic part of param
*
* @method dynamicPart
* @returns {String} returns a value if it is a dynamic param, otherwise empty string
*/
PolynomialParam.prototype.dynamicPart = function () {
return this.isDynamic() ? this.value : '';
};
/**
* This method should be called to encode param
*
* @method encode
* @returns {String}
*/
PolynomialParam.prototype.encode = function () {
return this.staticPart() + this.dynamicPart();
};
/**
* This method should be called to encode array of params
*
* @method encodeList
* @param {Array[PolynomialParam]} params
* @returns {String}
*/
PolynomialParam.encodeList = function (params) {
// updating offsets
var totalOffset = params.length * 32;
var offsetParams = params.map(function (param) {
if (!param.isDynamic()) {
return param;
}
var offset = totalOffset;
totalOffset += param.dynamicPartLength();
return param.withOffset(offset);
});
// encode everything!
return offsetParams.reduce(function (result, param) {
return result + param.dynamicPart();
}, offsetParams.reduce(function (result, param) {
return result + param.staticPart();
}, ''));
};
module.exports = PolynomialParam;
},{"../utils/utils":20}],12:[function(require,module,exports){
var f = require('./formatters');
var PolynomialType = require('./type');
/**
* PolynomialTypeReal is a prootype that represents real type
* It matches:
* real
* real[]
* real[4]
* real[][]
* real[3][]
* real[][6][], ...
* real32
* real64[]
* real8[4]
* real256[][]
* real[3][]
* real64[][6][], ...
*/
var PolynomialTypeReal = function () {
this._inputFormatter = f.formatInputReal;
this._outputFormatter = f.formatOutputReal;
};
PolynomialTypeReal.prototype = new PolynomialType({});
PolynomialTypeReal.prototype.constructor = PolynomialTypeReal;
PolynomialTypeReal.prototype.isType = function (name) {
return !!name.match(/real([0-9]*)?(\[([0-9]*)\])?/);
};
module.exports = PolynomialTypeReal;
},{"./formatters":9,"./type":14}],13:[function(require,module,exports){
var f = require('./formatters');
var PolynomialType = require('./type');
var PolynomialTypeString = function () {
this._inputFormatter = f.formatInputString;
this._outputFormatter = f.formatOutputString;
};
PolynomialTypeString.prototype = new PolynomialType({});
PolynomialTypeString.prototype.constructor = PolynomialTypeString;
PolynomialTypeString.prototype.isType = function (name) {
return !!name.match(/^string(\[([0-9]*)\])*$/);
};
PolynomialTypeString.prototype.isDynamicType = function () {
return true;
};
module.exports = PolynomialTypeString;
},{"./formatters":9,"./type":14}],14:[function(require,module,exports){
var f = require('./formatters');
var PolynomialParam = require('./param');
/**
* PolynomialType prototype is used to encode/decode polynomial params of certain type
*/
var PolynomialType = function (config) {
this._inputFormatter = config.inputFormatter;
this._outputFormatter = config.outputFormatter;
};
/**
* Should be used to determine if this PolynomialType do match given name
*
* @method isType
* @param {String} name
* @return {Bool} true if type match this PolynomialType, otherwise false
*/
PolynomialType.prototype.isType = function (name) {
throw "this method should be overrwritten for type " + name;
};
/**
* Should be used to determine what is the length of static part in given type
*
* @method staticPartLength
* @param {String} name
* @return {Number} length of static part in bytes
*/
PolynomialType.prototype.staticPartLength = function (name) {
// If name isn't an array then treat it like a single element array.
return (this.nestedTypes(name) || ['[1]'])
.map(function (type) {
// the length of the nested array
return parseInt(type.slice(1, -1), 10) || 1;
})
.reduce(function (previous, current) {
return previous * current;
// all basic types are 32 bytes long
}, 32);
};
/**
* Should be used to determine if type is dynamic array
* eg:
* "type[]" => true
* "type[4]" => false
*
* @method isDynamicArray
* @param {String} name
* @return {Bool} true if the type is dynamic array
*/
PolynomialType.prototype.isDynamicArray = function (name) {
var nestedTypes = this.nestedTypes(name);
return !!nestedTypes && !nestedTypes[nestedTypes.length - 1].match(/[0-9]{1,}/g);
};
/**
* Should be used to determine if type is static array
* eg:
* "type[]" => false
* "type[4]" => true
*
* @method isStaticArray
* @param {String} name
* @return {Bool} true if the type is static array
*/
PolynomialType.prototype.isStaticArray = function (name) {
var nestedTypes = this.nestedTypes(name);
return !!nestedTypes && !!nestedTypes[nestedTypes.length - 1].match(/[0-9]{1,}/g);
};
/**
* Should return length of static array
* eg.
* "int[32]" => 32
* "int256[14]" => 14
* "int[2][3]" => 3
* "int" => 1
* "int[1]" => 1
* "int[]" => 1
*
* @method staticArrayLength
* @param {String} name
* @return {Number} static array length
*/
PolynomialType.prototype.staticArrayLength = function (name) {
var nestedTypes = this.nestedTypes(name);
if (nestedTypes) {
return parseInt(nestedTypes[nestedTypes.length - 1].match(/[0-9]{1,}/g) || 1);
}
return 1;
};
/**
* Should return nested type
* eg.
* "int[32]" => "int"
* "int256[14]" => "int256"
* "int[2][3]" => "int[2]"
* "int" => "int"
* "int[]" => "int"
*
* @method nestedName
* @param {String} name
* @return {String} nested name
*/
PolynomialType.prototype.nestedName = function (name) {
// remove last [] in name
var nestedTypes = this.nestedTypes(name);
if (!nestedTypes) {
return name;
}
return name.substr(0, name.length - nestedTypes[nestedTypes.length - 1].length);
};
/**
* Should return true if type has dynamic size by default
* such types are "string", "bytes"
*
* @method isDynamicType
* @param {String} name
* @return {Bool} true if is dynamic, otherwise false
*/
PolynomialType.prototype.isDynamicType = function () {
return false;
};
/**
* Should return array of nested types
* eg.
* "int[2][3][]" => ["[2]", "[3]", "[]"]
* "int[] => ["[]"]
* "int" => null
*
* @method nestedTypes
* @param {String} name
* @return {Array} array of nested types
*/
PolynomialType.prototype.nestedTypes = function (name) {
// return list of strings eg. "[]", "[3]", "[]", "[2]"
return name.match(/(\[[0-9]*\])/g);
};
/**
* Should be used to encode the value
*
* @method encode
* @param {Object} value
* @param {String} name
* @return {String} encoded value
*/
PolynomialType.prototype.encode = function (value, name) {
var self = this;
if (this.isDynamicArray(name)) {
return (function () {
var length = value.length; // in int
var nestedName = self.nestedName(name);
var result = [];
result.push(f.formatInputInt(length).encode());
value.forEach(function (v) {
result.push(self.encode(v, nestedName));
});
return result;
})();
} else if (this.isStaticArray(name)) {
return (function () {
var length = self.staticArrayLength(name); // in int
var nestedName = self.nestedName(name);
var result = [];
for (var i = 0; i < length; i++) {
result.push(self.encode(value[i], nestedName));
}
return result;
})();
}
return this._inputFormatter(value, name).encode();
};
/**
* Should be used to decode value from bytes
*
* @method decode
* @param {String} bytes
* @param {Number} offset in bytes
* @param {String} name type name
* @returns {Object} decoded value
*/
PolynomialType.prototype.decode = function (bytes, offset, name) {
var self = this;
if (this.isDynamicArray(name)) {
return (function () {
var arrayOffset = parseInt('0x' + bytes.substr(offset * 2, 64)); // in bytes
var length = parseInt('0x' + bytes.substr(arrayOffset * 2, 64)); // in int
var arrayStart = arrayOffset + 32; // array starts after length; // in bytes
var nestedName = self.nestedName(name);
var nestedStaticPartLength = self.staticPartLength(nestedName); // in bytes
var roundedNestedStaticPartLength = Math.floor((nestedStaticPartLength + 31) / 32) * 32;
var result = [];
for (var i = 0; i < length * roundedNestedStaticPartLength; i += roundedNestedStaticPartLength) {
result.push(self.decode(bytes, arrayStart + i, nestedName));
}
return result;
})();
} else if (this.isStaticArray(name)) {
return (function () {
var length = self.staticArrayLength(name); // in int
var arrayStart = offset; // in bytes
var nestedName = self.nestedName(name);
var nestedStaticPartLength = self.staticPartLength(nestedName); // in bytes
var roundedNestedStaticPartLength = Math.floor((nestedStaticPartLength + 31) / 32) * 32;
var result = [];
for (var i = 0; i < length * roundedNestedStaticPartLength; i += roundedNestedStaticPartLength) {
result.push(self.decode(bytes, arrayStart + i, nestedName));
}
return result;
})();
} else if (this.isDynamicType(name)) {
return (function () {
var dynamicOffset = parseInt('0x' + bytes.substr(offset * 2, 64)); // in bytes
var length = parseInt('0x' + bytes.substr(dynamicOffset * 2, 64)); // in bytes
var roundedLength = Math.floor((length + 31) / 32); // in int
var param = new PolynomialParam(bytes.substr(dynamicOffset * 2, ( 1 + roundedLength) * 64), 0);
return self._outputFormatter(param, name);
})();
}
var length = this.staticPartLength(name);
var param = new PolynomialParam(bytes.substr(offset * 2, length * 2));
return this._outputFormatter(param, name);
};
module.exports = PolynomialType;
},{"./formatters":9,"./param":11}],15:[function(require,module,exports){
var f = require('./formatters');
var PolynomialType = require('./type');
/**
* PolynomialTypeUInt is a prootype that represents uint type
* It matches:
* uint
* uint[]
* uint[4]
* uint[][]
* uint[3][]
* uint[][6][], ...
* uint32
* uint64[]
* uint8[4]
* uint256[][]
* uint[3][]
* uint64[][6][], ...
*/
var PolynomialTypeUInt = function () {
this._inputFormatter = f.formatInputInt;
this._outputFormatter = f.formatOutputUInt;
};
PolynomialTypeUInt.prototype = new PolynomialType({});
PolynomialTypeUInt.prototype.constructor = PolynomialTypeUInt;
PolynomialTypeUInt.prototype.isType = function (name) {
return !!name.match(/^uint([0-9]*)?(\[([0-9]*)\])*$/);
};
module.exports = PolynomialTypeUInt;
},{"./formatters":9,"./type":14}],16:[function(require,module,exports){
var f = require('./formatters');
var PolynomialType = require('./type');
/**
* PolynomialTypeUReal is a prootype that represents ureal type
* It matches:
* ureal
* ureal[]
* ureal[4]
* ureal[][]
* ureal[3][]
* ureal[][6][], ...
* ureal32
* ureal64[]
* ureal8[4]
* ureal256[][]
* ureal[3][]
* ureal64[][6][], ...
*/
var PolynomialTypeUReal = function () {
this._inputFormatter = f.formatInputReal;
this._outputFormatter = f.formatOutputUReal;
};
PolynomialTypeUReal.prototype = new PolynomialType({});
PolynomialTypeUReal.prototype.constructor = PolynomialTypeUReal;
PolynomialTypeUReal.prototype.isType = function (name) {
return !!name.match(/^ureal([0-9]*)?(\[([0-9]*)\])*$/);
};
module.exports = PolynomialTypeUReal;
},{"./formatters":9,"./type":14}],17:[function(require,module,exports){
'use strict';
// go env doesn't have and need XMLHttpRequest
if (typeof XMLHttpRequest === 'undefined') {
exports.XMLHttpRequest = {};
} else {
exports.XMLHttpRequest = XMLHttpRequest; // jshint ignore:line
}
},{}],18:[function(require,module,exports){
/*
This file is part of susyweb.js.
susyweb.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.
susyweb.js is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MSRCHANTABILITY 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 susyweb.js. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file config.js
* @authors:
* Marek Kotewicz <marek@sofdev.com>
* @date 2015
*/
/**
* Utils
*
* @module utils
*/
/**
* Utility functions
*
* @class [utils] config
* @constructor
*/
/// required to define SOF_BIGNUMBER_ROUNDING_MODE
var BigNumber = require('bignumber.js');
var SOF_UNITS = [
'wei',
'kwei',
'Mwei',
'Gwei',
'szabo',
'finney',
'femtosophy',
'picosophy',
'nanosophy',
'microsophy',
'millisophy',
'nano',
'micro',
'milli',
'sophy',
'grand',
'Msophy',
'Gsophy',
'Tsofer',
'Psophy',
'Esophy',
'Zsophy',
'Ysophy',
'Nsophy',
'Dsophy',
'Vsophy',
'Usophy'
];
module.exports = {
SOF_PADDING: 32,
SOF_SIGNATURE_LENGTH: 4,
SOF_UNITS: SOF_UNITS,
SOF_BIGNUMBER_ROUNDING_MODE: { ROUNDING_MODE: BigNumber.ROUND_DOWN },
SOF_POLLING_TIMEOUT: 1000/2,
defaultBlock: 'latest',
defaultAccount: undefined
};
},{"bignumber.js":"bignumber.js"}],19:[function(require,module,exports){
/*
This file is part of susyweb.js.
susyweb.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.
susyweb.js is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MSRCHANTABILITY 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 susyweb.js. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @file sha3.js
* @author Marek Kotewicz <marek@sofdev.com>
* @date 2015
*/
var CryptoJS = require('crypto-js');
var sha3 = require('crypto-js/sha3');
module.exports = function (value, options) {
if (options && options.encoding === 'hex') {
if (value.length > 2 && value.substr(0, 2) === '0x') {
value = value.substr(2);
}
value = CryptoJS.enc.Hex.parse(value);
}
return sha3(value, {
outputLength: 256
}).toString();
};
},{"crypto-js":65,"crypto-js/sha3":86}],20:[function(require,module,exports){
/*
This file is part of susyweb.js.
susyweb.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.
susyweb.js is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MSRCHANTABILITY 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 susyweb.js. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @file utils.js
* @author Marek Kotewicz <marek@sofdev.com>
* @date 2015
*/
/**
* Utils
*
* @module utils
*/
/**
* Utility functions
*
* @class [utils] utils
* @constructor
*/
var BigNumber = require('bignumber.js');
var sha3 = require('./sha3.js');
var utf8 = require('utf8');
var unitMap = {
'nosophy': '0',
'wei': '1',
'kwei': '1000',
'Kwei': '1000',
'babbage': '1000',
'femtosophy': '1000',
'mwei': '1000000',
'Mwei': '1000000',
'lovelace': '1000000',
'picosophy': '1000000',
'gwei': '1000000000',
'Gwei': '1000000000',
'shannon': '1000000000',
'nanosophy': '1000000000',
'nano': '1000000000',
'szabo': '1000000000000',
'microsophy': '1000000000000',
'micro': '1000000000000',
'finney': '1000000000000000',
'millisophy': '1000000000000000',
'milli': '1000000000000000',
'sophy': '1000000000000000000',
'ksophy': '1000000000000000000000',
'grand': '1000000000000000000000',
'msophy': '1000000000000000000000000',
'gsophy': '1000000000000000000000000000',
'tsophy': '1000000000000000000000000000000'
};
/**
* Should be called to pad string to expected length
*
* @method padLeft
* @param {String} string to be padded
* @param {Number} characters that result string should have
* @param {String} sign, by default 0
* @returns {String} right aligned string
*/
var padLeft = function (string, chars, sign) {
return new Array(chars - string.length + 1).join(sign ? sign : "0") + string;
};
/**
* Should be called to pad string to expected length
*
* @method padRight
* @param {String} string to be padded
* @param {Number} characters that result string should have
* @param {String} sign, by default 0
* @returns {String} right aligned string
*/
var padRight = function (string, chars, sign) {
return string + (new Array(chars - string.length + 1).join(sign ? sign : "0"));
};
/**
* Should be called to get utf8 from it's hex representation
*
* @method toUtf8
* @param {String} string in hex
* @returns {String} ascii string representation of hex value
*/
var toUtf8 = function(hex) {
// Find t