UNPKG

@expanse/web3

Version:

Expanse and Ethereum JavaScript API, middleware to talk to an expanse or ethereum over RPC

1,907 lines (1,699 loc) 406 kB
require=(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({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": [], "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 SolidityType = require('./type'); /** * SolidityTypeAddress is a prootype that represents address type * It matches: * address * address[] * address[4] * address[][] * address[3][] * address[][6][], ... */ var SolidityTypeAddress = function () { this._inputFormatter = f.formatInputInt; this._outputFormatter = f.formatOutputAddress; }; SolidityTypeAddress.prototype = new SolidityType({}); SolidityTypeAddress.prototype.constructor = SolidityTypeAddress; SolidityTypeAddress.prototype.isType = function (name) { return !!name.match(/address(\[([0-9]*)\])?/); }; SolidityTypeAddress.prototype.staticPartLength = function (name) { return 32 * this.staticArrayLength(name); }; module.exports = SolidityTypeAddress; },{"./formatters":9,"./type":14}],5:[function(require,module,exports){ var f = require('./formatters'); var SolidityType = require('./type'); /** * SolidityTypeBool is a prootype that represents bool type * It matches: * bool * bool[] * bool[4] * bool[][] * bool[3][] * bool[][6][], ... */ var SolidityTypeBool = function () { this._inputFormatter = f.formatInputBool; this._outputFormatter = f.formatOutputBool; }; SolidityTypeBool.prototype = new SolidityType({}); SolidityTypeBool.prototype.constructor = SolidityTypeBool; SolidityTypeBool.prototype.isType = function (name) { return !!name.match(/^bool(\[([0-9]*)\])*$/); }; SolidityTypeBool.prototype.staticPartLength = function (name) { return 32 * this.staticArrayLength(name); }; module.exports = SolidityTypeBool; },{"./formatters":9,"./type":14}],6:[function(require,module,exports){ var f = require('./formatters'); var SolidityType = require('./type'); /** * SolidityTypeBytes is a prootype that represents bytes type * It matches: * bytes * bytes[] * bytes[4] * bytes[][] * bytes[3][] * bytes[][6][], ... * bytes32 * bytes64[] * bytes8[4] * bytes256[][] * bytes[3][] * bytes64[][6][], ... */ var SolidityTypeBytes = function () { this._inputFormatter = f.formatInputBytes; this._outputFormatter = f.formatOutputBytes; }; SolidityTypeBytes.prototype = new SolidityType({}); SolidityTypeBytes.prototype.constructor = SolidityTypeBytes; SolidityTypeBytes.prototype.isType = function (name) { return !!name.match(/^bytes([0-9]{1,})(\[([0-9]*)\])*$/); }; SolidityTypeBytes.prototype.staticPartLength = function (name) { var matches = name.match(/^bytes([0-9]*)/); var size = parseInt(matches[1]); return size * this.staticArrayLength(name); }; module.exports = SolidityTypeBytes; },{"./formatters":9,"./type":14}],7:[function(require,module,exports){ /* This file is part of web3.js. web3.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. web3.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 web3.js. If not, see <http://www.gnu.org/licenses/>. */ /** * @file coder.js * @author Marek Kotewicz <marek@ethdev.com> * @date 2015 */ var f = require('./formatters'); var SolidityTypeAddress = require('./address'); var SolidityTypeBool = require('./bool'); var SolidityTypeInt = require('./int'); var SolidityTypeUInt = require('./uint'); var SolidityTypeDynamicBytes = require('./dynamicbytes'); var SolidityTypeString = require('./string'); var SolidityTypeReal = require('./real'); var SolidityTypeUReal = require('./ureal'); var SolidityTypeBytes = require('./bytes'); /** * SolidityCoder prototype should be used to encode/decode solidity params of any type */ var SolidityCoder = function (types) { this._types = types; }; /** * This method should be used to transform type to SolidityType * * @method _requireType * @param {String} type * @returns {SolidityType} * @throws {Error} throws if no matching type is found */ SolidityCoder.prototype._requireType = function (type) { var solidityType = this._types.filter(function (t) { return t.isType(type); })[0]; if (!solidityType) { throw Error('invalid solidity type!: ' + type); } return solidityType; }; /** * Should be used to encode plain param * * @method encodeParam * @param {String} type * @param {Object} plain param * @return {String} encoded plain param */ SolidityCoder.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 */ SolidityCoder.prototype.encodeParams = function (types, params) { var solidityTypes = this.getSolidityTypes(types); var encodeds = solidityTypes.map(function (solidityType, index) { return solidityType.encode(params[index], types[index]); }); var dynamicOffset = solidityTypes.reduce(function (acc, solidityType, index) { var staticPartLength = solidityType.staticPartLength(types[index]); var roundedStaticPartLength = Math.floor((staticPartLength + 31) / 32) * 32; return acc + roundedStaticPartLength; }, 0); var result = this.encodeMultiWithOffset(types, solidityTypes, encodeds, dynamicOffset); return result; }; SolidityCoder.prototype.encodeMultiWithOffset = function (types, solidityTypes, encodeds, dynamicOffset) { var result = ""; var self = this; var isDynamic = function (i) { return solidityTypes[i].isDynamicArray(types[i]) || solidityTypes[i].isDynamicType(types[i]); }; types.forEach(function (type, i) { if (isDynamic(i)) { result += f.formatInputInt(dynamicOffset).encode(); var e = self.encodeWithOffset(types[i], solidityTypes[i], encodeds[i], dynamicOffset); dynamicOffset += e.length / 2; } else { // don't add length to dynamicOffset. it's already counted result += self.encodeWithOffset(types[i], solidityTypes[i], encodeds[i], dynamicOffset); } // TODO: figure out nested arrays }); types.forEach(function (type, i) { if (isDynamic(i)) { var e = self.encodeWithOffset(types[i], solidityTypes[i], encodeds[i], dynamicOffset); dynamicOffset += e.length / 2; result += e; } }); return result; }; // TODO: refactor whole encoding! SolidityCoder.prototype.encodeWithOffset = function (type, solidityType, encoded, offset) { var self = this; if (solidityType.isDynamicArray(type)) { return (function () { // offset was already set var nestedName = solidityType.nestedName(type); var nestedStaticPartLength = solidityType.staticPartLength(nestedName); var result = encoded[0]; (function () { var previousLength = 2; // in int if (solidityType.isDynamicArray(nestedName)) { for (var i = 1; i < encoded.length; i++) { previousLength += +(encoded[i - 1])[0] || 0; result += f.formatInputInt(offset + i * nestedStaticPartLength + previousLength * 32).encode(); } } })(); // first element is length, skip it (function () { for (var i = 0; i < encoded.length - 1; i++) { var additionalOffset = result / 2; result += self.encodeWithOffset(nestedName, solidityType, encoded[i + 1], offset + additionalOffset); } })(); return result; })(); } else if (solidityType.isStaticArray(type)) { return (function () { var nestedName = solidityType.nestedName(type); var nestedStaticPartLength = solidityType.staticPartLength(nestedName); var result = ""; if (solidityType.isDynamicArray(nestedName)) { (function () { var previousLength = 0; // in int for (var i = 0; i < encoded.length; i++) { // calculate length of previous item previousLength += +(encoded[i - 1] || [])[0] || 0; result += f.formatInputInt(offset + i * nestedStaticPartLength + previousLength * 32).encode(); } })(); } (function () { for (var i = 0; i < encoded.length; i++) { var additionalOffset = result / 2; result += self.encodeWithOffset(nestedName, solidityType, encoded[i], 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 */ SolidityCoder.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 */ SolidityCoder.prototype.decodeParams = function (types, bytes) { var solidityTypes = this.getSolidityTypes(types); var offsets = this.getOffsets(types, solidityTypes); return solidityTypes.map(function (solidityType, index) { return solidityType.decode(bytes, offsets[index], types[index], index); }); }; SolidityCoder.prototype.getOffsets = function (types, solidityTypes) { var lengths = solidityTypes.map(function (solidityType, index) { return solidityType.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 = solidityTypes[index].staticPartLength(types[index]); return length - staticPartLength; }); }; SolidityCoder.prototype.getSolidityTypes = function (types) { var self = this; return types.map(function (type) { return self._requireType(type); }); }; var coder = new SolidityCoder([ new SolidityTypeAddress(), new SolidityTypeBool(), new SolidityTypeInt(), new SolidityTypeUInt(), new SolidityTypeDynamicBytes(), new SolidityTypeBytes(), new SolidityTypeString(), new SolidityTypeReal(), new SolidityTypeUReal() ]); 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 SolidityType = require('./type'); var SolidityTypeDynamicBytes = function () { this._inputFormatter = f.formatInputDynamicBytes; this._outputFormatter = f.formatOutputDynamicBytes; }; SolidityTypeDynamicBytes.prototype = new SolidityType({}); SolidityTypeDynamicBytes.prototype.constructor = SolidityTypeDynamicBytes; SolidityTypeDynamicBytes.prototype.isType = function (name) { return !!name.match(/^bytes(\[([0-9]*)\])*$/); }; SolidityTypeDynamicBytes.prototype.staticPartLength = function (name) { return 32 * this.staticArrayLength(name); }; SolidityTypeDynamicBytes.prototype.isDynamicType = function () { return true; }; module.exports = SolidityTypeDynamicBytes; },{"./formatters":9,"./type":14}],9:[function(require,module,exports){ /* This file is part of web3.js. web3.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. web3.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 web3.js. If not, see <http://www.gnu.org/licenses/>. */ /** * @file formatters.js * @author Marek Kotewicz <marek@ethdev.com> * @date 2015 */ var BigNumber = require('bignumber.js'); var utils = require('../utils/utils'); var c = require('../utils/config'); var SolidityParam = 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 {SolidityParam} */ var formatInputInt = function (value) { BigNumber.config(c.ETH_BIGNUMBER_ROUNDING_MODE); var result = utils.padLeft(utils.toTwosComplement(value).round().toString(16), 64); return new SolidityParam(result); }; /** * Formats input bytes * * @method formatInputBytes * @param {String} * @returns {SolidityParam} */ 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 SolidityParam(result); }; /** * Formats input bytes * * @method formatDynamicInputBytes * @param {String} * @returns {SolidityParam} */ 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 SolidityParam(formatInputInt(length).value + result); }; /** * Formats input value to byte representation of string * * @method formatInputString * @param {String} * @returns {SolidityParam} */ 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 SolidityParam(formatInputInt(length).value + result); }; /** * Formats input value to byte representation of bool * * @method formatInputBool * @param {Boolean} * @returns {SolidityParam} */ var formatInputBool = function (value) { var result = '000000000000000000000000000000000000000000000000000000000000000' + (value ? '1' : '0'); return new SolidityParam(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 {SolidityParam} */ 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 {SolidityParam} 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 {SolidityParam} * @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 {SolidityParam} * @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 {SolidityParam} * @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 {SolidityParam} * @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 {SolidityParam} left-aligned hex representation of string * @returns {String} hex string */ var formatOutputBytes = function (param) { return '0x' + param.staticPart(); }; /** * Should be used to format output bytes * * @method formatOutputDynamicBytes * @param {SolidityParam} 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 {SolidityParam} 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 {SolidityParam} 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 SolidityType = require('./type'); /** * SolidityTypeInt 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 SolidityTypeInt = function () { this._inputFormatter = f.formatInputInt; this._outputFormatter = f.formatOutputInt; }; SolidityTypeInt.prototype = new SolidityType({}); SolidityTypeInt.prototype.constructor = SolidityTypeInt; SolidityTypeInt.prototype.isType = function (name) { return !!name.match(/^int([0-9]*)?(\[([0-9]*)\])*$/); }; SolidityTypeInt.prototype.staticPartLength = function (name) { return 32 * this.staticArrayLength(name); }; module.exports = SolidityTypeInt; },{"./formatters":9,"./type":14}],11:[function(require,module,exports){ /* This file is part of web3.js. web3.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. web3.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 web3.js. If not, see <http://www.gnu.org/licenses/>. */ /** * @file param.js * @author Marek Kotewicz <marek@ethdev.com> * @date 2015 */ var utils = require('../utils/utils'); /** * SolidityParam object prototype. * Should be used when encoding, decoding solidity bytes */ var SolidityParam = 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) */ SolidityParam.prototype.dynamicPartLength = function () { return this.dynamicPart().length / 2; }; /** * This method should be used to create copy of solidity param with different offset * * @method withOffset * @param {Number} offset length in bytes * @returns {SolidityParam} new solidity param with applied offset */ SolidityParam.prototype.withOffset = function (offset) { return new SolidityParam(this.value, offset); }; /** * This method should be used to combine solidity params together * eg. when appending an array * * @method combine * @param {SolidityParam} param with which we should combine * @param {SolidityParam} result of combination */ SolidityParam.prototype.combine = function (param) { return new SolidityParam(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} */ SolidityParam.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 */ SolidityParam.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 */ SolidityParam.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 */ SolidityParam.prototype.dynamicPart = function () { return this.isDynamic() ? this.value : ''; }; /** * This method should be called to encode param * * @method encode * @returns {String} */ SolidityParam.prototype.encode = function () { return this.staticPart() + this.dynamicPart(); }; /** * This method should be called to encode array of params * * @method encodeList * @param {Array[SolidityParam]} params * @returns {String} */ SolidityParam.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 = SolidityParam; },{"../utils/utils":20}],12:[function(require,module,exports){ var f = require('./formatters'); var SolidityType = require('./type'); /** * SolidityTypeReal 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 SolidityTypeReal = function () { this._inputFormatter = f.formatInputReal; this._outputFormatter = f.formatOutputReal; }; SolidityTypeReal.prototype = new SolidityType({}); SolidityTypeReal.prototype.constructor = SolidityTypeReal; SolidityTypeReal.prototype.isType = function (name) { return !!name.match(/real([0-9]*)?(\[([0-9]*)\])?/); }; SolidityTypeReal.prototype.staticPartLength = function (name) { return 32 * this.staticArrayLength(name); }; module.exports = SolidityTypeReal; },{"./formatters":9,"./type":14}],13:[function(require,module,exports){ var f = require('./formatters'); var SolidityType = require('./type'); var SolidityTypeString = function () { this._inputFormatter = f.formatInputString; this._outputFormatter = f.formatOutputString; }; SolidityTypeString.prototype = new SolidityType({}); SolidityTypeString.prototype.constructor = SolidityTypeString; SolidityTypeString.prototype.isType = function (name) { return !!name.match(/^string(\[([0-9]*)\])*$/); }; SolidityTypeString.prototype.staticPartLength = function (name) { return 32 * this.staticArrayLength(name); }; SolidityTypeString.prototype.isDynamicType = function () { return true; }; module.exports = SolidityTypeString; },{"./formatters":9,"./type":14}],14:[function(require,module,exports){ var f = require('./formatters'); var SolidityParam = require('./param'); /** * SolidityType prototype is used to encode/decode solidity params of certain type */ var SolidityType = function (config) { this._inputFormatter = config.inputFormatter; this._outputFormatter = config.outputFormatter; }; /** * Should be used to determine if this SolidityType do match given name * * @method isType * @param {String} name * @return {Bool} true if type match this SolidityType, otherwise false */ SolidityType.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 */ SolidityType.prototype.staticPartLength = function (name) { throw "this method should be overrwritten for type: " + name; }; /** * 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 */ SolidityType.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 */ SolidityType.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 */ SolidityType.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 */ SolidityType.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 */ SolidityType.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 */ SolidityType.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 */ SolidityType.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 */ SolidityType.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 return self._outputFormatter(new SolidityParam(bytes.substr(dynamicOffset * 2, ( 1 + roundedLength) * 64), 0)); })(); } var length = this.staticPartLength(name); return this._outputFormatter(new SolidityParam(bytes.substr(offset * 2, length * 2))); }; module.exports = SolidityType; },{"./formatters":9,"./param":11}],15:[function(require,module,exports){ var f = require('./formatters'); var SolidityType = require('./type'); /** * SolidityTypeUInt 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 SolidityTypeUInt = function () { this._inputFormatter = f.formatInputInt; this._outputFormatter = f.formatOutputUInt; }; SolidityTypeUInt.prototype = new SolidityType({}); SolidityTypeUInt.prototype.constructor = SolidityTypeUInt; SolidityTypeUInt.prototype.isType = function (name) { return !!name.match(/^uint([0-9]*)?(\[([0-9]*)\])*$/); }; SolidityTypeUInt.prototype.staticPartLength = function (name) { return 32 * this.staticArrayLength(name); }; module.exports = SolidityTypeUInt; },{"./formatters":9,"./type":14}],16:[function(require,module,exports){ var f = require('./formatters'); var SolidityType = require('./type'); /** * SolidityTypeUReal 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 SolidityTypeUReal = function () { this._inputFormatter = f.formatInputReal; this._outputFormatter = f.formatOutputUReal; }; SolidityTypeUReal.prototype = new SolidityType({}); SolidityTypeUReal.prototype.constructor = SolidityTypeUReal; SolidityTypeUReal.prototype.isType = function (name) { return !!name.match(/^ureal([0-9]*)?(\[([0-9]*)\])*$/); }; SolidityTypeUReal.prototype.staticPartLength = function (name) { return 32 * this.staticArrayLength(name); }; module.exports = SolidityTypeUReal; },{"./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 web3.js. web3.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. web3.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 web3.js. If not, see <http://www.gnu.org/licenses/>. */ /** @file config.js * @authors: * Marek Kotewicz <marek@ethdev.com> * @date 2015 */ /** * Utils * * @module utils */ /** * Utility functions * * @class [utils] config * @constructor */ /// required to define ETH_BIGNUMBER_ROUNDING_MODE var BigNumber = require('bignumber.js'); var ETH_UNITS = [ 'wei', 'kwei', 'Mwei', 'Gwei', 'szabo', 'finney', 'femtoether', 'picoether', 'nanoether', 'microether', 'milliether', 'femtoexp', 'picoexp', 'nanoexp', 'microexp', 'milliexp', 'femtoexpanse', 'picoexpanse', 'nanoexpanse', 'microexpanse', 'milliexpanse', 'nano', 'micro', 'milli', 'ether', 'grand', 'Mether', 'Gether', 'Tether', 'Pether', 'Eether', 'Zether', 'Yether', 'Nether', 'Dether', 'Vether', 'Uether', 'Mexp', 'Gexp', 'Texp', 'Pexp', 'Eexp', 'Zexp', 'Yexp', 'Nexp', 'Dexp', 'Vexp', 'Uexp', 'Mexpanse', 'Gexpanse', 'Texpanse', 'Pexpanse', 'Eexpanse', 'Zexpanse', 'Yexpanse', 'Nexpanse', 'Dexpanse', 'Vexpanse', 'Uexpanse' ]; module.exports = { ETH_PADDING: 32, ETH_SIGNATURE_LENGTH: 4, ETH_UNITS: ETH_UNITS, ETH_BIGNUMBER_ROUNDING_MODE: { ROUNDING_MODE: BigNumber.ROUND_DOWN }, ETH_POLLING_TIMEOUT: 1000/2, defaultBlock: 'latest', defaultAccount: undefined }; },{"bignumber.js":"bignumber.js"}],19:[function(require,module,exports){ /* This file is part of web3.js. web3.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. web3.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 web3.js. If not, see <http://www.gnu.org/licenses/>. */ /** * @file sha3.js * @author Marek Kotewicz <marek@ethdev.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":58,"crypto-js/sha3":79}],20:[function(require,module,exports){ /* This file is part of