diff options
author | zelig <viktor.tron@gmail.com> | 2015-05-20 09:58:49 +0800 |
---|---|---|
committer | zelig <viktor.tron@gmail.com> | 2015-05-20 09:58:49 +0800 |
commit | ea893aca8fbda0d821424ab7509a0a0cfef1f77d (patch) | |
tree | 918aebcb518b11bdf717dba2af6198d8d62162d3 /jsre/ethereum_js.go | |
parent | d92172f3d484cf54653e1dcdfde5a94f100448fa (diff) | |
download | dexon-ea893aca8fbda0d821424ab7509a0a0cfef1f77d.tar.gz dexon-ea893aca8fbda0d821424ab7509a0a0cfef1f77d.tar.zst dexon-ea893aca8fbda0d821424ab7509a0a0cfef1f77d.zip |
update web3.js to 0.4.2
Diffstat (limited to 'jsre/ethereum_js.go')
-rw-r--r-- | jsre/ethereum_js.go | 2536 |
1 files changed, 2061 insertions, 475 deletions
diff --git a/jsre/ethereum_js.go b/jsre/ethereum_js.go index a61ffcbbf..6c0ae33d7 100644 --- a/jsre/ethereum_js.go +++ b/jsre/ethereum_js.go @@ -1,7 +1,6 @@ package jsre -const Ethereum_JS = ` -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){ +const Ethereum_JS = `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){ /* This file is part of ethereum.js. @@ -18,142 +17,7 @@ require=(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof requ 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 abi.js - * @author Marek Kotewicz <marek@ethdev.com> - * @author Gav Wood <g@ethdev.com> - * @date 2014 - */ - -var utils = require('../utils/utils'); -var coder = require('./coder'); -var solUtils = require('./utils'); - -/** - * Formats input params to bytes - * - * @method formatInput - * @param {Array} abi inputs of method - * @param {Array} params that will be formatted to bytes - * @returns bytes representation of input params - */ -var formatInput = function (inputs, params) { - var i = inputs.map(function (input) { - return input.type; - }); - return coder.encodeParams(i, params); -}; - -/** - * Formats output bytes back to param list - * - * @method formatOutput - * @param {Array} abi outputs of method - * @param {String} bytes represention of output - * @returns {Array} output params - */ -var formatOutput = function (outs, bytes) { - var o = outs.map(function (out) { - return out.type; - }); - - return coder.decodeParams(o, bytes); -}; - /** - * Should be called to create input parser for contract with given abi - * - * @method inputParser - * @param {Array} contract abi - * @returns {Object} input parser object for given json abi - * TODO: refactor creating the parser, do not double logic from contract - */ -var inputParser = function (json) { - var parser = {}; - json.forEach(function (method) { - var displayName = utils.extractDisplayName(method.name); - var typeName = utils.extractTypeName(method.name); - - var impl = function () { - var params = Array.prototype.slice.call(arguments); - return formatInput(method.inputs, params); - }; - - if (parser[displayName] === undefined) { - parser[displayName] = impl; - } - - parser[displayName][typeName] = impl; - }); - - return parser; -}; - -/** - * Should be called to create output parser for contract with given abi - * - * @method outputParser - * @param {Array} contract abi - * @returns {Object} output parser for given json abi - */ -var outputParser = function (json) { - var parser = {}; - json.forEach(function (method) { - - var displayName = utils.extractDisplayName(method.name); - var typeName = utils.extractTypeName(method.name); - - var impl = function (output) { - return formatOutput(method.outputs, output); - }; - - if (parser[displayName] === undefined) { - parser[displayName] = impl; - } - - parser[displayName][typeName] = impl; - }); - - return parser; -}; - -var formatConstructorParams = function (abi, params) { - var constructor = solUtils.getConstructor(abi, params.length); - if (!constructor) { - if (params.length > 0) { - console.warn("didn't found matching constructor, using default one"); - } - return ''; - } - return formatInput(constructor.inputs, params); -}; - -module.exports = { - inputParser: inputParser, - outputParser: outputParser, - formatInput: formatInput, - formatOutput: formatOutput, - formatConstructorParams: formatConstructorParams -}; - -},{"../utils/utils":8,"./coder":2,"./utils":5}],2:[function(require,module,exports){ -/* - 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 coder.js * @author Marek Kotewicz <marek@ethdev.com> * @date 2015 @@ -208,7 +72,7 @@ SolidityType.prototype.isType = function (name) { * @method formatInput * @param {Object} param - plain object, or an array of objects * @param {Bool} arrayType - true if a param should be encoded as an array - * @return {SolidityParam} encoded param wrapped in SolidityParam object + * @return {SolidityParam} encoded param wrapped in SolidityParam object */ SolidityType.prototype.formatInput = function (param, arrayType) { if (utils.isArray(param) && arrayType) { // TODO: should fail if this two are not the same @@ -216,10 +80,9 @@ SolidityType.prototype.formatInput = function (param, arrayType) { return param.map(function (p) { return self._inputFormatter(p); }).reduce(function (acc, current) { - acc.appendArrayElement(current); - return acc; - }, new SolidityParam(f.formatInputInt(param.length).value)); - } + return acc.combine(current); + }, f.formatInputInt(param.length)).withOffset(32); + } return this._inputFormatter(param); }; @@ -233,11 +96,11 @@ SolidityType.prototype.formatInput = function (param, arrayType) { */ SolidityType.prototype.formatOutput = function (param, arrayType) { if (arrayType) { - // let's assume, that we solidity will never return long arrays :P + // let's assume, that we solidity will never return long arrays :P var result = []; - var length = new BigNumber(param.value, 16); + var length = new BigNumber(param.dynamicPart().slice(0, 64), 16); for (var i = 0; i < length * 64; i += 64) { - result.push(this._outputFormatter(new SolidityParam(param.suffix.slice(i, i + 64)))); + result.push(this._outputFormatter(new SolidityParam(param.dynamicPart().substr(i + 64, 64)))); } return result; } @@ -245,31 +108,21 @@ SolidityType.prototype.formatOutput = function (param, arrayType) { }; /** - * Should be used to check if a type is variadic - * - * @method isVariadicType - * @param {String} type - * @returns {Bool} true if the type is variadic - */ -SolidityType.prototype.isVariadicType = function (type) { - return isArrayType(type) || this._mode === 'bytes'; -}; - -/** - * Should be used to shift param from params group + * Should be used to slice single param from bytes * - * @method shiftParam + * @method sliceParam + * @param {String} bytes + * @param {Number} index of param to slice * @param {String} type - * @returns {SolidityParam} shifted param + * @returns {SolidityParam} param */ -SolidityType.prototype.shiftParam = function (type, param) { +SolidityType.prototype.sliceParam = function (bytes, index, type) { if (this._mode === 'bytes') { - return param.shiftBytes(); + return SolidityParam.decodeBytes(bytes, index); } else if (isArrayType(type)) { - var length = new BigNumber(param.value.slice(0, 64), 16); - return param.shiftArray(length); + return SolidityParam.decodeArray(bytes, index); } - return param.shiftValue(); + return SolidityParam.decodeParam(bytes, index); }; /** @@ -284,7 +137,7 @@ var SolidityCoder = function (types) { * * @method _requireType * @param {String} type - * @returns {SolidityType} + * @returns {SolidityType} * @throws {Error} throws if no matching type is found */ SolidityCoder.prototype._requireType = function (type) { @@ -300,20 +153,6 @@ SolidityCoder.prototype._requireType = function (type) { }; /** - * Should be used to transform plain bytes to SolidityParam object - * - * @method _bytesToParam - * @param {Array} types of params - * @param {String} bytes to be transformed to SolidityParam - * @return {SolidityParam} SolidityParam for this group of params - */ -SolidityCoder.prototype._bytesToParam = function (types, bytes) { - var value = bytes.slice(0, types.length * 64); - var suffix = bytes.slice(types.length * 64); - return new SolidityParam(value, suffix); -}; - -/** * Should be used to transform plain param of given type to SolidityParam * * @method _formatInput @@ -347,24 +186,11 @@ SolidityCoder.prototype.encodeParam = function (type, param) { */ SolidityCoder.prototype.encodeParams = function (types, params) { var self = this; - return types.map(function (type, index) { + var solidityParams = types.map(function (type, index) { return self._formatInput(type, params[index]); - }).reduce(function (acc, solidityParam) { - acc.append(solidityParam); - return acc; - }, new SolidityParam()).encode(); -}; + }); -/** - * Should be used to transform SolidityParam to plain param - * - * @method _formatOutput - * @param {String} type - * @param {SolidityParam} param - * @return {Object} plain param - */ -SolidityCoder.prototype._formatOutput = function (type, param) { - return this._requireType(type).formatOutput(param, isArrayType(type)); + return SolidityParam.encodeList(solidityParams); }; /** @@ -376,7 +202,7 @@ SolidityCoder.prototype._formatOutput = function (type, param) { * @return {Object} plain param */ SolidityCoder.prototype.decodeParam = function (type, bytes) { - return this._formatOutput(type, this._bytesToParam([type], bytes)); + return this.decodeParams([type], bytes)[0]; }; /** @@ -389,10 +215,9 @@ SolidityCoder.prototype.decodeParam = function (type, bytes) { */ SolidityCoder.prototype.decodeParams = function (types, bytes) { var self = this; - var param = this._bytesToParam(types, bytes); - return types.map(function (type) { + return types.map(function (type, index) { var solidityType = self._requireType(type); - var p = solidityType.shiftParam(type, param); + var p = solidityType.sliceParam(bytes, index, type); return solidityType.formatOutput(p, isArrayType(type)); }); }; @@ -459,7 +284,7 @@ var coder = new SolidityCoder([ module.exports = coder; -},{"../utils/utils":8,"./formatters":3,"./param":4,"bignumber.js":"bignumber.js"}],3:[function(require,module,exports){ +},{"../utils/utils":7,"./formatters":2,"./param":3,"bignumber.js":"bignumber.js"}],2:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -476,7 +301,7 @@ module.exports = coder; 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 * @author Marek Kotewicz <marek@ethdev.com> * @date 2015 @@ -525,7 +350,7 @@ var formatInputBytes = function (value) { */ var formatInputDynamicBytes = function (value) { var result = utils.fromAscii(value, c.ETH_PADDING).substr(2); - return new SolidityParam(formatInputInt(value.length).value, result); + return new SolidityParam(formatInputInt(value.length).value + result, 32); }; /** @@ -571,7 +396,7 @@ var signedIsNegative = function (value) { * @returns {BigNumber} right-aligned output bytes formatted to big number */ var formatOutputInt = function (param) { - var value = param.value || "0"; + var value = param.staticPart() || "0"; // check if it's negative number // it it is, return two's complement @@ -589,7 +414,7 @@ var formatOutputInt = function (param) { * @returns {BigNumeber} right-aligned output bytes formatted to uint */ var formatOutputUInt = function (param) { - var value = param.value || "0"; + var value = param.staticPart() || "0"; return new BigNumber(value, 16); }; @@ -601,7 +426,7 @@ var formatOutputUInt = function (param) { * @returns {BigNumber} input bytes formatted to real */ var formatOutputReal = function (param) { - return formatOutputInt(param).dividedBy(new BigNumber(2).pow(128)); + return formatOutputInt(param).dividedBy(new BigNumber(2).pow(128)); }; /** @@ -612,7 +437,7 @@ var formatOutputReal = function (param) { * @returns {BigNumber} input bytes formatted to ureal */ var formatOutputUReal = function (param) { - return formatOutputUInt(param).dividedBy(new BigNumber(2).pow(128)); + return formatOutputUInt(param).dividedBy(new BigNumber(2).pow(128)); }; /** @@ -623,7 +448,7 @@ var formatOutputUReal = function (param) { * @returns {Boolean} right-aligned input bytes formatted to bool */ var formatOutputBool = function (param) { - return param.value === '0000000000000000000000000000000000000000000000000000000000000001' ? true : false; + return param.staticPart() === '0000000000000000000000000000000000000000000000000000000000000001' ? true : false; }; /** @@ -635,7 +460,7 @@ var formatOutputBool = function (param) { */ var formatOutputBytes = function (param) { // length might also be important! - return utils.toAscii(param.value); + return utils.toAscii(param.staticPart()); }; /** @@ -647,7 +472,7 @@ var formatOutputBytes = function (param) { */ var formatOutputDynamicBytes = function (param) { // length might also be important! - return utils.toAscii(param.suffix); + return utils.toAscii(param.dynamicPart().slice(64)); }; /** @@ -658,7 +483,7 @@ var formatOutputDynamicBytes = function (param) { * @returns {String} address */ var formatOutputAddress = function (param) { - var value = param.value; + var value = param.staticPart(); return "0x" + value.slice(value.length - 40, value.length); }; @@ -679,7 +504,7 @@ module.exports = { }; -},{"../utils/config":7,"../utils/utils":8,"./param":4,"bignumber.js":"bignumber.js"}],4:[function(require,module,exports){ +},{"../utils/config":5,"../utils/utils":7,"./param":3,"bignumber.js":"bignumber.js"}],3:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -696,136 +521,202 @@ module.exports = { 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 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, suffix) { +var SolidityParam = function (value, offset) { this.value = value || ''; - this.suffix = suffix || ''; + this.offset = offset; // offset in bytes }; /** - * This method should be used to encode two params one after another + * This method should be used to get length of params's dynamic part * - * @method append - * @param {SolidityParam} param that it appended after this + * @method dynamicPartLength + * @returns {Number} length of dynamic part (in bytes) */ -SolidityParam.prototype.append = function (param) { - this.value += param.value; - this.suffix += param.suffix; +SolidityParam.prototype.dynamicPartLength = function () { + return this.dynamicPart().length / 2; }; /** - * This method should be used to encode next param in an array + * This method should be used to create copy of solidity param with different offset * - * @method appendArrayElement - * @param {SolidityParam} param that is appended to an array + * @method withOffset + * @param {Number} offset length in bytes + * @returns {SolidityParam} new solidity param with applied offset */ -SolidityParam.prototype.appendArrayElement = function (param) { - this.suffix += param.value; - //this.suffix += param.suffix; // we do not support nested dynamic types +SolidityParam.prototype.withOffset = function (offset) { + return new SolidityParam(this.value, offset); }; /** - * This method should be used to create bytearrays from param + * This method should be used to combine solidity params together + * eg. when appending an array * - * @method encode - * @return {String} encoded param(s) + * @method combine + * @param {SolidityParam} param with which we should combine + * @param {SolidityParam} result of combination */ -SolidityParam.prototype.encode = function () { - return this.value + this.suffix; +SolidityParam.prototype.combine = function (param) { + return new SolidityParam(this.value + param.value); }; /** - * This method should be used to shift first param from group of params + * This method should be called to check if param has dynamic size. + * If it has, it returns true, otherwise false * - * @method shiftValue - * @return {SolidityParam} first value param + * @method isDynamic + * @returns {Boolean} */ -SolidityParam.prototype.shiftValue = function () { - var value = this.value.slice(0, 64); - this.value = this.value.slice(64); - return new SolidityParam(value); +SolidityParam.prototype.isDynamic = function () { + return this.value.length > 64; }; /** - * This method should be used to first bytes param from group of params + * This method should be called to transform offset to bytes * - * @method shiftBytes - * @return {SolidityParam} first bytes param + * @method offsetAsBytes + * @returns {String} bytes representation of offset */ -SolidityParam.prototype.shiftBytes = function () { - return this.shiftArray(1); +SolidityParam.prototype.offsetAsBytes = function () { + return !this.isDynamic() ? '' : utils.padLeft(utils.toTwosComplement(this.offset).toString(16), 64); }; /** - * This method should be used to shift an array from group of params - * - * @method shiftArray - * @param {Number} size of an array to shift - * @return {SolidityParam} first array param + * 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.shiftArray = function (length) { - var value = this.value.slice(0, 64); - this.value = this.value.slice(64); - var suffix = this.suffix.slice(0, 64 * length); - this.suffix = this.suffix.slice(64 * length); - return new SolidityParam(value, suffix); +SolidityParam.prototype.staticPart = function () { + if (!this.isDynamic()) { + return this.value; + } + return this.offsetAsBytes(); }; -module.exports = SolidityParam; +/** + * 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(); +}; -},{}],5:[function(require,module,exports){ -/* - This file is part of ethereum.js. +/** + * This method should be called to encode array of params + * + * @method encodeList + * @param {Array[SolidityParam]} params + * @returns {String} + */ +SolidityParam.encodeList = function (params) { - 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. + // 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); + }); - 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. + // encode everything! + return offsetParams.reduce(function (result, param) { + return result + param.dynamicPart(); + }, offsetParams.reduce(function (result, param) { + return result + param.staticPart(); + }, '')); +}; - 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 utils.js - * @author Marek Kotewicz <marek@ethdev.com> - * @date 2015 + * This method should be used to decode plain (static) solidity param at given index + * + * @method decodeParam + * @param {String} bytes + * @param {Number} index + * @returns {SolidityParam} */ +SolidityParam.decodeParam = function (bytes, index) { + index = index || 0; + return new SolidityParam(bytes.substr(index * 64, 64)); +}; /** - * Returns the contstructor with matching number of arguments + * This method should be called to get offset value from bytes at given index * - * @method getConstructor - * @param {Array} abi - * @param {Number} numberOfArgs - * @returns {Object} constructor function abi + * @method getOffset + * @param {String} bytes + * @param {Number} index + * @returns {Number} offset as number */ -var getConstructor = function (abi, numberOfArgs) { - return abi.filter(function (f) { - return f.type === 'constructor' && f.inputs.length === numberOfArgs; - })[0]; +var getOffset = function (bytes, index) { + // we can do this cause offset is rather small + return parseInt('0x' + bytes.substr(index * 64, 64)); }; -module.exports = { - getConstructor: getConstructor +/** + * This method should be called to decode solidity bytes param at given index + * + * @method decodeBytes + * @param {String} bytes + * @param {Number} index + * @returns {SolidityParam} + */ +SolidityParam.decodeBytes = function (bytes, index) { + index = index || 0; + //TODO add support for strings longer than 32 bytes + //var length = parseInt('0x' + bytes.substr(offset * 64, 64)); + + var offset = getOffset(bytes, index); + + // 2 * , cause we also parse length + return new SolidityParam(bytes.substr(offset * 2, 2 * 64)); }; +/** + * This method should be used to decode solidity array at given index + * + * @method decodeArray + * @param {String} bytes + * @param {Number} index + * @returns {SolidityParam} + */ +SolidityParam.decodeArray = function (bytes, index) { + index = index || 0; + var offset = getOffset(bytes, index); + var length = parseInt('0x' + bytes.substr(offset * 2, 64)); + return new SolidityParam(bytes.substr(offset * 2, (length + 1) * 64)); +}; + +module.exports = SolidityParam; + -},{}],6:[function(require,module,exports){ +},{"../utils/utils":7}],4:[function(require,module,exports){ 'use strict'; // go env doesn't have and need XMLHttpRequest @@ -836,7 +727,7 @@ if (typeof XMLHttpRequest === 'undefined') { } -},{}],7:[function(require,module,exports){ +},{}],5:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -861,13 +752,13 @@ if (typeof XMLHttpRequest === 'undefined') { /** * Utils - * + * * @module utils */ /** * Utility functions - * + * * @class [utils] config * @constructor */ @@ -875,26 +766,26 @@ if (typeof XMLHttpRequest === 'undefined') { /// required to define ETH_BIGNUMBER_ROUNDING_MODE var BigNumber = require('bignumber.js'); -var ETH_UNITS = [ - 'wei', - 'Kwei', - 'Mwei', - 'Gwei', - 'szabo', - 'finney', - 'ether', - 'grand', - 'Mether', - 'Gether', - 'Tether', - 'Pether', - 'Eether', - 'Zether', - 'Yether', - 'Nether', - 'Dether', - 'Vether', - 'Uether' +var ETH_UNITS = [ + 'wei', + 'Kwei', + 'Mwei', + 'Gwei', + 'szabo', + 'finney', + 'ether', + 'grand', + 'Mether', + 'Gether', + 'Tether', + 'Pether', + 'Eether', + 'Zether', + 'Yether', + 'Nether', + 'Dether', + 'Vether', + 'Uether' ]; module.exports = { @@ -908,7 +799,7 @@ module.exports = { }; -},{"bignumber.js":"bignumber.js"}],8:[function(require,module,exports){ +},{"bignumber.js":"bignumber.js"}],6:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -925,7 +816,39 @@ module.exports = { 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 sha3.js + * @author Marek Kotewicz <marek@ethdev.com> + * @date 2015 + */ + +var sha3 = require('crypto-js/sha3'); + +module.exports = function (str) { + return sha3(str, { + outputLength: 256 + }).toString(); +}; + + +},{"crypto-js/sha3":30}],7:[function(require,module,exports){ +/* + 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 utils.js * @author Marek Kotewicz <marek@ethdev.com> * @date 2015 @@ -933,13 +856,13 @@ module.exports = { /** * Utils - * + * * @module utils */ /** * Utility functions - * + * * @class [utils] utils * @constructor */ @@ -978,7 +901,7 @@ var padLeft = function (string, chars, sign) { return new Array(chars - string.length + 1).join(sign ? sign : "0") + string; }; -/** +/** * Should be called to get sting from it's hex representation * * @method toAscii @@ -1003,9 +926,9 @@ var toAscii = function(hex) { return str; }; - + /** - * Shold be called to get hex representation (prefixed by 0x) of ascii string + * Shold be called to get hex representation (prefixed by 0x) of ascii string * * @method toHexNative * @param {String} string @@ -1022,7 +945,7 @@ var toHexNative = function(str) { }; /** - * Shold be called to get hex representation (prefixed by 0x) of ascii string + * Shold be called to get hex representation (prefixed by 0x) of ascii string * * @method fromAscii * @param {String} string @@ -1055,13 +978,13 @@ var transformToFullName = function (json) { /** * Should be called to get display name of contract function - * + * * @method extractDisplayName * @param {String} name of function/event * @returns {String} display name for function/event eg. multiply(uint256) -> multiply */ var extractDisplayName = function (name) { - var length = name.indexOf('('); + var length = name.indexOf('('); return length !== -1 ? name.substr(0, length) : name; }; @@ -1169,7 +1092,7 @@ var getValueOfUnit = function (unit) { var fromWei = function(number, unit) { var returnValue = toBigNumber(number).dividedBy(getValueOfUnit(unit)); - return isBigNumber(number) ? returnValue : returnValue.toString(10); + return isBigNumber(number) ? returnValue : returnValue.toString(10); }; /** @@ -1195,7 +1118,7 @@ var fromWei = function(number, unit) { var toWei = function(number, unit) { var returnValue = toBigNumber(number).times(getValueOfUnit(unit)); - return isBigNumber(number) ? returnValue : returnValue.toString(10); + return isBigNumber(number) ? returnValue : returnValue.toString(10); }; /** @@ -1214,7 +1137,7 @@ var toBigNumber = function(number) { if (isString(number) && (number.indexOf('0x') === 0 || number.indexOf('-0x') === 0)) { return new BigNumber(number.replace('0x',''), 16); } - + return new BigNumber(number.toString(10), 10); }; @@ -1266,7 +1189,7 @@ var toAddress = function (address) { if (isStrictAddress(address)) { return address; } - + if (/^[0-9a-f]{40}$/.test(address)) { return '0x' + address; } @@ -1274,12 +1197,13 @@ var toAddress = function (address) { return '0x' + padLeft(toHex(address).substr(2), 40); }; + /** * Returns true if object is BigNumber, otherwise false * * @method isBigNumber * @param {Object} - * @return {Boolean} + * @return {Boolean} */ var isBigNumber = function (object) { return object instanceof BigNumber || @@ -1288,7 +1212,7 @@ var isBigNumber = function (object) { /** * Returns true if object is string, otherwise false - * + * * @method isString * @param {Object} * @return {Boolean} @@ -1339,12 +1263,12 @@ var isBoolean = function (object) { * @return {Boolean} */ var isArray = function (object) { - return object instanceof Array; + return object instanceof Array; }; /** * Returns true if given string is valid json object - * + * * @method isJson * @param {String} * @return {Boolean} @@ -1384,12 +1308,12 @@ module.exports = { }; -},{"bignumber.js":"bignumber.js"}],9:[function(require,module,exports){ +},{"bignumber.js":"bignumber.js"}],8:[function(require,module,exports){ module.exports={ - "version": "0.3.5" + "version": "0.4.2" } -},{}],10:[function(require,module,exports){ +},{}],9:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -1427,16 +1351,9 @@ var utils = require('./utils/utils'); var formatters = require('./web3/formatters'); var RequestManager = require('./web3/requestmanager'); var c = require('./utils/config'); -var Method = require('./web3/method'); var Property = require('./web3/property'); - -var web3Methods = [ - new Method({ - name: 'sha3', - call: 'web3_sha3', - params: 1 - }) -]; +var Batch = require('./web3/batch'); +var sha3 = require('./utils/sha3'); var web3Properties = [ new Property({ @@ -1521,6 +1438,10 @@ web3.toBigNumber = utils.toBigNumber; web3.toWei = utils.toWei; web3.fromWei = utils.fromWei; web3.isAddress = utils.isAddress; +web3.sha3 = sha3; +web3.createBatch = function () { + return new Batch(); +}; // ADD defaultblock Object.defineProperty(web3.eth, 'defaultBlock', { @@ -1544,7 +1465,6 @@ Object.defineProperty(web3.eth, 'defaultAccount', { }); /// setups all api methods -setupMethods(web3, web3Methods); setupProperties(web3, web3Properties); setupMethods(web3.net, net.methods); setupProperties(web3.net, net.properties); @@ -1556,7 +1476,7 @@ setupMethods(web3.shh, shh.methods); module.exports = web3; -},{"./utils/config":7,"./utils/utils":8,"./version.json":9,"./web3/db":12,"./web3/eth":14,"./web3/filter":16,"./web3/formatters":17,"./web3/method":21,"./web3/net":22,"./web3/property":23,"./web3/requestmanager":25,"./web3/shh":26,"./web3/watches":27}],11:[function(require,module,exports){ +},{"./utils/config":5,"./utils/sha3":6,"./utils/utils":7,"./version.json":8,"./web3/batch":10,"./web3/db":12,"./web3/eth":14,"./web3/filter":16,"./web3/formatters":17,"./web3/net":22,"./web3/property":23,"./web3/requestmanager":25,"./web3/shh":26,"./web3/watches":27}],10:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -1573,20 +1493,109 @@ module.exports = web3; 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 batch.js + * @author Marek Kotewicz <marek@ethdev.com> + * @date 2015 + */ + +var RequestManager = require('./requestmanager'); + +var Batch = function () { + this.requests = []; +}; + +/** + * Should be called to add create new request to batch request + * + * @method add + * @param {Object} jsonrpc requet object + */ +Batch.prototype.add = function (request) { + this.requests.push(request); +}; + +/** + * Should be called to execute batch request + * + * @method execute + */ +Batch.prototype.execute = function () { + var requests = this.requests; + RequestManager.getInstance().sendBatch(requests, function (err, results) { + results = results || []; + requests.map(function (request, index) { + return results[index] || {}; + }).map(function (result, index) { + return requests[index].format ? requests[index].format(result.result) : result.result; + }).forEach(function (result, index) { + if (requests[index].callback) { + requests[index].callback(err, result); + } + }); + }); +}; + +module.exports = Batch; + + +},{"./requestmanager":25}],11:[function(require,module,exports){ +/* + 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 contract.js * @author Marek Kotewicz <marek@ethdev.com> * @date 2014 */ -var web3 = require('../web3'); -var solAbi = require('../solidity/abi'); +var web3 = require('../web3'); var utils = require('../utils/utils'); +var coder = require('../solidity/coder'); var SolidityEvent = require('./event'); var SolidityFunction = require('./function'); -var addFunctionsToContract = function (contract, desc) { - desc.filter(function (json) { +/** + * Should be called to encode constructor params + * + * @method encodeConstructorParams + * @param {Array} abi + * @param {Array} constructor params + */ +var encodeConstructorParams = function (abi, params) { + return abi.filter(function (json) { + return json.type === 'constructor' && json.inputs.length === params.length; + }).map(function (json) { + return json.inputs.map(function (input) { + return input.type; + }); + }).map(function (types) { + return coder.encodeParams(types, params); + })[0] || ''; +}; + +/** + * Should be called to add functions to contract object + * + * @method addFunctionsToContract + * @param {Contract} contract + * @param {Array} abi + */ +var addFunctionsToContract = function (contract, abi) { + abi.filter(function (json) { return json.type === 'function'; }).map(function (json) { return new SolidityFunction(json, contract.address); @@ -1595,8 +1604,15 @@ var addFunctionsToContract = function (contract, desc) { }); }; -var addEventsToContract = function (contract, desc) { - desc.filter(function (json) { +/** + * Should be called to add events to contract object + * + * @method addEventsToContract + * @param {Contract} contract + * @param {Array} abi + */ +var addEventsToContract = function (contract, abi) { + abi.filter(function (json) { return json.type === 'event'; }).map(function (json) { return new SolidityEvent(json, contract.address); @@ -1606,65 +1622,106 @@ var addEventsToContract = function (contract, desc) { }; /** - * This method should be called when we want to call / transact some solidity method from javascript - * it returns an object which has same methods available as solidity contract description - * usage example: - * - * var abi = [{ - * name: 'myMethod', - * inputs: [{ name: 'a', type: 'string' }], - * outputs: [{name: 'd', type: 'string' }] - * }]; // contract abi - * - * var MyContract = web3.eth.contract(abi); // creation of contract prototype - * - * var contractInstance = new MyContract('0x0123123121'); - * - * contractInstance.myMethod('this is test string param for call'); // myMethod call (implicit, default) - * contractInstance.call().myMethod('this is test string param for call'); // myMethod call (explicit) - * contractInstance.sendTransaction().myMethod('this is test string param for transact'); // myMethod sendTransaction + * Should be called to create new ContractFactory * - * @param abi - abi json description of the contract, which is being created - * @returns contract object + * @method contract + * @param {Array} abi + * @returns {ContractFactory} new contract factory */ var contract = function (abi) { + return new ContractFactory(abi); +}; - // return prototype - return Contract.bind(null, abi); +/** + * Should be called to create new ContractFactory instance + * + * @method ContractFactory + * @param {Array} abi + */ +var ContractFactory = function (abi) { + this.abi = abi; }; -var Contract = function (abi, options) { +/** + * Should be called to create new contract on a blockchain + * + * @method new + * @param {Any} contract constructor param1 (optional) + * @param {Any} contract constructor param2 (optional) + * @param {Object} contract transaction object (required) + * @param {Function} callback + * @returns {Contract} returns contract if no callback was passed, + * otherwise calls callback function (err, contract) + */ +ContractFactory.prototype.new = function () { + // parse arguments + var options = {}; // required! + var callback; - this.address = ''; - if (utils.isAddress(options)) { - this.address = options; - } else { // is an object! - // TODO, parse the rest of the args - options = options || {}; - var args = Array.prototype.slice.call(arguments, 2); - var bytes = solAbi.formatConstructorParams(abi, args); - options.data += bytes; - this.address = web3.eth.sendTransaction(options); + var args = Array.prototype.slice.call(arguments); + if (utils.isFunction(args[args.length - 1])) { + callback = args.pop(); } - addFunctionsToContract(this, abi); - addEventsToContract(this, abi); + var last = args[args.length - 1]; + if (utils.isObject(last) && !utils.isArray(last)) { + options = args.pop(); + } + + // throw an error if there are no options + + var bytes = encodeConstructorParams(this.abi, args); + options.data += bytes; + + if (!callback) { + var address = web3.eth.sendTransaction(options); + return this.at(address); + } + + var self = this; + web3.eth.sendTransaction(options, function (err, address) { + if (err) { + callback(err); + } + self.at(address, callback); + }); }; -Contract.prototype.call = function () { - console.error('contract.call is deprecated'); - return this; +/** + * Should be called to get access to existing contract on a blockchain + * + * @method at + * @param {Address} contract address (required) + * @param {Function} callback {optional) + * @returns {Contract} returns contract if no callback was passed, + * otherwise calls callback function (err, contract) + */ +ContractFactory.prototype.at = function (address, callback) { + // TODO: address is required + + if (callback) { + callback(null, new Contract(this.abi, address)); + } + return new Contract(this.abi, address); }; -Contract.prototype.sendTransaction = function () { - console.error('contract.sendTransact is deprecated'); - return this; +/** + * Should be called to create new contract instance + * + * @method Contract + * @param {Array} abi + * @param {Address} contract address + */ +var Contract = function (abi, address) { + this.address = address; + addFunctionsToContract(this, abi); + addEventsToContract(this, abi); }; module.exports = contract; -},{"../solidity/abi":1,"../utils/utils":8,"../web3":10,"./event":15,"./function":18}],12:[function(require,module,exports){ +},{"../solidity/coder":1,"../utils/utils":7,"../web3":9,"./event":15,"./function":18}],12:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -1739,7 +1796,7 @@ module.exports = { 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 errors.js * @author Marek Kotewicz <marek@ethdev.com> * @date 2015 @@ -1925,12 +1982,6 @@ var getTransactionCount = new Method({ outputFormatter: utils.toDecimal }); -var sign = new Method({ - name: 'sign', - call: 'eth_sign', - params: 1 -}); - var sendTransaction = new Method({ name: 'sendTransaction', call: 'eth_sendTransaction', @@ -1945,6 +1996,14 @@ var call = new Method({ inputFormatter: [formatters.inputTransactionFormatter, formatters.inputDefaultBlockNumberFormatter] }); +var estimateGas = new Method({ + name: 'estimateGas', + call: 'eth_estimateGas', + params: 1, + inputFormatter: [formatters.inputTransactionFormatter], + outputFormatter: utils.toDecimal +}); + var compileSolidity = new Method({ name: 'compile.solidity', call: 'eth_compileSolidity', @@ -1963,6 +2022,18 @@ var compileSerpent = new Method({ params: 1 }); +var submitWork = new Method({ + name: 'submitWork', + call: 'eth_submitWork', + params: 3 +}); + +var getWork = new Method({ + name: 'getWork', + call: 'eth_getWork', + params: 0 +}); + var methods = [ getBalance, getStorageAt, @@ -1976,11 +2047,13 @@ var methods = [ getTransactionFromBlock, getTransactionCount, call, - sign, + estimateGas, sendTransaction, compileSolidity, compileLLL, compileSerpent, + submitWork, + getWork ]; /// @returns an array of objects describing web3.eth api properties @@ -2023,7 +2096,7 @@ module.exports = { }; -},{"../utils/utils":8,"./formatters":17,"./method":21,"./property":23}],15:[function(require,module,exports){ +},{"../utils/utils":7,"./formatters":17,"./method":21,"./property":23}],15:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -2040,7 +2113,7 @@ module.exports = { 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 event.js * @author Marek Kotewicz <marek@ethdev.com> * @date 2014 @@ -2050,6 +2123,7 @@ var utils = require('../utils/utils'); var coder = require('../solidity/coder'); var web3 = require('../web3'); var formatters = require('./formatters'); +var sha3 = require('../utils/sha3'); /** * This prototype should be used to create event filters @@ -2103,12 +2177,12 @@ SolidityEvent.prototype.typeName = function () { * @return {String} event signature */ SolidityEvent.prototype.signature = function () { - return web3.sha3(web3.fromAscii(this._name)).slice(2); + return sha3(this._name); }; /** * Should be used to encode indexed params and options to one final object - * + * * @method encode * @param {Object} indexed * @param {Object} options @@ -2139,7 +2213,7 @@ SolidityEvent.prototype.encode = function (indexed, options) { if (value === undefined || value === null) { return null; } - + if (utils.isArray(value)) { return value.map(function (v) { return '0x' + coder.encodeParam(i.type, v); @@ -2161,17 +2235,17 @@ SolidityEvent.prototype.encode = function (indexed, options) { * @return {Object} result object with decoded indexed && not indexed params */ SolidityEvent.prototype.decode = function (data) { - + data.data = data.data || ''; data.topics = data.topics || []; var argTopics = this._anonymous ? data.topics : data.topics.slice(1); var indexedData = argTopics.map(function (topics) { return topics.slice(2); }).join(""); - var indexedParams = coder.decodeParams(this.types(true), indexedData); + var indexedParams = coder.decodeParams(this.types(true), indexedData); var notIndexedData = data.data.slice(2); var notIndexedParams = coder.decodeParams(this.types(false), notIndexedData); - + var result = formatters.outputLogFormatter(data); result.event = this.displayName(); result.address = data.address; @@ -2219,7 +2293,7 @@ SolidityEvent.prototype.attachToContract = function (contract) { module.exports = SolidityEvent; -},{"../solidity/coder":2,"../utils/utils":8,"../web3":10,"./formatters":17}],16:[function(require,module,exports){ +},{"../solidity/coder":1,"../utils/sha3":6,"../utils/utils":7,"../web3":9,"./formatters":17}],16:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -2276,7 +2350,7 @@ var getOptions = function (options) { if (utils.isString(options)) { return options; - } + } options = options || {}; @@ -2292,8 +2366,8 @@ var getOptions = function (options) { to: options.to, address: options.address, fromBlock: formatters.inputBlockNumberFormatter(options.fromBlock), - toBlock: formatters.inputBlockNumberFormatter(options.toBlock) - }; + toBlock: formatters.inputBlockNumberFormatter(options.toBlock) + }; }; var Filter = function (options, methods, formatter) { @@ -2376,7 +2450,7 @@ Filter.prototype.get = function (callback) { module.exports = Filter; -},{"../utils/utils":8,"./formatters":17,"./requestmanager":25}],17:[function(require,module,exports){ +},{"../utils/utils":7,"./formatters":17,"./requestmanager":25}],17:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -2393,7 +2467,7 @@ module.exports = Filter; 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 * @author Marek Kotewicz <marek@ethdev.com> * @author Fabian Vogelsteller <fabian@ethdev.com> @@ -2451,18 +2525,18 @@ var inputTransactionFormatter = function (options){ delete options.code; } - ['gasPrice', 'gas', 'value'].filter(function (key) { + ['gasPrice', 'gas', 'value', 'nonce'].filter(function (key) { return options[key] !== undefined; }).forEach(function(key){ options[key] = utils.fromDecimal(options[key]); }); - return options; + return options; }; /** * Formats the output of a transaction to its proper values - * + * * @method outputTransactionFormatter * @param {Object} transaction * @returns {Object} transaction @@ -2481,7 +2555,7 @@ var outputTransactionFormatter = function (tx){ * Formats the output of a block to its proper values * * @method outputBlockFormatter - * @param {Object} block object + * @param {Object} block object * @returns {Object} block object */ var outputBlockFormatter = function(block) { @@ -2508,7 +2582,7 @@ var outputBlockFormatter = function(block) { /** * Formats the output of a log - * + * * @method outputLogFormatter * @param {Object} log object * @returns {Object} log @@ -2549,7 +2623,7 @@ var inputPostFormatter = function(post) { return utils.fromAscii(topic); }); - return post; + return post; }; /** @@ -2596,7 +2670,7 @@ module.exports = { }; -},{"../utils/config":7,"../utils/utils":8}],18:[function(require,module,exports){ +},{"../utils/config":5,"../utils/utils":7}],18:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -2613,7 +2687,7 @@ module.exports = { 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 function.js * @author Marek Kotewicz <marek@ethdev.com> * @date 2015 @@ -2622,6 +2696,7 @@ module.exports = { var web3 = require('../web3'); var coder = require('../solidity/coder'); var utils = require('../utils/utils'); +var sha3 = require('../utils/sha3'); /** * This prototype should be used to call/sendTransaction to solidity functions @@ -2638,18 +2713,23 @@ var SolidityFunction = function (json, address) { this._address = address; }; +SolidityFunction.prototype.extractCallback = function (args) { + if (utils.isFunction(args[args.length - 1])) { + return args.pop(); // modify the args array! + } +}; + /** * Should be used to create payload from arguments * * @method toPayload - * @param {...} solidity function params + * @param {Array} solidity function params * @param {Object} optional payload options */ -SolidityFunction.prototype.toPayload = function () { - var args = Array.prototype.slice.call(arguments); +SolidityFunction.prototype.toPayload = function (args) { var options = {}; if (args.length > this._inputTypes.length && utils.isObject(args[args.length -1])) { - options = args.pop(); + options = args[args.length - 1]; } options.to = this._address; options.data = '0x' + this.signature() + coder.encodeParams(this._inputTypes, args); @@ -2663,22 +2743,44 @@ SolidityFunction.prototype.toPayload = function () { * @return {String} function signature */ SolidityFunction.prototype.signature = function () { - return web3.sha3(web3.fromAscii(this._name)).slice(2, 10); + return sha3(this._name).slice(0, 8); +}; + + +SolidityFunction.prototype.unpackOutput = function (output) { + if (output === null) { + return; + } + + output = output.length >= 2 ? output.slice(2) : output; + var result = coder.decodeParams(this._outputTypes, output); + return result.length === 1 ? result[0] : result; }; /** - * Should be used to call function - * + * Calls a contract function. + * * @method call - * @param {Object} options + * @param {...Object} Contract function arguments + * @param {function} If the last argument is a function, the contract function + * call will be asynchronous, and the callback will be passed the + * error and result. * @return {String} output bytes */ SolidityFunction.prototype.call = function () { - var payload = this.toPayload.apply(this, Array.prototype.slice.call(arguments)); - var output = web3.eth.call(payload); - output = output.length >= 2 ? output.slice(2) : output; - var result = coder.decodeParams(this._outputTypes, output); - return result.length === 1 ? result[0] : result; + var args = Array.prototype.slice.call(arguments); + var callback = this.extractCallback(args); + var payload = this.toPayload(args); + + if (!callback) { + var output = web3.eth.call(payload); + return this.unpackOutput(output); + } + + var self = this; + web3.eth.call(payload, function (error, output) { + callback(error, self.unpackOutput(output)); + }); }; /** @@ -2688,8 +2790,16 @@ SolidityFunction.prototype.call = function () { * @param {Object} options */ SolidityFunction.prototype.sendTransaction = function () { - var payload = this.toPayload.apply(this, Array.prototype.slice.call(arguments)); - web3.eth.sendTransaction(payload); + var args = Array.prototype.slice.call(arguments); + var callback = this.extractCallback(args); + var payload = this.toPayload(args); + + if (!callback) { + web3.eth.sendTransaction(payload); + return; + } + + web3.eth.sendTransaction(payload, callback); }; /** @@ -2704,7 +2814,7 @@ SolidityFunction.prototype.displayName = function () { /** * Should be used to get function type name - * + * * @method typeName * @return {String} type name of the function */ @@ -2713,13 +2823,32 @@ SolidityFunction.prototype.typeName = function () { }; /** + * Should be called to get rpc requests from solidity function + * + * @method request + * @returns {Object} + */ +SolidityFunction.prototype.request = function () { + var args = Array.prototype.slice.call(arguments); + var callback = this.extractCallback(args); + var payload = this.toPayload(args); + var format = this.unpackOutput.bind(this); + + return { + callback: callback, + payload: payload, + format: format + }; +}; + +/** * Should be called to execute function * * @method execute */ SolidityFunction.prototype.execute = function () { var transaction = !this._constant; - + // send transaction if (transaction) { return this.sendTransaction.apply(this, Array.prototype.slice.call(arguments)); @@ -2737,6 +2866,7 @@ SolidityFunction.prototype.execute = function () { */ SolidityFunction.prototype.attachToContract = function (contract) { var execute = this.execute.bind(this); + execute.request = this.request.bind(this); execute.call = this.call.bind(this); execute.sendTransaction = this.sendTransaction.bind(this); var displayName = this.displayName(); @@ -2749,7 +2879,7 @@ SolidityFunction.prototype.attachToContract = function (contract) { module.exports = SolidityFunction; -},{"../solidity/coder":2,"../utils/utils":8,"../web3":10}],19:[function(require,module,exports){ +},{"../solidity/coder":1,"../utils/sha3":6,"../utils/utils":7,"../web3":9}],19:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -2787,7 +2917,7 @@ HttpProvider.prototype.send = function (payload) { var request = new XMLHttpRequest(); request.open('POST', this.host, false); - + try { request.send(JSON.stringify(payload)); } catch(error) { @@ -2800,15 +2930,32 @@ HttpProvider.prototype.send = function (payload) { //if (request.status !== 200) { //return; //} - return JSON.parse(request.responseText); + + var result = request.responseText; + + try { + result = JSON.parse(result); + } catch(e) { + throw errors.InvalidResponse(result); + } + + return result; }; HttpProvider.prototype.sendAsync = function (payload, callback) { var request = new XMLHttpRequest(); request.onreadystatechange = function() { if (request.readyState === 4) { - // TODO: handle the error properly here!!! - callback(null, JSON.parse(request.responseText)); + var result = request.responseText; + var error = null; + + try { + result = JSON.parse(result); + } catch(e) { + error = errors.InvalidResponse(result); + } + + callback(error, result); } }; @@ -2824,7 +2971,7 @@ HttpProvider.prototype.sendAsync = function (payload, callback) { module.exports = HttpProvider; -},{"./errors":13,"xmlhttprequest":6}],20:[function(require,module,exports){ +},{"./errors":13,"xmlhttprequest":4}],20:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -2974,12 +3121,11 @@ Method.prototype.extractCallback = function (args) { if (utils.isFunction(args[args.length - 1])) { return args.pop(); // modify the args array! } - return null; }; /** * Should be called to check if the number of arguments is correct - * + * * @method validateArgs * @param {Array} arguments * @throws {Error} if it is not @@ -2992,7 +3138,7 @@ Method.prototype.validateArgs = function (args) { /** * Should be called to format input args of method - * + * * @method formatInput * @param {Array} * @return {Array} @@ -3020,20 +3166,21 @@ Method.prototype.formatOutput = function (result) { /** * Should attach function to method - * + * * @method attachToObject * @param {Object} * @param {Function} */ Method.prototype.attachToObject = function (obj) { var func = this.send.bind(this); + func.request = this.request.bind(this); func.call = this.call; // that's ugly. filter.js uses it var name = this.name.split('.'); if (name.length > 1) { obj[name[0]] = obj[name[0]] || {}; obj[name[0]][name[1]] = func; } else { - obj[name[0]] = func; + obj[name[0]] = func; } }; @@ -3058,6 +3205,19 @@ Method.prototype.toPayload = function (args) { }; /** + * Should be called to create pure JSONRPC request which can be used in batch request + * + * @method request + * @param {...} params + * @return {Object} jsonrpc request + */ +Method.prototype.request = function () { + var payload = this.toPayload(Array.prototype.slice.call(arguments)); + payload.format = this.formatOutput.bind(this); + return payload; +}; + +/** * Should send request to the API * * @method send @@ -3069,7 +3229,7 @@ Method.prototype.send = function () { if (payload.callback) { var self = this; return RequestManager.getInstance().sendAsync(payload, function (err, result) { - payload.callback(null, self.formatOutput(result)); + payload.callback(err, self.formatOutput(result)); }); } return this.formatOutput(RequestManager.getInstance().send(payload)); @@ -3078,7 +3238,7 @@ Method.prototype.send = function () { module.exports = Method; -},{"../utils/utils":8,"./errors":13,"./requestmanager":25}],22:[function(require,module,exports){ +},{"../utils/utils":7,"./errors":13,"./requestmanager":25}],22:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -3128,7 +3288,7 @@ module.exports = { }; -},{"../utils/utils":8,"./property":23}],23:[function(require,module,exports){ +},{"../utils/utils":7,"./property":23}],23:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -3164,7 +3324,7 @@ var Property = function (options) { /** * Should be called to format input args of method - * + * * @method formatInput * @param {Array} * @return {Array} @@ -3186,7 +3346,7 @@ Property.prototype.formatOutput = function (result) { /** * Should attach function to method - * + * * @method attachToObject * @param {Object} * @param {Function} @@ -3194,16 +3354,23 @@ Property.prototype.formatOutput = function (result) { Property.prototype.attachToObject = function (obj) { var proto = { get: this.get.bind(this), - set: this.set.bind(this) }; - var name = this.name.split('.'); - if (name.length > 1) { - obj[name[0]] = obj[name[0]] || {}; - Object.defineProperty(obj[name[0]], name[1], proto); - } else { - Object.defineProperty(obj, name[0], proto); + var names = this.name.split('.'); + var name = names[0]; + if (names.length > 1) { + obj[names[0]] = obj[names[0]] || {}; + obj = obj[names[0]]; + name = names[1]; } + + Object.defineProperty(obj, name, proto); + + var toAsyncName = function (prefix, name) { + return prefix + name.charAt(0).toUpperCase() + name.slice(1); + }; + + obj[toAsyncName('get', name)] = this.getAsync.bind(this); }; /** @@ -3219,15 +3386,20 @@ Property.prototype.get = function () { }; /** - * Should be used to set value of the property + * Should be used to asynchrounously get value of property * - * @method set - * @param {Object} new value of the property + * @method getAsync + * @param {Function} */ -Property.prototype.set = function (value) { - return RequestManager.getInstance().send({ - method: this.setter, - params: [this.formatInput(value)] +Property.prototype.getAsync = function (callback) { + var self = this; + RequestManager.getInstance().sendAsync({ + method: this.getter + }, function (err, result) { + if (err) { + return callback(err); + } + callback(err, self.formatOutput(result)); }); }; @@ -3286,7 +3458,7 @@ module.exports = QtSyncProvider; 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 requestmanager.js * @author Jeffrey Wilcke <jeff@ethdev.com> * @author Marek Kotewicz <marek@ethdev.com> @@ -3368,7 +3540,7 @@ RequestManager.prototype.sendAsync = function (data, callback) { if (err) { return callback(err); } - + if (!Jsonrpc.getInstance().isValidResponse(result)) { return callback(errors.InvalidResponse(result)); } @@ -3378,6 +3550,33 @@ RequestManager.prototype.sendAsync = function (data, callback) { }; /** + * Should be called to asynchronously send batch request + * + * @method sendBatch + * @param {Array} batch data + * @param {Function} callback + */ +RequestManager.prototype.sendBatch = function (data, callback) { + if (!this.provider) { + return callback(errors.InvalidProvider()); + } + + var payload = Jsonrpc.getInstance().toBatchPayload(data); + + this.provider.sendAsync(payload, function (err, results) { + if (err) { + return callback(err); + } + + if (!utils.isArray(results)) { + return callback(errors.InvalidResponse(results)); + } + + callback(err, results); + }); +}; + +/** * Should be used to set provider of request manager * * @method setProvider @@ -3427,7 +3626,7 @@ RequestManager.prototype.stopPolling = function (pollId) { */ RequestManager.prototype.reset = function () { this.polls.forEach(function (poll) { - poll.uninstall(poll.id); + poll.uninstall(poll.id); }); this.polls = []; @@ -3465,7 +3664,7 @@ RequestManager.prototype.poll = function () { if (error) { return; } - + if (!utils.isArray(results)) { throw errors.InvalidResponse(results); } @@ -3490,7 +3689,7 @@ RequestManager.prototype.poll = function () { module.exports = RequestManager; -},{"../utils/config":7,"../utils/utils":8,"./errors":13,"./jsonrpc":20}],26:[function(require,module,exports){ +},{"../utils/config":5,"../utils/utils":7,"./errors":13,"./jsonrpc":20}],26:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -3517,8 +3716,8 @@ var Method = require('./method'); var formatters = require('./formatters'); var post = new Method({ - name: 'post', - call: 'shh_post', + name: 'post', + call: 'shh_post', params: 1, inputFormatter: [formatters.inputPostFormatter] }); @@ -3588,7 +3787,20 @@ var Method = require('./method'); /// @returns an array of objects describing web3.eth.filter api methods var eth = function () { var newFilterCall = function (args) { - return typeof args[0] === 'string' ? 'eth_newBlockFilter' : 'eth_newFilter'; + var type = args[0]; + + switch(type) { + case 'latest': + args.pop(); + this.params = 0; + return 'eth_newBlockFilter'; + case 'pending': + args.pop(); + this.params = 0; + return 'eth_newPendingTransactionFilter'; + default: + return 'eth_newFilter'; + } }; var newFilter = new Method({ @@ -3665,7 +3877,1382 @@ module.exports = { },{"./method":21}],28:[function(require,module,exports){ -},{}],"bignumber.js":[function(require,module,exports){ +},{}],29:[function(require,module,exports){ +;(function (root, factory) { + if (typeof exports === "object") { + // CommonJS + module.exports = exports = factory(); + } + else if (typeof define === "function" && define.amd) { + // AMD + define([], factory); + } + else { + // Global (browser) + root.CryptoJS = factory(); + } +}(this, function () { + + /** + * CryptoJS core components. + */ + var CryptoJS = CryptoJS || (function (Math, undefined) { + /** + * CryptoJS namespace. + */ + var C = {}; + + /** + * Library namespace. + */ + var C_lib = C.lib = {}; + + /** + * Base object for prototypal inheritance. + */ + var Base = C_lib.Base = (function () { + function F() {} + + return { + /** + * Creates a new object that inherits from this object. + * + * @param {Object} overrides Properties to copy into the new object. + * + * @return {Object} The new object. + * + * @static + * + * @example + * + * var MyType = CryptoJS.lib.Base.extend({ + * field: 'value', + * + * method: function () { + * } + * }); + */ + extend: function (overrides) { + // Spawn + F.prototype = this; + var subtype = new F(); + + // Augment + if (overrides) { + subtype.mixIn(overrides); + } + + // Create default initializer + if (!subtype.hasOwnProperty('init')) { + subtype.init = function () { + subtype.$super.init.apply(this, arguments); + }; + } + + // Initializer's prototype is the subtype object + subtype.init.prototype = subtype; + + // Reference supertype + subtype.$super = this; + + return subtype; + }, + + /** + * Extends this object and runs the init method. + * Arguments to create() will be passed to init(). + * + * @return {Object} The new object. + * + * @static + * + * @example + * + * var instance = MyType.create(); + */ + create: function () { + var instance = this.extend(); + instance.init.apply(instance, arguments); + + return instance; + }, + + /** + * Initializes a newly created object. + * Override this method to add some logic when your objects are created. + * + * @example + * + * var MyType = CryptoJS.lib.Base.extend({ + * init: function () { + * // ... + * } + * }); + */ + init: function () { + }, + + /** + * Copies properties into this object. + * + * @param {Object} properties The properties to mix in. + * + * @example + * + * MyType.mixIn({ + * field: 'value' + * }); + */ + mixIn: function (properties) { + for (var propertyName in properties) { + if (properties.hasOwnProperty(propertyName)) { + this[propertyName] = properties[propertyName]; + } + } + + // IE won't copy toString using the loop above + if (properties.hasOwnProperty('toString')) { + this.toString = properties.toString; + } + }, + + /** + * Creates a copy of this object. + * + * @return {Object} The clone. + * + * @example + * + * var clone = instance.clone(); + */ + clone: function () { + return this.init.prototype.extend(this); + } + }; + }()); + + /** + * An array of 32-bit words. + * + * @property {Array} words The array of 32-bit words. + * @property {number} sigBytes The number of significant bytes in this word array. + */ + var WordArray = C_lib.WordArray = Base.extend({ + /** + * Initializes a newly created word array. + * + * @param {Array} words (Optional) An array of 32-bit words. + * @param {number} sigBytes (Optional) The number of significant bytes in the words. + * + * @example + * + * var wordArray = CryptoJS.lib.WordArray.create(); + * var wordArray = CryptoJS.lib.WordArray.create([0x00010203, 0x04050607]); + * var wordArray = CryptoJS.lib.WordArray.create([0x00010203, 0x04050607], 6); + */ + init: function (words, sigBytes) { + words = this.words = words || []; + + if (sigBytes != undefined) { + this.sigBytes = sigBytes; + } else { + this.sigBytes = words.length * 4; + } + }, + + /** + * Converts this word array to a string. + * + * @param {Encoder} encoder (Optional) The encoding strategy to use. Default: CryptoJS.enc.Hex + * + * @return {string} The stringified word array. + * + * @example + * + * var string = wordArray + ''; + * var string = wordArray.toString(); + * var string = wordArray.toString(CryptoJS.enc.Utf8); + */ + toString: function (encoder) { + return (encoder || Hex).stringify(this); + }, + + /** + * Concatenates a word array to this word array. + * + * @param {WordArray} wordArray The word array to append. + * + * @return {WordArray} This word array. + * + * @example + * + * wordArray1.concat(wordArray2); + */ + concat: function (wordArray) { + // Shortcuts + var thisWords = this.words; + var thatWords = wordArray.words; + var thisSigBytes = this.sigBytes; + var thatSigBytes = wordArray.sigBytes; + + // Clamp excess bits + this.clamp(); + + // Concat + if (thisSigBytes % 4) { + // Copy one byte at a time + for (var i = 0; i < thatSigBytes; i++) { + var thatByte = (thatWords[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff; + thisWords[(thisSigBytes + i) >>> 2] |= thatByte << (24 - ((thisSigBytes + i) % 4) * 8); + } + } else if (thatWords.length > 0xffff) { + // Copy one word at a time + for (var i = 0; i < thatSigBytes; i += 4) { + thisWords[(thisSigBytes + i) >>> 2] = thatWords[i >>> 2]; + } + } else { + // Copy all words at once + thisWords.push.apply(thisWords, thatWords); + } + this.sigBytes += thatSigBytes; + + // Chainable + return this; + }, + + /** + * Removes insignificant bits. + * + * @example + * + * wordArray.clamp(); + */ + clamp: function () { + // Shortcuts + var words = this.words; + var sigBytes = this.sigBytes; + + // Clamp + words[sigBytes >>> 2] &= 0xffffffff << (32 - (sigBytes % 4) * 8); + words.length = Math.ceil(sigBytes / 4); + }, + + /** + * Creates a copy of this word array. + * + * @return {WordArray} The clone. + * + * @example + * + * var clone = wordArray.clone(); + */ + clone: function () { + var clone = Base.clone.call(this); + clone.words = this.words.slice(0); + + return clone; + }, + + /** + * Creates a word array filled with random bytes. + * + * @param {number} nBytes The number of random bytes to generate. + * + * @return {WordArray} The random word array. + * + * @static + * + * @example + * + * var wordArray = CryptoJS.lib.WordArray.random(16); + */ + random: function (nBytes) { + var words = []; + + var r = (function (m_w) { + var m_w = m_w; + var m_z = 0x3ade68b1; + var mask = 0xffffffff; + + return function () { + m_z = (0x9069 * (m_z & 0xFFFF) + (m_z >> 0x10)) & mask; + m_w = (0x4650 * (m_w & 0xFFFF) + (m_w >> 0x10)) & mask; + var result = ((m_z << 0x10) + m_w) & mask; + result /= 0x100000000; + result += 0.5; + return result * (Math.random() > .5 ? 1 : -1); + } + }); + + for (var i = 0, rcache; i < nBytes; i += 4) { + var _r = r((rcache || Math.random()) * 0x100000000); + + rcache = _r() * 0x3ade67b7; + words.push((_r() * 0x100000000) | 0); + } + + return new WordArray.init(words, nBytes); + } + }); + + /** + * Encoder namespace. + */ + var C_enc = C.enc = {}; + + /** + * Hex encoding strategy. + */ + var Hex = C_enc.Hex = { + /** + * Converts a word array to a hex string. + * + * @param {WordArray} wordArray The word array. + * + * @return {string} The hex string. + * + * @static + * + * @example + * + * var hexString = CryptoJS.enc.Hex.stringify(wordArray); + */ + stringify: function (wordArray) { + // Shortcuts + var words = wordArray.words; + var sigBytes = wordArray.sigBytes; + + // Convert + var hexChars = []; + for (var i = 0; i < sigBytes; i++) { + var bite = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff; + hexChars.push((bite >>> 4).toString(16)); + hexChars.push((bite & 0x0f).toString(16)); + } + + return hexChars.join(''); + }, + + /** + * Converts a hex string to a word array. + * + * @param {string} hexStr The hex string. + * + * @return {WordArray} The word array. + * + * @static + * + * @example + * + * var wordArray = CryptoJS.enc.Hex.parse(hexString); + */ + parse: function (hexStr) { + // Shortcut + var hexStrLength = hexStr.length; + + // Convert + var words = []; + for (var i = 0; i < hexStrLength; i += 2) { + words[i >>> 3] |= parseInt(hexStr.substr(i, 2), 16) << (24 - (i % 8) * 4); + } + + return new WordArray.init(words, hexStrLength / 2); + } + }; + + /** + * Latin1 encoding strategy. + */ + var Latin1 = C_enc.Latin1 = { + /** + * Converts a word array to a Latin1 string. + * + * @param {WordArray} wordArray The word array. + * + * @return {string} The Latin1 string. + * + * @static + * + * @example + * + * var latin1String = CryptoJS.enc.Latin1.stringify(wordArray); + */ + stringify: function (wordArray) { + // Shortcuts + var words = wordArray.words; + var sigBytes = wordArray.sigBytes; + + // Convert + var latin1Chars = []; + for (var i = 0; i < sigBytes; i++) { + var bite = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff; + latin1Chars.push(String.fromCharCode(bite)); + } + + return latin1Chars.join(''); + }, + + /** + * Converts a Latin1 string to a word array. + * + * @param {string} latin1Str The Latin1 string. + * + * @return {WordArray} The word array. + * + * @static + * + * @example + * + * var wordArray = CryptoJS.enc.Latin1.parse(latin1String); + */ + parse: function (latin1Str) { + // Shortcut + var latin1StrLength = latin1Str.length; + + // Convert + var words = []; + for (var i = 0; i < latin1StrLength; i++) { + words[i >>> 2] |= (latin1Str.charCodeAt(i) & 0xff) << (24 - (i % 4) * 8); + } + + return new WordArray.init(words, latin1StrLength); + } + }; + + /** + * UTF-8 encoding strategy. + */ + var Utf8 = C_enc.Utf8 = { + /** + * Converts a word array to a UTF-8 string. + * + * @param {WordArray} wordArray The word array. + * + * @return {string} The UTF-8 string. + * + * @static + * + * @example + * + * var utf8String = CryptoJS.enc.Utf8.stringify(wordArray); + */ + stringify: function (wordArray) { + try { + return decodeURIComponent(escape(Latin1.stringify(wordArray))); + } catch (e) { + throw new Error('Malformed UTF-8 data'); + } + }, + + /** + * Converts a UTF-8 string to a word array. + * + * @param {string} utf8Str The UTF-8 string. + * + * @return {WordArray} The word array. + * + * @static + * + * @example + * + * var wordArray = CryptoJS.enc.Utf8.parse(utf8String); + */ + parse: function (utf8Str) { + return Latin1.parse(unescape(encodeURIComponent(utf8Str))); + } + }; + + /** + * Abstract buffered block algorithm template. + * + * The property blockSize must be implemented in a concrete subtype. + * + * @property {number} _minBufferSize The number of blocks that should be kept unprocessed in the buffer. Default: 0 + */ + var BufferedBlockAlgorithm = C_lib.BufferedBlockAlgorithm = Base.extend({ + /** + * Resets this block algorithm's data buffer to its initial state. + * + * @example + * + * bufferedBlockAlgorithm.reset(); + */ + reset: function () { + // Initial values + this._data = new WordArray.init(); + this._nDataBytes = 0; + }, + + /** + * Adds new data to this block algorithm's buffer. + * + * @param {WordArray|string} data The data to append. Strings are converted to a WordArray using UTF-8. + * + * @example + * + * bufferedBlockAlgorithm._append('data'); + * bufferedBlockAlgorithm._append(wordArray); + */ + _append: function (data) { + // Convert string to WordArray, else assume WordArray already + if (typeof data == 'string') { + data = Utf8.parse(data); + } + + // Append + this._data.concat(data); + this._nDataBytes += data.sigBytes; + }, + + /** + * Processes available data blocks. + * + * This method invokes _doProcessBlock(offset), which must be implemented by a concrete subtype. + * + * @param {boolean} doFlush Whether all blocks and partial blocks should be processed. + * + * @return {WordArray} The processed data. + * + * @example + * + * var processedData = bufferedBlockAlgorithm._process(); + * var processedData = bufferedBlockAlgorithm._process(!!'flush'); + */ + _process: function (doFlush) { + // Shortcuts + var data = this._data; + var dataWords = data.words; + var dataSigBytes = data.sigBytes; + var blockSize = this.blockSize; + var blockSizeBytes = blockSize * 4; + + // Count blocks ready + var nBlocksReady = dataSigBytes / blockSizeBytes; + if (doFlush) { + // Round up to include partial blocks + nBlocksReady = Math.ceil(nBlocksReady); + } else { + // Round down to include only full blocks, + // less the number of blocks that must remain in the buffer + nBlocksReady = Math.max((nBlocksReady | 0) - this._minBufferSize, 0); + } + + // Count words ready + var nWordsReady = nBlocksReady * blockSize; + + // Count bytes ready + var nBytesReady = Math.min(nWordsReady * 4, dataSigBytes); + + // Process blocks + if (nWordsReady) { + for (var offset = 0; offset < nWordsReady; offset += blockSize) { + // Perform concrete-algorithm logic + this._doProcessBlock(dataWords, offset); + } + + // Remove processed words + var processedWords = dataWords.splice(0, nWordsReady); + data.sigBytes -= nBytesReady; + } + + // Return processed words + return new WordArray.init(processedWords, nBytesReady); + }, + + /** + * Creates a copy of this object. + * + * @return {Object} The clone. + * + * @example + * + * var clone = bufferedBlockAlgorithm.clone(); + */ + clone: function () { + var clone = Base.clone.call(this); + clone._data = this._data.clone(); + + return clone; + }, + + _minBufferSize: 0 + }); + + /** + * Abstract hasher template. + * + * @property {number} blockSize The number of 32-bit words this hasher operates on. Default: 16 (512 bits) + */ + var Hasher = C_lib.Hasher = BufferedBlockAlgorithm.extend({ + /** + * Configuration options. + */ + cfg: Base.extend(), + + /** + * Initializes a newly created hasher. + * + * @param {Object} cfg (Optional) The configuration options to use for this hash computation. + * + * @example + * + * var hasher = CryptoJS.algo.SHA256.create(); + */ + init: function (cfg) { + // Apply config defaults + this.cfg = this.cfg.extend(cfg); + + // Set initial values + this.reset(); + }, + + /** + * Resets this hasher to its initial state. + * + * @example + * + * hasher.reset(); + */ + reset: function () { + // Reset data buffer + BufferedBlockAlgorithm.reset.call(this); + + // Perform concrete-hasher logic + this._doReset(); + }, + + /** + * Updates this hasher with a message. + * + * @param {WordArray|string} messageUpdate The message to append. + * + * @return {Hasher} This hasher. + * + * @example + * + * hasher.update('message'); + * hasher.update(wordArray); + */ + update: function (messageUpdate) { + // Append + this._append(messageUpdate); + + // Update the hash + this._process(); + + // Chainable + return this; + }, + + /** + * Finalizes the hash computation. + * Note that the finalize operation is effectively a destructive, read-once operation. + * + * @param {WordArray|string} messageUpdate (Optional) A final message update. + * + * @return {WordArray} The hash. + * + * @example + * + * var hash = hasher.finalize(); + * var hash = hasher.finalize('message'); + * var hash = hasher.finalize(wordArray); + */ + finalize: function (messageUpdate) { + // Final message update + if (messageUpdate) { + this._append(messageUpdate); + } + + // Perform concrete-hasher logic + var hash = this._doFinalize(); + + return hash; + }, + + blockSize: 512/32, + + /** + * Creates a shortcut function to a hasher's object interface. + * + * @param {Hasher} hasher The hasher to create a helper for. + * + * @return {Function} The shortcut function. + * + * @static + * + * @example + * + * var SHA256 = CryptoJS.lib.Hasher._createHelper(CryptoJS.algo.SHA256); + */ + _createHelper: function (hasher) { + return function (message, cfg) { + return new hasher.init(cfg).finalize(message); + }; + }, + + /** + * Creates a shortcut function to the HMAC's object interface. + * + * @param {Hasher} hasher The hasher to use in this HMAC helper. + * + * @return {Function} The shortcut function. + * + * @static + * + * @example + * + * var HmacSHA256 = CryptoJS.lib.Hasher._createHmacHelper(CryptoJS.algo.SHA256); + */ + _createHmacHelper: function (hasher) { + return function (message, key) { + return new C_algo.HMAC.init(hasher, key).finalize(message); + }; + } + }); + + /** + * Algorithm namespace. + */ + var C_algo = C.algo = {}; + + return C; + }(Math)); + + + return CryptoJS; + +})); +},{}],30:[function(require,module,exports){ +;(function (root, factory, undef) { + if (typeof exports === "object") { + // CommonJS + module.exports = exports = factory(require("./core"), require("./x64-core")); + } + else if (typeof define === "function" && define.amd) { + // AMD + define(["./core", "./x64-core"], factory); + } + else { + // Global (browser) + factory(root.CryptoJS); + } +}(this, function (CryptoJS) { + + (function (Math) { + // Shortcuts + var C = CryptoJS; + var C_lib = C.lib; + var WordArray = C_lib.WordArray; + var Hasher = C_lib.Hasher; + var C_x64 = C.x64; + var X64Word = C_x64.Word; + var C_algo = C.algo; + + // Constants tables + var RHO_OFFSETS = []; + var PI_INDEXES = []; + var ROUND_CONSTANTS = []; + + // Compute Constants + (function () { + // Compute rho offset constants + var x = 1, y = 0; + for (var t = 0; t < 24; t++) { + RHO_OFFSETS[x + 5 * y] = ((t + 1) * (t + 2) / 2) % 64; + + var newX = y % 5; + var newY = (2 * x + 3 * y) % 5; + x = newX; + y = newY; + } + + // Compute pi index constants + for (var x = 0; x < 5; x++) { + for (var y = 0; y < 5; y++) { + PI_INDEXES[x + 5 * y] = y + ((2 * x + 3 * y) % 5) * 5; + } + } + + // Compute round constants + var LFSR = 0x01; + for (var i = 0; i < 24; i++) { + var roundConstantMsw = 0; + var roundConstantLsw = 0; + + for (var j = 0; j < 7; j++) { + if (LFSR & 0x01) { + var bitPosition = (1 << j) - 1; + if (bitPosition < 32) { + roundConstantLsw ^= 1 << bitPosition; + } else /* if (bitPosition >= 32) */ { + roundConstantMsw ^= 1 << (bitPosition - 32); + } + } + + // Compute next LFSR + if (LFSR & 0x80) { + // Primitive polynomial over GF(2): x^8 + x^6 + x^5 + x^4 + 1 + LFSR = (LFSR << 1) ^ 0x71; + } else { + LFSR <<= 1; + } + } + + ROUND_CONSTANTS[i] = X64Word.create(roundConstantMsw, roundConstantLsw); + } + }()); + + // Reusable objects for temporary values + var T = []; + (function () { + for (var i = 0; i < 25; i++) { + T[i] = X64Word.create(); + } + }()); + + /** + * SHA-3 hash algorithm. + */ + var SHA3 = C_algo.SHA3 = Hasher.extend({ + /** + * Configuration options. + * + * @property {number} outputLength + * The desired number of bits in the output hash. + * Only values permitted are: 224, 256, 384, 512. + * Default: 512 + */ + cfg: Hasher.cfg.extend({ + outputLength: 512 + }), + + _doReset: function () { + var state = this._state = [] + for (var i = 0; i < 25; i++) { + state[i] = new X64Word.init(); + } + + this.blockSize = (1600 - 2 * this.cfg.outputLength) / 32; + }, + + _doProcessBlock: function (M, offset) { + // Shortcuts + var state = this._state; + var nBlockSizeLanes = this.blockSize / 2; + + // Absorb + for (var i = 0; i < nBlockSizeLanes; i++) { + // Shortcuts + var M2i = M[offset + 2 * i]; + var M2i1 = M[offset + 2 * i + 1]; + + // Swap endian + M2i = ( + (((M2i << 8) | (M2i >>> 24)) & 0x00ff00ff) | + (((M2i << 24) | (M2i >>> 8)) & 0xff00ff00) + ); + M2i1 = ( + (((M2i1 << 8) | (M2i1 >>> 24)) & 0x00ff00ff) | + (((M2i1 << 24) | (M2i1 >>> 8)) & 0xff00ff00) + ); + + // Absorb message into state + var lane = state[i]; + lane.high ^= M2i1; + lane.low ^= M2i; + } + + // Rounds + for (var round = 0; round < 24; round++) { + // Theta + for (var x = 0; x < 5; x++) { + // Mix column lanes + var tMsw = 0, tLsw = 0; + for (var y = 0; y < 5; y++) { + var lane = state[x + 5 * y]; + tMsw ^= lane.high; + tLsw ^= lane.low; + } + + // Temporary values + var Tx = T[x]; + Tx.high = tMsw; + Tx.low = tLsw; + } + for (var x = 0; x < 5; x++) { + // Shortcuts + var Tx4 = T[(x + 4) % 5]; + var Tx1 = T[(x + 1) % 5]; + var Tx1Msw = Tx1.high; + var Tx1Lsw = Tx1.low; + + // Mix surrounding columns + var tMsw = Tx4.high ^ ((Tx1Msw << 1) | (Tx1Lsw >>> 31)); + var tLsw = Tx4.low ^ ((Tx1Lsw << 1) | (Tx1Msw >>> 31)); + for (var y = 0; y < 5; y++) { + var lane = state[x + 5 * y]; + lane.high ^= tMsw; + lane.low ^= tLsw; + } + } + + // Rho Pi + for (var laneIndex = 1; laneIndex < 25; laneIndex++) { + // Shortcuts + var lane = state[laneIndex]; + var laneMsw = lane.high; + var laneLsw = lane.low; + var rhoOffset = RHO_OFFSETS[laneIndex]; + + // Rotate lanes + if (rhoOffset < 32) { + var tMsw = (laneMsw << rhoOffset) | (laneLsw >>> (32 - rhoOffset)); + var tLsw = (laneLsw << rhoOffset) | (laneMsw >>> (32 - rhoOffset)); + } else /* if (rhoOffset >= 32) */ { + var tMsw = (laneLsw << (rhoOffset - 32)) | (laneMsw >>> (64 - rhoOffset)); + var tLsw = (laneMsw << (rhoOffset - 32)) | (laneLsw >>> (64 - rhoOffset)); + } + + // Transpose lanes + var TPiLane = T[PI_INDEXES[laneIndex]]; + TPiLane.high = tMsw; + TPiLane.low = tLsw; + } + + // Rho pi at x = y = 0 + var T0 = T[0]; + var state0 = state[0]; + T0.high = state0.high; + T0.low = state0.low; + + // Chi + for (var x = 0; x < 5; x++) { + for (var y = 0; y < 5; y++) { + // Shortcuts + var laneIndex = x + 5 * y; + var lane = state[laneIndex]; + var TLane = T[laneIndex]; + var Tx1Lane = T[((x + 1) % 5) + 5 * y]; + var Tx2Lane = T[((x + 2) % 5) + 5 * y]; + + // Mix rows + lane.high = TLane.high ^ (~Tx1Lane.high & Tx2Lane.high); + lane.low = TLane.low ^ (~Tx1Lane.low & Tx2Lane.low); + } + } + + // Iota + var lane = state[0]; + var roundConstant = ROUND_CONSTANTS[round]; + lane.high ^= roundConstant.high; + lane.low ^= roundConstant.low;; + } + }, + + _doFinalize: function () { + // Shortcuts + var data = this._data; + var dataWords = data.words; + var nBitsTotal = this._nDataBytes * 8; + var nBitsLeft = data.sigBytes * 8; + var blockSizeBits = this.blockSize * 32; + + // Add padding + dataWords[nBitsLeft >>> 5] |= 0x1 << (24 - nBitsLeft % 32); + dataWords[((Math.ceil((nBitsLeft + 1) / blockSizeBits) * blockSizeBits) >>> 5) - 1] |= 0x80; + data.sigBytes = dataWords.length * 4; + + // Hash final blocks + this._process(); + + // Shortcuts + var state = this._state; + var outputLengthBytes = this.cfg.outputLength / 8; + var outputLengthLanes = outputLengthBytes / 8; + + // Squeeze + var hashWords = []; + for (var i = 0; i < outputLengthLanes; i++) { + // Shortcuts + var lane = state[i]; + var laneMsw = lane.high; + var laneLsw = lane.low; + + // Swap endian + laneMsw = ( + (((laneMsw << 8) | (laneMsw >>> 24)) & 0x00ff00ff) | + (((laneMsw << 24) | (laneMsw >>> 8)) & 0xff00ff00) + ); + laneLsw = ( + (((laneLsw << 8) | (laneLsw >>> 24)) & 0x00ff00ff) | + (((laneLsw << 24) | (laneLsw >>> 8)) & 0xff00ff00) + ); + + // Squeeze state to retrieve hash + hashWords.push(laneLsw); + hashWords.push(laneMsw); + } + + // Return final computed hash + return new WordArray.init(hashWords, outputLengthBytes); + }, + + clone: function () { + var clone = Hasher.clone.call(this); + + var state = clone._state = this._state.slice(0); + for (var i = 0; i < 25; i++) { + state[i] = state[i].clone(); + } + + return clone; + } + }); + + /** + * Shortcut function to the hasher's object interface. + * + * @param {WordArray|string} message The message to hash. + * + * @return {WordArray} The hash. + * + * @static + * + * @example + * + * var hash = CryptoJS.SHA3('message'); + * var hash = CryptoJS.SHA3(wordArray); + */ + C.SHA3 = Hasher._createHelper(SHA3); + + /** + * Shortcut function to the HMAC's object interface. + * + * @param {WordArray|string} message The message to hash. + * @param {WordArray|string} key The secret key. + * + * @return {WordArray} The HMAC. + * + * @static + * + * @example + * + * var hmac = CryptoJS.HmacSHA3(message, key); + */ + C.HmacSHA3 = Hasher._createHmacHelper(SHA3); + }(Math)); + + + return CryptoJS.SHA3; + +})); +},{"./core":29,"./x64-core":31}],31:[function(require,module,exports){ +;(function (root, factory) { + if (typeof exports === "object") { + // CommonJS + module.exports = exports = factory(require("./core")); + } + else if (typeof define === "function" && define.amd) { + // AMD + define(["./core"], factory); + } + else { + // Global (browser) + factory(root.CryptoJS); + } +}(this, function (CryptoJS) { + + (function (undefined) { + // Shortcuts + var C = CryptoJS; + var C_lib = C.lib; + var Base = C_lib.Base; + var X32WordArray = C_lib.WordArray; + + /** + * x64 namespace. + */ + var C_x64 = C.x64 = {}; + + /** + * A 64-bit word. + */ + var X64Word = C_x64.Word = Base.extend({ + /** + * Initializes a newly created 64-bit word. + * + * @param {number} high The high 32 bits. + * @param {number} low The low 32 bits. + * + * @example + * + * var x64Word = CryptoJS.x64.Word.create(0x00010203, 0x04050607); + */ + init: function (high, low) { + this.high = high; + this.low = low; + } + + /** + * Bitwise NOTs this word. + * + * @return {X64Word} A new x64-Word object after negating. + * + * @example + * + * var negated = x64Word.not(); + */ + // not: function () { + // var high = ~this.high; + // var low = ~this.low; + + // return X64Word.create(high, low); + // }, + + /** + * Bitwise ANDs this word with the passed word. + * + * @param {X64Word} word The x64-Word to AND with this word. + * + * @return {X64Word} A new x64-Word object after ANDing. + * + * @example + * + * var anded = x64Word.and(anotherX64Word); + */ + // and: function (word) { + // var high = this.high & word.high; + // var low = this.low & word.low; + + // return X64Word.create(high, low); + // }, + + /** + * Bitwise ORs this word with the passed word. + * + * @param {X64Word} word The x64-Word to OR with this word. + * + * @return {X64Word} A new x64-Word object after ORing. + * + * @example + * + * var ored = x64Word.or(anotherX64Word); + */ + // or: function (word) { + // var high = this.high | word.high; + // var low = this.low | word.low; + + // return X64Word.create(high, low); + // }, + + /** + * Bitwise XORs this word with the passed word. + * + * @param {X64Word} word The x64-Word to XOR with this word. + * + * @return {X64Word} A new x64-Word object after XORing. + * + * @example + * + * var xored = x64Word.xor(anotherX64Word); + */ + // xor: function (word) { + // var high = this.high ^ word.high; + // var low = this.low ^ word.low; + + // return X64Word.create(high, low); + // }, + + /** + * Shifts this word n bits to the left. + * + * @param {number} n The number of bits to shift. + * + * @return {X64Word} A new x64-Word object after shifting. + * + * @example + * + * var shifted = x64Word.shiftL(25); + */ + // shiftL: function (n) { + // if (n < 32) { + // var high = (this.high << n) | (this.low >>> (32 - n)); + // var low = this.low << n; + // } else { + // var high = this.low << (n - 32); + // var low = 0; + // } + + // return X64Word.create(high, low); + // }, + + /** + * Shifts this word n bits to the right. + * + * @param {number} n The number of bits to shift. + * + * @return {X64Word} A new x64-Word object after shifting. + * + * @example + * + * var shifted = x64Word.shiftR(7); + */ + // shiftR: function (n) { + // if (n < 32) { + // var low = (this.low >>> n) | (this.high << (32 - n)); + // var high = this.high >>> n; + // } else { + // var low = this.high >>> (n - 32); + // var high = 0; + // } + + // return X64Word.create(high, low); + // }, + + /** + * Rotates this word n bits to the left. + * + * @param {number} n The number of bits to rotate. + * + * @return {X64Word} A new x64-Word object after rotating. + * + * @example + * + * var rotated = x64Word.rotL(25); + */ + // rotL: function (n) { + // return this.shiftL(n).or(this.shiftR(64 - n)); + // }, + + /** + * Rotates this word n bits to the right. + * + * @param {number} n The number of bits to rotate. + * + * @return {X64Word} A new x64-Word object after rotating. + * + * @example + * + * var rotated = x64Word.rotR(7); + */ + // rotR: function (n) { + // return this.shiftR(n).or(this.shiftL(64 - n)); + // }, + + /** + * Adds this word with the passed word. + * + * @param {X64Word} word The x64-Word to add with this word. + * + * @return {X64Word} A new x64-Word object after adding. + * + * @example + * + * var added = x64Word.add(anotherX64Word); + */ + // add: function (word) { + // var low = (this.low + word.low) | 0; + // var carry = (low >>> 0) < (this.low >>> 0) ? 1 : 0; + // var high = (this.high + word.high + carry) | 0; + + // return X64Word.create(high, low); + // } + }); + + /** + * An array of 64-bit words. + * + * @property {Array} words The array of CryptoJS.x64.Word objects. + * @property {number} sigBytes The number of significant bytes in this word array. + */ + var X64WordArray = C_x64.WordArray = Base.extend({ + /** + * Initializes a newly created word array. + * + * @param {Array} words (Optional) An array of CryptoJS.x64.Word objects. + * @param {number} sigBytes (Optional) The number of significant bytes in the words. + * + * @example + * + * var wordArray = CryptoJS.x64.WordArray.create(); + * + * var wordArray = CryptoJS.x64.WordArray.create([ + * CryptoJS.x64.Word.create(0x00010203, 0x04050607), + * CryptoJS.x64.Word.create(0x18191a1b, 0x1c1d1e1f) + * ]); + * + * var wordArray = CryptoJS.x64.WordArray.create([ + * CryptoJS.x64.Word.create(0x00010203, 0x04050607), + * CryptoJS.x64.Word.create(0x18191a1b, 0x1c1d1e1f) + * ], 10); + */ + init: function (words, sigBytes) { + words = this.words = words || []; + + if (sigBytes != undefined) { + this.sigBytes = sigBytes; + } else { + this.sigBytes = words.length * 8; + } + }, + + /** + * Converts this 64-bit word array to a 32-bit word array. + * + * @return {CryptoJS.lib.WordArray} This word array's data as a 32-bit word array. + * + * @example + * + * var x32WordArray = x64WordArray.toX32(); + */ + toX32: function () { + // Shortcuts + var x64Words = this.words; + var x64WordsLength = x64Words.length; + + // Convert + var x32Words = []; + for (var i = 0; i < x64WordsLength; i++) { + var x64Word = x64Words[i]; + x32Words.push(x64Word.high); + x32Words.push(x64Word.low); + } + + return X32WordArray.create(x32Words, this.sigBytes); + }, + + /** + * Creates a copy of this word array. + * + * @return {X64WordArray} The clone. + * + * @example + * + * var clone = x64WordArray.clone(); + */ + clone: function () { + var clone = Base.clone.call(this); + + // Clone "words" array + var words = clone.words = this.words.slice(0); + + // Clone each X64Word object + var wordsLength = words.length; + for (var i = 0; i < wordsLength; i++) { + words[i] = words[i].clone(); + } + + return clone; + } + }); + }()); + + + return CryptoJS; + +})); +},{"./core":29}],"bignumber.js":[function(require,module,exports){ 'use strict'; module.exports = BigNumber; // jshint ignore:line @@ -3676,7 +5263,6 @@ var web3 = require('./lib/web3'); web3.providers.HttpProvider = require('./lib/web3/httpprovider'); web3.providers.QtSyncProvider = require('./lib/web3/qtsync'); web3.eth.contract = require('./lib/web3/contract'); -web3.abi = require('./lib/solidity/abi'); // dont override global variable if (typeof window !== 'undefined' && typeof window.web3 === 'undefined') { @@ -3686,7 +5272,7 @@ if (typeof window !== 'undefined' && typeof window.web3 === 'undefined') { module.exports = web3; -},{"./lib/solidity/abi":1,"./lib/web3":10,"./lib/web3/contract":11,"./lib/web3/httpprovider":19,"./lib/web3/qtsync":24}]},{},["web3"]) +},{"./lib/web3":9,"./lib/web3/contract":11,"./lib/web3/httpprovider":19,"./lib/web3/qtsync":24}]},{},["web3"]) //# sourceMappingURL=web3-light.js.map |