diff --git a/js/web3.js b/js/web3.js index 54a5519db..d4f1d2130 100644 --- a/js/web3.js +++ b/js/web3.js @@ -15,141 +15,6 @@ 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 . */ -/** - * @file abi.js - * @author Marek Kotewicz - * @author Gav Wood - * @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 . -*/ /** * @file coder.js * @author Marek Kotewicz @@ -213,9 +78,8 @@ 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); }; @@ -232,9 +96,9 @@ SolidityType.prototype.formatOutput = function (param, arrayType) { if (arrayType) { // let's assume, that we solidity will never return long arrays :P var result = []; - var length = new BigNumber(param.prefix, 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; } @@ -242,31 +106,21 @@ SolidityType.prototype.formatOutput = function (param, arrayType) { }; /** - * Should be used to check if a type is variadic + * Should be used to slice single param from bytes * - * @method isVariadicType + * @method sliceParam + * @param {String} bytes + * @param {Number} index of param to slice * @param {String} type - * @returns {Bool} true if the type is variadic + * @returns {SolidityParam} param */ -SolidityType.prototype.isVariadicType = function (type) { - return isArrayType(type) || this._mode === 'bytes'; -}; - -/** - * Should be used to shift param from params group - * - * @method shiftParam - * @param {String} type - * @returns {SolidityParam} shifted 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.prefix.slice(0, 64), 16); - return param.shiftArray(length); + return SolidityParam.decodeArray(bytes, index); } - return param.shiftValue(); + return SolidityParam.decodeParam(bytes, index); }; /** @@ -296,28 +150,6 @@ SolidityCoder.prototype._requireType = function (type) { return solidityType; }; -/** - * 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 self = this; - var prefixTypes = types.reduce(function (acc, type) { - return self._requireType(type).isVariadicType(type) ? acc + 1 : acc; - }, 0); - var valueTypes = types.length - prefixTypes; - - var prefix = bytes.slice(0, prefixTypes * 64); - bytes = bytes.slice(prefixTypes * 64); - var value = bytes.slice(0, valueTypes * 64); - var suffix = bytes.slice(valueTypes * 64); - return new SolidityParam(value, prefix, suffix); -}; - /** * Should be used to transform plain param of given type to SolidityParam * @@ -352,24 +184,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); }; /** @@ -381,7 +200,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]; }; /** @@ -394,10 +213,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)); }); }; @@ -464,7 +282,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. @@ -530,7 +348,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); }; /** @@ -576,7 +394,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 @@ -594,7 +412,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); }; @@ -628,7 +446,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; }; /** @@ -640,7 +458,7 @@ var formatOutputBool = function (param) { */ var formatOutputBytes = function (param) { // length might also be important! - return utils.toAscii(param.value); + return utils.toAscii(param.staticPart()); }; /** @@ -652,7 +470,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)); }; /** @@ -663,7 +481,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); }; @@ -684,7 +502,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. @@ -707,133 +525,196 @@ module.exports = { * @date 2015 */ +var utils = require('../utils/utils'); + /** * SolidityParam object prototype. * Should be used when encoding, decoding solidity bytes */ -var SolidityParam = function (value, prefix, suffix) { - this.prefix = prefix || ''; +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 - * - * @method append - * @param {SolidityParam} param that it appended after this + * 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.append = function (param) { - this.prefix += param.prefix; - 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.prefix += param.prefix; - // TODO: suffix not supported = it's required for nested arrays; +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 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.value.length > 64 || 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 - * @return {String} encoded param(s) + * @returns {String} */ SolidityParam.prototype.encode = function () { - return this.prefix + this.value + this.suffix; + return this.staticPart() + this.dynamicPart(); }; /** - * This method should be used to shift first param from group of params + * This method should be called to encode array of params * - * @method shiftValue - * @return {SolidityParam} first value param + * @method encodeList + * @param {Array[SolidityParam]} params + * @returns {String} */ -SolidityParam.prototype.shiftValue = function () { - var value = this.value.slice(0, 64); - this.value = this.value.slice(64); - return new SolidityParam(value); +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(); + }, '')); }; /** - * This method should be used to first bytes param from group of params + * This method should be used to decode plain (static) solidity param at given index * - * @method shiftBytes - * @return {SolidityParam} first bytes param + * @method decodeParam + * @param {String} bytes + * @param {Number} index + * @returns {SolidityParam} */ -SolidityParam.prototype.shiftBytes = function () { - return this.shiftArray(1); +SolidityParam.decodeParam = function (bytes, index) { + index = index || 0; + return new SolidityParam(bytes.substr(index * 64, 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 offset value from bytes at given index + * + * @method getOffset + * @param {String} bytes + * @param {Number} index + * @returns {Number} offset as number */ -SolidityParam.prototype.shiftArray = function (length) { - var prefix = this.prefix.slice(0, 64); - this.prefix = this.value.slice(64); - var suffix = this.suffix.slice(0, 64 * length); - this.suffix = this.suffix.slice(64 * length); - return new SolidityParam('', prefix, suffix); +var getOffset = function (bytes, index) { + // we can do this cause offset is rather small + return parseInt('0x' + bytes.substr(index * 64, 64)); +}; + +/** + * 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), 0); +}; + +/** + * 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), 0); }; module.exports = SolidityParam; -},{}],5:[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 . -*/ -/** - * @file utils.js - * @author Marek Kotewicz - * @date 2015 - */ - -/** - * Returns the contstructor with matching number of arguments - * - * @method getConstructor - * @param {Array} abi - * @param {Number} numberOfArgs - * @returns {Object} constructor function abi - */ -var getConstructor = function (abi, numberOfArgs) { - return abi.filter(function (f) { - return f.type === 'constructor' && f.inputs.length === numberOfArgs; - })[0]; -}; - -module.exports = { - getConstructor: getConstructor -}; - - -},{}],6:[function(require,module,exports){ +},{"../utils/utils":7}],4:[function(require,module,exports){ 'use strict'; // go env doesn't have and need XMLHttpRequest @@ -844,7 +725,7 @@ if (typeof XMLHttpRequest === 'undefined') { } -},{}],7:[function(require,module,exports){ +},{}],5:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -916,7 +797,48 @@ 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. + + 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 . +*/ +/** + * @file sha3.js + * @author Marek Kotewicz + * @date 2015 + */ + +var utils = require('./utils'); +var sha3 = require('crypto-js/sha3'); + +module.exports = function (str, isNew) { + if (str.substr(0, 2) === '0x' && !isNew) { + console.warn('requirement of using web3.fromAscii before sha3 is deprecated'); + console.warn('new usage: \'web3.sha3("hello")\''); + console.warn('see https://github.com/ethereum/web3.js/pull/205'); + console.warn('if you need to hash hex value, you can do \'sha3("0xfff", true)\''); + str = utils.toAscii(str); + } + + return sha3(str, { + outputLength: 256 + }).toString(); +}; + + +},{"./utils":7,"crypto-js/sha3":33}],7:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -1282,6 +1204,7 @@ var toAddress = function (address) { return '0x' + padLeft(toHex(address).substr(2), 40); }; + /** * Returns true if object is BigNumber, otherwise false * @@ -1365,6 +1288,18 @@ var isJson = function (str) { } }; +/** + * This method should be called to check if string is valid ethereum IBAN number + * Supports direct and indirect IBANs + * + * @method isIBAN + * @param {String} + * @return {Boolean} + */ +var isIBAN = function (iban) { + return /^XE[0-9]{2}(ETH[0-9A-Z]{13}|[0-9A-Z]{30})$/.test(iban); +}; + module.exports = { padLeft: padLeft, toHex: toHex, @@ -1388,16 +1323,17 @@ module.exports = { isObject: isObject, isBoolean: isBoolean, isArray: isArray, - isJson: isJson + isJson: isJson, + isIBAN: isIBAN }; -},{"bignumber.js":"bignumber.js"}],9:[function(require,module,exports){ +},{"bignumber.js":"bignumber.js"}],8:[function(require,module,exports){ module.exports={ - "version": "0.3.4" + "version": "0.5.0" } -},{}],10:[function(require,module,exports){ +},{}],9:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -1435,16 +1371,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({ @@ -1529,6 +1458,11 @@ web3.toBigNumber = utils.toBigNumber; web3.toWei = utils.toWei; web3.fromWei = utils.fromWei; web3.isAddress = utils.isAddress; +web3.isIBAN = utils.isIBAN; +web3.sha3 = sha3; +web3.createBatch = function () { + return new Batch(); +}; // ADD defaultblock Object.defineProperty(web3.eth, 'defaultBlock', { @@ -1552,7 +1486,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); @@ -1564,7 +1497,70 @@ 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":24,"./web3/property":25,"./web3/requestmanager":27,"./web3/shh":28,"./web3/watches":30}],10:[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 . +*/ +/** + * @file batch.js + * @author Marek Kotewicz + * @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":27}],11:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -1588,13 +1584,39 @@ module.exports = web3; */ var web3 = require('../web3'); -var solAbi = require('../solidity/abi'); 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); @@ -1603,8 +1625,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); @@ -1614,65 +1643,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: + * Should be called to create new ContractFactory * - * 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 - * - * @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 prototype - return Contract.bind(null, abi); + return new ContractFactory(abi); }; -var Contract = function (abi, options) { +/** + * Should be called to create new ContractFactory instance + * + * @method ContractFactory + * @param {Array} abi + */ +var ContractFactory = function (abi) { + this.abi = abi; +}; - 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); +/** + * 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; + + var args = Array.prototype.slice.call(arguments); + if (utils.isFunction(args[args.length - 1])) { + callback = args.pop(); } + 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); + }); +}; + +/** + * 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); +}; + +/** + * 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); }; -Contract.prototype.call = function () { - console.error('contract.call is deprecated'); - return this; -}; - -Contract.prototype.sendTransaction = function () { - console.error('contract.sendTransact is deprecated'); - return this; -}; - 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. @@ -1730,7 +1800,7 @@ module.exports = { methods: methods }; -},{"./method":21}],13:[function(require,module,exports){ +},{"./method":22}],13:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -1947,6 +2017,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', @@ -1965,6 +2043,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, @@ -1978,10 +2068,13 @@ var methods = [ getTransactionFromBlock, getTransactionCount, call, + estimateGas, sendTransaction, compileSolidity, compileLLL, compileSerpent, + submitWork, + getWork ]; /// @returns an array of objects describing web3.eth api properties @@ -2024,7 +2117,7 @@ module.exports = { }; -},{"../utils/utils":8,"./formatters":17,"./method":21,"./property":23}],15:[function(require,module,exports){ +},{"../utils/utils":7,"./formatters":17,"./method":22,"./property":25}],15:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -2051,6 +2144,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 @@ -2104,7 +2198,7 @@ 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); }; /** @@ -2220,7 +2314,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. @@ -2377,7 +2471,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":27}],17:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -2452,7 +2546,7 @@ 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]); @@ -2597,7 +2691,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. @@ -2614,7 +2708,7 @@ module.exports = { You should have received a copy of the GNU Lesser General Public License along with ethereum.js. If not, see . */ -/** +/** * @file function.js * @author Marek Kotewicz * @date 2015 @@ -2623,6 +2717,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 @@ -2639,18 +2734,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); @@ -2664,24 +2764,46 @@ 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); }; -/** - * Should be used to call function - * - * @method call - * @param {Object} options - * @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); + +SolidityFunction.prototype.unpackOutput = function (output) { + if (!output) { + return; + } + output = output.length >= 2 ? output.slice(2) : output; var result = coder.decodeParams(this._outputTypes, output); return result.length === 1 ? result[0] : result; }; +/** + * Calls a contract function. + * + * @method call + * @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 args = Array.prototype.slice.call(arguments).filter(function (a) {return a !== undefined; }); + 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)); + }); +}; + /** * Should be used to sendTransaction to solidity function * @@ -2689,8 +2811,33 @@ 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).filter(function (a) {return a !== undefined; }); + var callback = this.extractCallback(args); + var payload = this.toPayload(args); + + if (!callback) { + return web3.eth.sendTransaction(payload); + } + + web3.eth.sendTransaction(payload, callback); +}; + +/** + * Should be used to estimateGas of solidity function + * + * @method estimateGas + * @param {Object} options + */ +SolidityFunction.prototype.estimateGas = function () { + var args = Array.prototype.slice.call(arguments); + var callback = this.extractCallback(args); + var payload = this.toPayload(args); + + if (!callback) { + return web3.eth.estimateGas(payload); + } + + web3.eth.estimateGas(payload, callback); }; /** @@ -2705,7 +2852,7 @@ SolidityFunction.prototype.displayName = function () { /** * Should be used to get function type name - * + * * @method typeName * @return {String} type name of the function */ @@ -2713,6 +2860,25 @@ SolidityFunction.prototype.typeName = function () { return utils.extractTypeName(this._name); }; +/** + * 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 * @@ -2720,7 +2886,7 @@ SolidityFunction.prototype.typeName = function () { */ SolidityFunction.prototype.execute = function () { var transaction = !this._constant; - + // send transaction if (transaction) { return this.sendTransaction.apply(this, Array.prototype.slice.call(arguments)); @@ -2738,8 +2904,10 @@ 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); + execute.estimateGas = this.estimateGas.bind(this); var displayName = this.displayName(); if (!contract[displayName]) { contract[displayName] = execute; @@ -2750,7 +2918,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. @@ -2801,15 +2969,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); } }; @@ -2825,7 +3010,117 @@ 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. + + 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 . +*/ +/** + * @file icap.js + * @author Marek Kotewicz + * @date 2015 + */ + +var utils = require('../utils/utils'); + +/** + * This prototype should be used to extract necessary information from iban address + * + * @param {String} iban + */ +var ICAP = function (iban) { + this._iban = iban; +}; + +/** + * Should be called to check if icap is correct + * + * @method isValid + * @returns {Boolean} true if it is, otherwise false + */ +ICAP.prototype.isValid = function () { + return utils.isIBAN(this._iban); +}; + +/** + * Should be called to check if iban number is direct + * + * @method isDirect + * @returns {Boolean} true if it is, otherwise false + */ +ICAP.prototype.isDirect = function () { + return this._iban.length === 34; +}; + +/** + * Should be called to check if iban number if indirect + * + * @method isIndirect + * @returns {Boolean} true if it is, otherwise false + */ +ICAP.prototype.isIndirect = function () { + return this._iban.length === 20; +}; + +/** + * Should be called to get iban checksum + * Uses the mod-97-10 checksumming protocol (ISO/IEC 7064:2003) + * + * @method checksum + * @returns {String} checksum + */ +ICAP.prototype.checksum = function () { + return this._iban.substr(2, 2); +}; + +/** + * Should be called to get institution identifier + * eg. XREG + * + * @method institution + * @returns {String} institution identifier + */ +ICAP.prototype.institution = function () { + return this.isIndirect() ? this._iban.substr(7, 4) : ''; +}; + +/** + * Should be called to get client identifier within institution + * eg. GAVOFYORK + * + * @method client + * @returns {String} client identifier + */ +ICAP.prototype.client = function () { + return this.isIndirect() ? this._iban.substr(11) : ''; +}; + +/** + * Should be called to get client direct address + * + * @method address + * @returns {String} client direct address + */ +ICAP.prototype.address = function () { + return this.isDirect() ? this._iban.substr(4) : ''; +}; + +module.exports = ICAP; + + +},{"../utils/utils":7}],21:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -2918,7 +3213,7 @@ Jsonrpc.prototype.toBatchPayload = function (messages) { module.exports = Jsonrpc; -},{}],21:[function(require,module,exports){ +},{}],22:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -2975,7 +3270,6 @@ Method.prototype.extractCallback = function (args) { if (utils.isFunction(args[args.length - 1])) { return args.pop(); // modify the args array! } - return null; }; /** @@ -3028,6 +3322,7 @@ Method.prototype.formatOutput = function (result) { */ 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) { @@ -3058,6 +3353,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 * @@ -3070,7 +3378,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)); @@ -3079,7 +3387,55 @@ 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":27}],23:[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 . +*/ +/** + * @file namereg.js + * @author Marek Kotewicz + * @date 2015 + */ + +var contract = require('./contract'); + +var address = '0xc6d9d2cd449a754c494264e1809c50e34d64562b'; + +var abi = [ + {"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":"o_subRegistrar","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"}, + {"constant":true,"inputs":[{"name":"_name","type":"bytes32"}],"name":"register","outputs":[{"name":"","type":"address"}],"type":"function"}, + {"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"} +]; + +module.exports = contract(abi).at(address); + + +},{"./contract":11}],24:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -3129,7 +3485,7 @@ module.exports = { }; -},{"../utils/utils":8,"./property":23}],23:[function(require,module,exports){ +},{"../utils/utils":7,"./property":25}],25:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -3195,16 +3551,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); }; /** @@ -3220,22 +3583,27 @@ 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)); }); }; module.exports = Property; -},{"./requestmanager":25}],24:[function(require,module,exports){ +},{"./requestmanager":27}],26:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -3270,7 +3638,7 @@ QtSyncProvider.prototype.send = function (payload) { module.exports = QtSyncProvider; -},{}],25:[function(require,module,exports){ +},{}],27:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -3378,6 +3746,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 * @@ -3491,7 +3886,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":21}],28:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -3561,7 +3956,103 @@ module.exports = { }; -},{"./formatters":17,"./method":21}],27:[function(require,module,exports){ +},{"./formatters":17,"./method":22}],29:[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 . +*/ +/** + * @file transfer.js + * @author Marek Kotewicz + * @date 2015 + */ + +var web3 = require('../web3'); +var ICAP = require('./icap'); +var namereg = require('./namereg'); +var contract = require('./contract'); + +/** + * Should be used to make ICAP transfer + * + * @method transfer + * @param {String} iban number + * @param {String} from (address) + * @param {Value} value to be tranfered + * @param {Function} callback, callback + */ +var transfer = function (from, iban, value, callback) { + var icap = new ICAP(iban); + if (!icap.isValid()) { + throw new Error('invalid iban address'); + } + + if (icap.isDirect()) { + return transferToAddress(from, icap.address(), value, callback); + } + + if (!callback) { + var address = namereg.addr(icap.institution()); + return deposit(from, address, value, icap.client()); + } + + namereg.addr(icap.insitution(), function (err, address) { + return deposit(from, address, value, icap.client(), callback); + }); + +}; + +/** + * Should be used to transfer funds to certain address + * + * @method transferToAddress + * @param {String} address + * @param {String} from (address) + * @param {Value} value to be tranfered + * @param {Function} callback, callback + */ +var transferToAddress = function (from, address, value, callback) { + return web3.eth.sendTransaction({ + address: address, + from: from, + value: value + }, callback); +}; + +/** + * Should be used to deposit funds to generic Exchange contract (must implement deposit(bytes32) method!) + * + * @method deposit + * @param {String} address + * @param {String} from (address) + * @param {Value} value to be tranfered + * @param {String} client unique identifier + * @param {Function} callback, callback + */ +var deposit = function (from, address, value, client, callback) { + var abi = [{"constant":false,"inputs":[{"name":"name","type":"bytes32"}],"name":"deposit","outputs":[],"type":"function"}]; + return contract(abi).at(address).deposit(client, { + from: from, + value: value + }, callback); +}; + +module.exports = transfer; + + +},{"../web3":9,"./contract":11,"./icap":20,"./namereg":23}],30:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -3589,7 +4080,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({ @@ -3664,9 +4168,1384 @@ module.exports = { }; -},{"./method":21}],28:[function(require,module,exports){ +},{"./method":22}],31:[function(require,module,exports){ -},{}],"bignumber.js":[function(require,module,exports){ +},{}],32:[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; + +})); +},{}],33:[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":32,"./x64-core":34}],34:[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":32}],"bignumber.js":[function(require,module,exports){ /*! bignumber.js v2.0.7 https://github.com/MikeMcl/bignumber.js/LICENCE */ ;(function (global) { @@ -6351,12 +8230,13 @@ module.exports = { } })(this); -},{"crypto":28}],"web3":[function(require,module,exports){ +},{"crypto":31}],"web3":[function(require,module,exports){ 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'); +web3.eth.namereg = require('./lib/web3/namereg'); +web3.eth.sendIBANTransaction = require('./lib/web3/transfer'); // dont override global variable if (typeof window !== 'undefined' && typeof window.web3 === 'undefined') { @@ -6366,7 +8246,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/namereg":23,"./lib/web3/qtsync":26,"./lib/web3/transfer":29}]},{},["web3"]) //# sourceMappingURL=web3.js.map \ No newline at end of file diff --git a/package.json b/package.json index 2916ec2a0..8656baa75 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "matchdep": "^0.3.0", "read-yaml": "^1.0.0", "shelljs": "^0.5.0", - "web3": "^0.4.3", + "web3": "^0.5.0", "wrench": "^1.5.8" }, "author": "Iuri Matias ", diff --git a/tasks/deploy.coffee b/tasks/deploy.coffee index 946583762..f18cd2b6e 100644 --- a/tasks/deploy.coffee +++ b/tasks/deploy.coffee @@ -37,7 +37,7 @@ module.exports = (grunt) -> result += "var #{className}Abi = #{abi};" result += "var #{className}Contract = web3.eth.contract(#{className}Abi);" - result += "var #{className} = new #{className}Contract('#{contractAddress}');"; + result += "var #{className} = #{className}Contract.at('#{contractAddress}');"; else #for geth < 0.9.23 contract = compiled_contracts @@ -49,7 +49,7 @@ module.exports = (grunt) -> result += "var #{className}Abi = #{abi};" result += "var #{className}Contract = web3.eth.contract(#{className}Abi);" - result += "var #{className} = new #{className}Contract('#{contractAddress}');"; + result += "var #{className} = #{className}Contract.at('#{contractAddress}');"; destFile = grunt.config.get("deploy.dest") grunt.file.write(destFile, result)