From bf6ea2919dc424586eff00974b813bbbedcede9b Mon Sep 17 00:00:00 2001 From: Jeffrey Wilcke Date: Tue, 11 Aug 2015 17:17:20 +0200 Subject: [PATCH] web3: updated --- jsre/ethereum_js.go | 3075 +++++++++++++++++++++++++++++-------------- 1 file changed, 2122 insertions(+), 953 deletions(-) diff --git a/jsre/ethereum_js.go b/jsre/ethereum_js.go index 012e5af70..f33bb7c25 100644 --- a/jsre/ethereum_js.go +++ b/jsre/ethereum_js.go @@ -18,6 +18,622 @@ package jsre const Web3_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 64 || this.offset !== undefined; + return this.offset !== undefined; }; /** @@ -708,71 +1360,398 @@ SolidityParam.encodeList = function (params) { }, '')); }; -/** - * 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)); -}; -/** - * 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 - */ -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; - - var offset = getOffset(bytes, index); - - var l = parseInt('0x' + bytes.substr(offset * 2, 64)); - l = Math.floor((l + 31) / 32); - - // (1 + l) * , cause we also parse length - return new SolidityParam(bytes.substr(offset * 2, (1 + l) * 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; -},{"../utils/utils":7}],4:[function(require,module,exports){ +},{"../utils/utils":20}],12:[function(require,module,exports){ +var f = require('./formatters'); +var SolidityType = require('./type'); + +/** + * SolidityTypeReal is a prootype that represents real type + * It matches: + * real + * real[] + * real[4] + * real[][] + * real[3][] + * real[][6][], ... + * real32 + * real64[] + * real8[4] + * real256[][] + * real[3][] + * real64[][6][], ... + */ +var SolidityTypeReal = function () { + this._inputFormatter = f.formatInputReal; + this._outputFormatter = f.formatOutputReal; +}; + +SolidityTypeReal.prototype = new SolidityType({}); +SolidityTypeReal.prototype.constructor = SolidityTypeReal; + +SolidityTypeReal.prototype.isType = function (name) { + return !!name.match(/real([0-9]*)?(\[([0-9]*)\])?/); +}; + +SolidityTypeReal.prototype.staticPartLength = function (name) { + return 32 * this.staticArrayLength(name); +}; + +module.exports = SolidityTypeReal; + +},{"./formatters":9,"./type":14}],13:[function(require,module,exports){ +var f = require('./formatters'); +var SolidityType = require('./type'); + +var SolidityTypeString = function () { + this._inputFormatter = f.formatInputString; + this._outputFormatter = f.formatOutputString; +}; + +SolidityTypeString.prototype = new SolidityType({}); +SolidityTypeString.prototype.constructor = SolidityTypeString; + +SolidityTypeString.prototype.isType = function (name) { + return !!name.match(/^string(\[([0-9]*)\])*$/); +}; + +SolidityTypeString.prototype.staticPartLength = function (name) { + return 32 * this.staticArrayLength(name); +}; + +SolidityTypeString.prototype.isDynamicType = function () { + return true; +}; + +module.exports = SolidityTypeString; + + +},{"./formatters":9,"./type":14}],14:[function(require,module,exports){ +var f = require('./formatters'); +var SolidityParam = require('./param'); + +/** + * SolidityType prototype is used to encode/decode solidity params of certain type + */ +var SolidityType = function (config) { + this._inputFormatter = config.inputFormatter; + this._outputFormatter = config.outputFormatter; +}; + +/** + * Should be used to determine if this SolidityType do match given name + * + * @method isType + * @param {String} name + * @return {Bool} true if type match this SolidityType, otherwise false + */ +SolidityType.prototype.isType = function (name) { + throw "this method should be overrwritten for type " + name; +}; + +/** + * Should be used to determine what is the length of static part in given type + * + * @method staticPartLength + * @param {String} name + * @return {Number} length of static part in bytes + */ +SolidityType.prototype.staticPartLength = function (name) { + throw "this method should be overrwritten for type: " + name; +}; + +/** + * Should be used to determine if type is dynamic array + * eg: + * "type[]" => true + * "type[4]" => false + * + * @method isDynamicArray + * @param {String} name + * @return {Bool} true if the type is dynamic array + */ +SolidityType.prototype.isDynamicArray = function (name) { + var nestedTypes = this.nestedTypes(name); + return !!nestedTypes && !nestedTypes[nestedTypes.length - 1].match(/[0-9]{1,}/g); +}; + +/** + * Should be used to determine if type is static array + * eg: + * "type[]" => false + * "type[4]" => true + * + * @method isStaticArray + * @param {String} name + * @return {Bool} true if the type is static array + */ +SolidityType.prototype.isStaticArray = function (name) { + var nestedTypes = this.nestedTypes(name); + return !!nestedTypes && !!nestedTypes[nestedTypes.length - 1].match(/[0-9]{1,}/g); +}; + +/** + * Should return length of static array + * eg. + * "int[32]" => 32 + * "int256[14]" => 14 + * "int[2][3]" => 3 + * "int" => 1 + * "int[1]" => 1 + * "int[]" => 1 + * + * @method staticArrayLength + * @param {String} name + * @return {Number} static array length + */ +SolidityType.prototype.staticArrayLength = function (name) { + var nestedTypes = this.nestedTypes(name); + if (nestedTypes) { + return parseInt(nestedTypes[nestedTypes.length - 1].match(/[0-9]{1,}/g) || 1); + } + return 1; +}; + +/** + * Should return nested type + * eg. + * "int[32]" => "int" + * "int256[14]" => "int256" + * "int[2][3]" => "int[2]" + * "int" => "int" + * "int[]" => "int" + * + * @method nestedName + * @param {String} name + * @return {String} nested name + */ +SolidityType.prototype.nestedName = function (name) { + // remove last [] in name + var nestedTypes = this.nestedTypes(name); + if (!nestedTypes) { + return name; + } + + return name.substr(0, name.length - nestedTypes[nestedTypes.length - 1].length); +}; + +/** + * Should return true if type has dynamic size by default + * such types are "string", "bytes" + * + * @method isDynamicType + * @param {String} name + * @return {Bool} true if is dynamic, otherwise false + */ +SolidityType.prototype.isDynamicType = function () { + return false; +}; + +/** + * Should return array of nested types + * eg. + * "int[2][3][]" => ["[2]", "[3]", "[]"] + * "int[] => ["[]"] + * "int" => null + * + * @method nestedTypes + * @param {String} name + * @return {Array} array of nested types + */ +SolidityType.prototype.nestedTypes = function (name) { + // return list of strings eg. "[]", "[3]", "[]", "[2]" + return name.match(/(\[[0-9]*\])/g); +}; + +/** + * Should be used to encode the value + * + * @method encode + * @param {Object} value + * @param {String} name + * @return {String} encoded value + */ +SolidityType.prototype.encode = function (value, name) { + var self = this; + if (this.isDynamicArray(name)) { + + return (function () { + var length = value.length; // in int + var nestedName = self.nestedName(name); + + var result = []; + result.push(f.formatInputInt(length).encode()); + + value.forEach(function (v) { + result.push(self.encode(v, nestedName)); + }); + + return result; + })(); + + } else if (this.isStaticArray(name)) { + + return (function () { + var length = self.staticArrayLength(name); // in int + var nestedName = self.nestedName(name); + + var result = []; + for (var i = 0; i < length; i++) { + result.push(self.encode(value[i], nestedName)); + } + + return result; + })(); + + } + + return this._inputFormatter(value, name).encode(); +}; + +/** + * Should be used to decode value from bytes + * + * @method decode + * @param {String} bytes + * @param {Number} offset in bytes + * @param {String} name type name + * @returns {Object} decoded value + */ +SolidityType.prototype.decode = function (bytes, offset, name) { + var self = this; + + if (this.isDynamicArray(name)) { + + return (function () { + var arrayOffset = parseInt('0x' + bytes.substr(offset * 2, 64)); // in bytes + var length = parseInt('0x' + bytes.substr(arrayOffset * 2, 64)); // in int + var arrayStart = arrayOffset + 32; // array starts after length; // in bytes + + var nestedName = self.nestedName(name); + var nestedStaticPartLength = self.staticPartLength(nestedName); // in bytes + var result = []; + + for (var i = 0; i < length * nestedStaticPartLength; i += nestedStaticPartLength) { + result.push(self.decode(bytes, arrayStart + i, nestedName)); + } + + return result; + })(); + + } else if (this.isStaticArray(name)) { + + return (function () { + var length = self.staticArrayLength(name); // in int + var arrayStart = offset; // in bytes + + var nestedName = self.nestedName(name); + var nestedStaticPartLength = self.staticPartLength(nestedName); // in bytes + var result = []; + + for (var i = 0; i < length * nestedStaticPartLength; i += nestedStaticPartLength) { + result.push(self.decode(bytes, arrayStart + i, nestedName)); + } + + return result; + })(); + } else if (this.isDynamicType(name)) { + + return (function () { + var dynamicOffset = parseInt('0x' + bytes.substr(offset * 2, 64)); // in bytes + var length = parseInt('0x' + bytes.substr(dynamicOffset * 2, 64)); // in bytes + var roundedLength = Math.floor((length + 31) / 32); // in int + + return self._outputFormatter(new SolidityParam(bytes.substr(dynamicOffset * 2, ( 1 + roundedLength) * 64), 0)); + })(); + } + + var length = this.staticPartLength(name); + return this._outputFormatter(new SolidityParam(bytes.substr(offset * 2, length * 2))); +}; + +module.exports = SolidityType; + +},{"./formatters":9,"./param":11}],15:[function(require,module,exports){ +var f = require('./formatters'); +var SolidityType = require('./type'); + +/** + * SolidityTypeUInt is a prootype that represents uint type + * It matches: + * uint + * uint[] + * uint[4] + * uint[][] + * uint[3][] + * uint[][6][], ... + * uint32 + * uint64[] + * uint8[4] + * uint256[][] + * uint[3][] + * uint64[][6][], ... + */ +var SolidityTypeUInt = function () { + this._inputFormatter = f.formatInputInt; + this._outputFormatter = f.formatOutputInt; +}; + +SolidityTypeUInt.prototype = new SolidityType({}); +SolidityTypeUInt.prototype.constructor = SolidityTypeUInt; + +SolidityTypeUInt.prototype.isType = function (name) { + return !!name.match(/^uint([0-9]*)?(\[([0-9]*)\])*$/); +}; + +SolidityTypeUInt.prototype.staticPartLength = function (name) { + return 32 * this.staticArrayLength(name); +}; + +module.exports = SolidityTypeUInt; + +},{"./formatters":9,"./type":14}],16:[function(require,module,exports){ +var f = require('./formatters'); +var SolidityType = require('./type'); + +/** + * SolidityTypeUReal is a prootype that represents ureal type + * It matches: + * ureal + * ureal[] + * ureal[4] + * ureal[][] + * ureal[3][] + * ureal[][6][], ... + * ureal32 + * ureal64[] + * ureal8[4] + * ureal256[][] + * ureal[3][] + * ureal64[][6][], ... + */ +var SolidityTypeUReal = function () { + this._inputFormatter = f.formatInputReal; + this._outputFormatter = f.formatOutputUReal; +}; + +SolidityTypeUReal.prototype = new SolidityType({}); +SolidityTypeUReal.prototype.constructor = SolidityTypeUReal; + +SolidityTypeUReal.prototype.isType = function (name) { + return !!name.match(/^ureal([0-9]*)?(\[([0-9]*)\])*$/); +}; + +SolidityTypeUReal.prototype.staticPartLength = function (name) { + return 32 * this.staticArrayLength(name); +}; + +module.exports = SolidityTypeUReal; + +},{"./formatters":9,"./type":14}],17:[function(require,module,exports){ 'use strict'; // go env doesn't have and need XMLHttpRequest @@ -783,7 +1762,7 @@ if (typeof XMLHttpRequest === 'undefined') { } -},{}],5:[function(require,module,exports){ +},{}],18:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -819,6 +1798,7 @@ if (typeof XMLHttpRequest === 'undefined') { * @constructor */ + /// required to define ETH_BIGNUMBER_ROUNDING_MODE var BigNumber = require('bignumber.js'); @@ -863,7 +1843,7 @@ module.exports = { }; -},{"bignumber.js":"bignumber.js"}],6:[function(require,module,exports){ +},{"bignumber.js":"bignumber.js"}],19:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -886,6 +1866,7 @@ module.exports = { * @date 2015 */ + var utils = require('./utils'); var sha3 = require('crypto-js/sha3'); @@ -904,7 +1885,7 @@ module.exports = function (str, isNew) { }; -},{"./utils":7,"crypto-js/sha3":34}],7:[function(require,module,exports){ +},{"./utils":20,"crypto-js/sha3":47}],20:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -940,6 +1921,7 @@ module.exports = function (str, isNew) { * @constructor */ + var BigNumber = require('bignumber.js'); var unitMap = { @@ -1015,7 +1997,7 @@ var toAscii = function(hex) { str += String.fromCharCode(code); } - return decodeURIComponent(escape(str)); + return decodeURIComponent(escape(str)); // jshint ignore:line }; /** @@ -1026,7 +2008,7 @@ var toAscii = function(hex) { * @returns {String} hex representation of input string */ var toHexNative = function(str) { - str = unescape(encodeURIComponent(str)); + str = unescape(encodeURIComponent(str)); // jshint ignore:line var hex = ""; for(var i = 0; i < str.length; i++) { var n = str.charCodeAt(i).toString(16); @@ -1377,18 +2359,6 @@ 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, padRight: padRight, @@ -1413,17 +2383,16 @@ module.exports = { isObject: isObject, isBoolean: isBoolean, isArray: isArray, - isJson: isJson, - isIBAN: isIBAN + isJson: isJson }; -},{"bignumber.js":"bignumber.js"}],8:[function(require,module,exports){ +},{"bignumber.js":"bignumber.js"}],21:[function(require,module,exports){ module.exports={ - "version": "0.9.1" + "version": "0.12.1" } -},{}],9:[function(require,module,exports){ +},{}],22:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -1451,11 +2420,11 @@ module.exports={ */ var version = require('./version.json'); -var net = require('./web3/net'); -var eth = require('./web3/eth'); -var db = require('./web3/db'); -var shh = require('./web3/shh'); -var watches = require('./web3/watches'); +var net = require('./web3/methods/net'); +var eth = require('./web3/methods/eth'); +var db = require('./web3/methods/db'); +var shh = require('./web3/methods/shh'); +var watches = require('./web3/methods/watches'); var Filter = require('./web3/filter'); var utils = require('./utils/utils'); var formatters = require('./web3/formatters'); @@ -1600,7 +2569,7 @@ setupMethods(web3.shh, shh.methods); module.exports = web3; -},{"./utils/config":5,"./utils/sha3":6,"./utils/utils":7,"./version.json":8,"./web3/batch":11,"./web3/db":13,"./web3/eth":15,"./web3/filter":17,"./web3/formatters":18,"./web3/method":24,"./web3/net":26,"./web3/property":27,"./web3/requestmanager":28,"./web3/shh":29,"./web3/watches":31}],10:[function(require,module,exports){ +},{"./utils/config":18,"./utils/sha3":19,"./utils/utils":20,"./version.json":21,"./web3/batch":24,"./web3/filter":28,"./web3/formatters":29,"./web3/method":35,"./web3/methods/db":36,"./web3/methods/eth":37,"./web3/methods/net":38,"./web3/methods/shh":39,"./web3/methods/watches":40,"./web3/property":42,"./web3/requestmanager":43}],23:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -1628,7 +2597,7 @@ var SolidityEvent = require('./event'); var formatters = require('./formatters'); var utils = require('../utils/utils'); var Filter = require('./filter'); -var watches = require('./watches'); +var watches = require('./methods/watches'); var AllSolidityEvents = function (json, address) { this._json = json; @@ -1669,6 +2638,13 @@ AllSolidityEvents.prototype.decode = function (data) { }; AllSolidityEvents.prototype.execute = function (options, callback) { + + if (utils.isFunction(arguments[arguments.length - 1])) { + callback = arguments[arguments.length - 1]; + if(arguments.length === 1) + options = null; + } + var o = this.encode(options); var formatter = this.decode.bind(this); return new Filter(o, watches.eth(), formatter, callback); @@ -1682,7 +2658,7 @@ AllSolidityEvents.prototype.attachToContract = function (contract) { module.exports = AllSolidityEvents; -},{"../utils/sha3":6,"../utils/utils":7,"./event":16,"./filter":17,"./formatters":18,"./watches":31}],11:[function(require,module,exports){ +},{"../utils/sha3":19,"../utils/utils":20,"./event":27,"./filter":28,"./formatters":29,"./methods/watches":40}],24:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -1750,7 +2726,7 @@ Batch.prototype.execute = function () { module.exports = Batch; -},{"./errors":14,"./jsonrpc":23,"./requestmanager":28}],12:[function(require,module,exports){ +},{"./errors":26,"./jsonrpc":34,"./requestmanager":43}],25:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -2029,65 +3005,7 @@ var Contract = function (abi, address) { module.exports = contract; -},{"../solidity/coder":1,"../utils/utils":7,"../web3":9,"./allevents":10,"./event":16,"./function":19}],13:[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 db.js - * @authors: - * Marek Kotewicz - * @date 2015 - */ - -var Method = require('./method'); - -var putString = new Method({ - name: 'putString', - call: 'db_putString', - params: 3 -}); - - -var getString = new Method({ - name: 'getString', - call: 'db_getString', - params: 2 -}); - -var putHex = new Method({ - name: 'putHex', - call: 'db_putHex', - params: 3 -}); - -var getHex = new Method({ - name: 'getHex', - call: 'db_getHex', - params: 2 -}); - -var methods = [ - putString, getString, putHex, getHex -]; - -module.exports = { - methods: methods -}; - -},{"./method":24}],14:[function(require,module,exports){ +},{"../solidity/coder":7,"../utils/utils":20,"../web3":22,"./allevents":23,"./event":27,"./function":30}],26:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -2127,300 +3045,7 @@ module.exports = { }; -},{}],15:[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 eth.js - * @author Marek Kotewicz - * @author Fabian Vogelsteller - * @date 2015 - */ - -/** - * Web3 - * - * @module web3 - */ - -/** - * Eth methods and properties - * - * An example method object can look as follows: - * - * { - * name: 'getBlock', - * call: blockCall, - * params: 2, - * outputFormatter: formatters.outputBlockFormatter, - * inputFormatter: [ // can be a formatter funciton or an array of functions. Where each item in the array will be used for one parameter - * utils.toHex, // formats paramter 1 - * function(param){ return !!param; } // formats paramter 2 - * ] - * }, - * - * @class [web3] eth - * @constructor - */ - -"use strict"; - -var formatters = require('./formatters'); -var utils = require('../utils/utils'); -var Method = require('./method'); -var Property = require('./property'); - -var blockCall = function (args) { - return (utils.isString(args[0]) && args[0].indexOf('0x') === 0) ? "eth_getBlockByHash" : "eth_getBlockByNumber"; -}; - -var transactionFromBlockCall = function (args) { - return (utils.isString(args[0]) && args[0].indexOf('0x') === 0) ? 'eth_getTransactionByBlockHashAndIndex' : 'eth_getTransactionByBlockNumberAndIndex'; -}; - -var uncleCall = function (args) { - return (utils.isString(args[0]) && args[0].indexOf('0x') === 0) ? 'eth_getUncleByBlockHashAndIndex' : 'eth_getUncleByBlockNumberAndIndex'; -}; - -var getBlockTransactionCountCall = function (args) { - return (utils.isString(args[0]) && args[0].indexOf('0x') === 0) ? 'eth_getBlockTransactionCountByHash' : 'eth_getBlockTransactionCountByNumber'; -}; - -var uncleCountCall = function (args) { - return (utils.isString(args[0]) && args[0].indexOf('0x') === 0) ? 'eth_getUncleCountByBlockHash' : 'eth_getUncleCountByBlockNumber'; -}; - -/// @returns an array of objects describing web3.eth api methods - -var getBalance = new Method({ - name: 'getBalance', - call: 'eth_getBalance', - params: 2, - inputFormatter: [utils.toAddress, formatters.inputDefaultBlockNumberFormatter], - outputFormatter: formatters.outputBigNumberFormatter -}); - -var getStorageAt = new Method({ - name: 'getStorageAt', - call: 'eth_getStorageAt', - params: 3, - inputFormatter: [null, utils.toHex, formatters.inputDefaultBlockNumberFormatter] -}); - -var getCode = new Method({ - name: 'getCode', - call: 'eth_getCode', - params: 2, - inputFormatter: [utils.toAddress, formatters.inputDefaultBlockNumberFormatter] -}); - -var getBlock = new Method({ - name: 'getBlock', - call: blockCall, - params: 2, - inputFormatter: [formatters.inputBlockNumberFormatter, function (val) { return !!val; }], - outputFormatter: formatters.outputBlockFormatter -}); - -var getUncle = new Method({ - name: 'getUncle', - call: uncleCall, - params: 2, - inputFormatter: [formatters.inputBlockNumberFormatter, utils.toHex], - outputFormatter: formatters.outputBlockFormatter, - -}); - -var getCompilers = new Method({ - name: 'getCompilers', - call: 'eth_getCompilers', - params: 0 -}); - -var getBlockTransactionCount = new Method({ - name: 'getBlockTransactionCount', - call: getBlockTransactionCountCall, - params: 1, - inputFormatter: [formatters.inputBlockNumberFormatter], - outputFormatter: utils.toDecimal -}); - -var getBlockUncleCount = new Method({ - name: 'getBlockUncleCount', - call: uncleCountCall, - params: 1, - inputFormatter: [formatters.inputBlockNumberFormatter], - outputFormatter: utils.toDecimal -}); - -var getTransaction = new Method({ - name: 'getTransaction', - call: 'eth_getTransactionByHash', - params: 1, - outputFormatter: formatters.outputTransactionFormatter -}); - -var getTransactionFromBlock = new Method({ - name: 'getTransactionFromBlock', - call: transactionFromBlockCall, - params: 2, - inputFormatter: [formatters.inputBlockNumberFormatter, utils.toHex], - outputFormatter: formatters.outputTransactionFormatter -}); - -var getTransactionReceipt = new Method({ - name: 'getTransactionReceipt', - call: 'eth_getTransactionReceipt', - params: 1, - outputFormatter: formatters.outputTransactionReceiptFormatter -}); - -var getTransactionCount = new Method({ - name: 'getTransactionCount', - call: 'eth_getTransactionCount', - params: 2, - inputFormatter: [null, formatters.inputDefaultBlockNumberFormatter], - outputFormatter: utils.toDecimal -}); - -var sendRawTransaction = new Method({ - name: 'sendRawTransaction', - call: 'eth_sendRawTransaction', - params: 1, - inputFormatter: [null] -}); - -var sendTransaction = new Method({ - name: 'sendTransaction', - call: 'eth_sendTransaction', - params: 1, - inputFormatter: [formatters.inputTransactionFormatter] -}); - -var call = new Method({ - name: 'call', - call: 'eth_call', - params: 2, - 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', - params: 1 -}); - -var compileLLL = new Method({ - name: 'compile.lll', - call: 'eth_compileLLL', - params: 1 -}); - -var compileSerpent = new Method({ - name: 'compile.serpent', - call: 'eth_compileSerpent', - 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, - getCode, - getBlock, - getUncle, - getCompilers, - getBlockTransactionCount, - getBlockUncleCount, - getTransaction, - getTransactionFromBlock, - getTransactionReceipt, - getTransactionCount, - call, - estimateGas, - sendRawTransaction, - sendTransaction, - compileSolidity, - compileLLL, - compileSerpent, - submitWork, - getWork -]; - -/// @returns an array of objects describing web3.eth api properties - - - -var properties = [ - new Property({ - name: 'coinbase', - getter: 'eth_coinbase' - }), - new Property({ - name: 'mining', - getter: 'eth_mining' - }), - new Property({ - name: 'hashrate', - getter: 'eth_hashrate', - outputFormatter: utils.toDecimal - }), - new Property({ - name: 'gasPrice', - getter: 'eth_gasPrice', - outputFormatter: formatters.outputBigNumberFormatter - }), - new Property({ - name: 'accounts', - getter: 'eth_accounts' - }), - new Property({ - name: 'blockNumber', - getter: 'eth_blockNumber', - outputFormatter: utils.toDecimal - }) -]; - -module.exports = { - methods: methods, - properties: properties -}; - - -},{"../utils/utils":7,"./formatters":18,"./method":24,"./property":27}],16:[function(require,module,exports){ +},{}],27:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -2448,7 +3073,7 @@ var coder = require('../solidity/coder'); var formatters = require('./formatters'); var sha3 = require('../utils/sha3'); var Filter = require('./filter'); -var watches = require('./watches'); +var watches = require('./methods/watches'); /** * This prototype should be used to create event filters @@ -2629,7 +3254,7 @@ SolidityEvent.prototype.attachToContract = function (contract) { module.exports = SolidityEvent; -},{"../solidity/coder":1,"../utils/sha3":6,"../utils/utils":7,"./filter":17,"./formatters":18,"./watches":31}],17:[function(require,module,exports){ +},{"../solidity/coder":7,"../utils/sha3":19,"../utils/utils":20,"./filter":28,"./formatters":29,"./methods/watches":40}],28:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -2795,6 +3420,7 @@ var Filter = function (options, methods, formatter, callback) { } }); + return this; }; Filter.prototype.watch = function (callback) { @@ -2840,7 +3466,7 @@ Filter.prototype.get = function (callback) { module.exports = Filter; -},{"../utils/utils":7,"./formatters":18,"./requestmanager":28}],18:[function(require,module,exports){ +},{"../utils/utils":20,"./formatters":29,"./requestmanager":43}],29:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -2866,6 +3492,7 @@ module.exports = Filter; var utils = require('../utils/utils'); var config = require('../utils/config'); +var Iban = require('./iban'); /** * Should the format output to a big number @@ -2898,6 +3525,34 @@ var inputBlockNumberFormatter = function (blockNumber) { return utils.toHex(blockNumber); }; +/** + * Formats the input of a transaction and converts all values to HEX + * + * @method inputCallFormatter + * @param {Object} transaction options + * @returns object +*/ +var inputCallFormatter = function (options){ + + options.from = options.from || config.defaultAccount; + + if (options.from) { + options.from = inputAddressFormatter(options.from); + } + + if (options.to) { // it might be contract creation + options.to = inputAddressFormatter(options.to); + } + + ['gasPrice', 'gas', 'value', 'nonce'].filter(function (key) { + return options[key] !== undefined; + }).forEach(function(key){ + options[key] = utils.fromDecimal(options[key]); + }); + + return options; +}; + /** * Formats the input of a transaction and converts all values to HEX * @@ -2908,11 +3563,10 @@ var inputBlockNumberFormatter = function (blockNumber) { var inputTransactionFormatter = function (options){ options.from = options.from || config.defaultAccount; + options.from = inputAddressFormatter(options.from); - // make code -> data - if (options.code) { - options.data = options.code; - delete options.code; + if (options.to) { // it might be contract creation + options.to = inputAddressFormatter(options.to); } ['gasPrice', 'gas', 'value', 'nonce'].filter(function (key) { @@ -3073,10 +3727,24 @@ var outputPostFormatter = function(post){ return post; }; +var inputAddressFormatter = function (address) { + var iban = new Iban(address); + if (iban.isValid() && iban.isDirect()) { + return '0x' + iban.address(); + } else if (utils.isStrictAddress(address)) { + return address; + } else if (utils.isAddress(address)) { + return '0x' + address; + } + throw 'invalid address'; +}; + module.exports = { inputDefaultBlockNumberFormatter: inputDefaultBlockNumberFormatter, inputBlockNumberFormatter: inputBlockNumberFormatter, + inputCallFormatter: inputCallFormatter, inputTransactionFormatter: inputTransactionFormatter, + inputAddressFormatter: inputAddressFormatter, inputPostFormatter: inputPostFormatter, outputBigNumberFormatter: outputBigNumberFormatter, outputTransactionFormatter: outputTransactionFormatter, @@ -3087,7 +3755,7 @@ module.exports = { }; -},{"../utils/config":5,"../utils/utils":7}],19:[function(require,module,exports){ +},{"../utils/config":18,"../utils/utils":20,"./iban":32}],30:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -3324,7 +3992,7 @@ SolidityFunction.prototype.attachToContract = function (contract) { module.exports = SolidityFunction; -},{"../solidity/coder":1,"../utils/sha3":6,"../utils/utils":7,"../web3":9,"./formatters":18}],20:[function(require,module,exports){ +},{"../solidity/coder":7,"../utils/sha3":19,"../utils/utils":20,"../web3":22,"./formatters":29}],31:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -3351,51 +4019,61 @@ module.exports = SolidityFunction; "use strict"; -var XMLHttpRequest = (typeof window !== 'undefined' && window.XMLHttpRequest) ? window.XMLHttpRequest : require('xmlhttprequest').XMLHttpRequest; // jshint ignore:line var errors = require('./errors'); +// workaround to use httpprovider in different envs +var XMLHttpRequest; // jshint ignore: line + +// meteor server environment +if (typeof Meteor !== 'undefined' && Meteor.isServer) { // jshint ignore: line + XMLHttpRequest = Npm.require('xmlhttprequest').XMLHttpRequest; // jshint ignore: line + +// browser +} else if (typeof window !== 'undefined' && window.XMLHttpRequest) { + XMLHttpRequest = window.XMLHttpRequest; // jshint ignore: line + +// node +} else { + XMLHttpRequest = require('xmlhttprequest').XMLHttpRequest; // jshint ignore: line +} + +/** + * HttpProvider should be used to send rpc calls over http + */ var HttpProvider = function (host) { this.host = host || 'http://localhost:8545'; }; -HttpProvider.prototype.isConnected = function() { +/** + * Should be called to prepare new XMLHttpRequest + * + * @method prepareRequest + * @param {Boolean} true if request should be async + * @return {XMLHttpRequest} object + */ +HttpProvider.prototype.prepareRequest = function (async) { var request = new XMLHttpRequest(); - - request.open('POST', this.host, false); - request.setRequestHeader('Content-type','application/json'); - - try { - request.send(JSON.stringify({ - id: 9999999999, - jsonrpc: '2.0', - method: 'net_listening', - params: [] - })); - return true; - } catch(e) { - return false; - } + request.open('POST', this.host, async); + request.setRequestHeader('Content-Type','application/json'); + return request; }; +/** + * Should be called to make sync request + * + * @method send + * @param {Object} payload + * @return {Object} result + */ HttpProvider.prototype.send = function (payload) { - var request = new XMLHttpRequest(); + var request = this.prepareRequest(false); - request.open('POST', this.host, false); - request.setRequestHeader('Content-type','application/json'); - try { request.send(JSON.stringify(payload)); } catch(error) { throw errors.InvalidConnection(this.host); } - - // check request.status - // TODO: throw an error here! it cannot silently fail!!! - //if (request.status !== 200) { - //return; - //} - var result = request.responseText; try { @@ -3407,8 +4085,16 @@ HttpProvider.prototype.send = function (payload) { return result; }; +/** + * Should be used to make async request + * + * @method sendAsync + * @param {Object} payload + * @param {Function} callback triggered on end with (err, result) + */ HttpProvider.prototype.sendAsync = function (payload, callback) { - var request = new XMLHttpRequest(); + var request = this.prepareRequest(true); + request.onreadystatechange = function() { if (request.readyState === 4) { var result = request.responseText; @@ -3423,9 +4109,6 @@ HttpProvider.prototype.sendAsync = function (payload, callback) { callback(error, result); } }; - - request.open('POST', this.host, true); - request.setRequestHeader('Content-type','application/json'); try { request.send(JSON.stringify(payload)); @@ -3434,10 +4117,30 @@ HttpProvider.prototype.sendAsync = function (payload, callback) { } }; +/** + * Synchronously tries to make Http request + * + * @method isConnected + * @return {Boolean} returns true if request haven't failed. Otherwise false + */ +HttpProvider.prototype.isConnected = function() { + try { + this.send({ + id: 9999999999, + jsonrpc: '2.0', + method: 'net_listening', + params: [] + }); + return true; + } catch(e) { + return false; + } +}; + module.exports = HttpProvider; -},{"./errors":14,"xmlhttprequest":4}],21:[function(require,module,exports){ +},{"./errors":26,"xmlhttprequest":17}],32:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -3455,30 +4158,139 @@ module.exports = HttpProvider; along with ethereum.js. If not, see . */ /** - * @file icap.js + * @file iban.js * @author Marek Kotewicz * @date 2015 */ -var utils = require('../utils/utils'); +var BigNumber = require('bignumber.js'); + +var padLeft = function (string, bytes) { + var result = string; + while (result.length < bytes * 2) { + result = '00' + result; + } + return result; +}; /** - * This prototype should be used to extract necessary information from iban address + * Prepare an IBAN for mod 97 computation by moving the first 4 chars to the end and transforming the letters to + * numbers (A = 10, B = 11, ..., Z = 35), as specified in ISO13616. + * + * @method iso13616Prepare + * @param {String} iban the IBAN + * @returns {String} the prepared IBAN + */ +var iso13616Prepare = function (iban) { + var A = 'A'.charCodeAt(0); + var Z = 'Z'.charCodeAt(0); + + iban = iban.toUpperCase(); + iban = iban.substr(4) + iban.substr(0,4); + + return iban.split('').map(function(n){ + var code = n.charCodeAt(0); + if (code >= A && code <= Z){ + // A = 10, B = 11, ... Z = 35 + return code - A + 10; + } else { + return n; + } + }).join(''); +}; + +/** + * Calculates the MOD 97 10 of the passed IBAN as specified in ISO7064. + * + * @method mod9710 + * @param {String} iban + * @returns {Number} + */ +var mod9710 = function (iban) { + var remainder = iban, + block; + + while (remainder.length > 2){ + block = remainder.slice(0, 9); + remainder = parseInt(block, 10) % 97 + remainder.slice(block.length); + } + + return parseInt(remainder, 10) % 97; +}; + +/** + * This prototype should be used to create iban object from iban correct string * * @param {String} iban */ -var ICAP = function (iban) { +var Iban = function (iban) { this._iban = iban; }; /** - * Should be called to check if icap is correct + * This method should be used to create iban object from ethereum address + * + * @method fromAddress + * @param {String} address + * @return {Iban} the IBAN object + */ +Iban.fromAddress = function (address) { + var asBn = new BigNumber(address, 16); + var base36 = asBn.toString(36); + var padded = padLeft(base36, 15); + return Iban.fromBban(padded.toUpperCase()); +}; + +/** + * Convert the passed BBAN to an IBAN for this country specification. + * Please note that "generation of the IBAN shall be the exclusive responsibility of the bank/branch servicing the account". + * This method implements the preferred algorithm described in http://en.wikipedia.org/wiki/International_Bank_Account_Number#Generating_IBAN_check_digits + * + * @method fromBban + * @param {String} bban the BBAN to convert to IBAN + * @returns {Iban} the IBAN object + */ +Iban.fromBban = function (bban) { + var countryCode = 'XE'; + + var remainder = mod9710(iso13616Prepare(countryCode + '00' + bban)); + var checkDigit = ('0' + (98 - remainder)).slice(-2); + + return new Iban(countryCode + checkDigit + bban); +}; + +/** + * Should be used to create IBAN object for given institution and identifier + * + * @method createIndirect + * @param {Object} options, required options are "institution" and "identifier" + * @return {Iban} the IBAN object + */ +Iban.createIndirect = function (options) { + return Iban.fromBban('ETH' + options.institution + options.identifier); +}; + +/** + * Thos method should be used to check if given string is valid iban object + * + * @method isValid + * @param {String} iban string + * @return {Boolean} true if it is valid IBAN + */ +Iban.isValid = function (iban) { + var i = new Iban(iban); + return i.isValid(); +}; + +/** + * Should be called to check if iban is correct * * @method isValid * @returns {Boolean} true if it is, otherwise false */ -ICAP.prototype.isValid = function () { - return utils.isIBAN(this._iban); +Iban.prototype.isValid = function () { + return /^XE[0-9]{2}(ETH[0-9A-Z]{13}|[0-9A-Z]{30})$/.test(this._iban) && + mod9710(iso13616Prepare(this._iban)) === 1; }; /** @@ -3487,8 +4299,8 @@ ICAP.prototype.isValid = function () { * @method isDirect * @returns {Boolean} true if it is, otherwise false */ -ICAP.prototype.isDirect = function () { - return this._iban.length === 34; +Iban.prototype.isDirect = function () { + return this._iban.length === 34 || this._iban.length === 35; }; /** @@ -3497,7 +4309,7 @@ ICAP.prototype.isDirect = function () { * @method isIndirect * @returns {Boolean} true if it is, otherwise false */ -ICAP.prototype.isIndirect = function () { +Iban.prototype.isIndirect = function () { return this._iban.length === 20; }; @@ -3508,7 +4320,7 @@ ICAP.prototype.isIndirect = function () { * @method checksum * @returns {String} checksum */ -ICAP.prototype.checksum = function () { +Iban.prototype.checksum = function () { return this._iban.substr(2, 2); }; @@ -3519,7 +4331,7 @@ ICAP.prototype.checksum = function () { * @method institution * @returns {String} institution identifier */ -ICAP.prototype.institution = function () { +Iban.prototype.institution = function () { return this.isIndirect() ? this._iban.substr(7, 4) : ''; }; @@ -3530,7 +4342,7 @@ ICAP.prototype.institution = function () { * @method client * @returns {String} client identifier */ -ICAP.prototype.client = function () { +Iban.prototype.client = function () { return this.isIndirect() ? this._iban.substr(11) : ''; }; @@ -3540,14 +4352,24 @@ ICAP.prototype.client = function () { * @method address * @returns {String} client direct address */ -ICAP.prototype.address = function () { - return this.isDirect() ? this._iban.substr(4) : ''; +Iban.prototype.address = function () { + if (this.isDirect()) { + var base36 = this._iban.substr(4); + var asBn = new BigNumber(base36, 36); + return padLeft(asBn.toString(16), 20); + } + + return ''; }; -module.exports = ICAP; +Iban.prototype.toString = function () { + return this._iban; +}; + +module.exports = Iban; -},{"../utils/utils":7}],22:[function(require,module,exports){ +},{"bignumber.js":"bignumber.js"}],33:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -3575,16 +4397,23 @@ module.exports = ICAP; var utils = require('../utils/utils'); var errors = require('./errors'); -var errorTimeout = '{"jsonrpc": "2.0", "error": {"code": -32603, "message": "IPC Request timed out for method \'__method__\'"}, "id": "__id__"}'; - +var errorTimeout = function (method, id) { + var err = { + "jsonrpc": "2.0", + "error": { + "code": -32603, + "message": "IPC Request timed out for method \'" + method + "\'" + }, + "id": id + }; + return JSON.stringify(err); +}; var IpcProvider = function (path, net) { var _this = this; this.responseCallbacks = {}; this.path = path; - net = net || require('net'); - this.connection = net.connect({path: this.path}); this.connection.on('error', function(e){ @@ -3701,7 +4530,7 @@ Timeout all requests when the end/error event is fired IpcProvider.prototype._timeout = function() { for(var key in this.responseCallbacks) { if(this.responseCallbacks.hasOwnProperty(key)){ - this.responseCallbacks[key](errorTimeout.replace('__id__', key).replace('__method__', this.responseCallbacks[key].method)); + this.responseCallbacks[key](errorTimeout(this.responseCallbacks[key].method, key)); delete this.responseCallbacks[key]; } } @@ -3760,7 +4589,7 @@ IpcProvider.prototype.sendAsync = function (payload, callback) { module.exports = IpcProvider; -},{"../utils/utils":7,"./errors":14,"net":32}],23:[function(require,module,exports){ +},{"../utils/utils":20,"./errors":26}],34:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -3853,7 +4682,7 @@ Jsonrpc.prototype.toBatchPayload = function (messages) { module.exports = Jsonrpc; -},{}],24:[function(require,module,exports){ +},{}],35:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -4027,7 +4856,7 @@ Method.prototype.send = function () { module.exports = Method; -},{"../utils/utils":7,"./errors":14,"./requestmanager":28}],25:[function(require,module,exports){ +},{"../utils/utils":20,"./errors":26,"./requestmanager":43}],36:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -4044,38 +4873,341 @@ module.exports = Method; 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 +/** @file db.js + * @authors: + * Marek Kotewicz * @date 2015 */ -var contract = require('./contract'); +var Method = require('../method'); -var address = '0xc6d9d2cd449a754c494264e1809c50e34d64562b'; +var putString = new Method({ + name: 'putString', + call: 'db_putString', + params: 3 +}); -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"} + +var getString = new Method({ + name: 'getString', + call: 'db_getString', + params: 2 +}); + +var putHex = new Method({ + name: 'putHex', + call: 'db_putHex', + params: 3 +}); + +var getHex = new Method({ + name: 'getHex', + call: 'db_getHex', + params: 2 +}); + +var methods = [ + putString, getString, putHex, getHex ]; -module.exports = contract(abi).at(address); +module.exports = { + methods: methods +}; + +},{"../method":35}],37:[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 eth.js + * @author Marek Kotewicz + * @author Fabian Vogelsteller + * @date 2015 + */ + +/** + * Web3 + * + * @module web3 + */ + +/** + * Eth methods and properties + * + * An example method object can look as follows: + * + * { + * name: 'getBlock', + * call: blockCall, + * params: 2, + * outputFormatter: formatters.outputBlockFormatter, + * inputFormatter: [ // can be a formatter funciton or an array of functions. Where each item in the array will be used for one parameter + * utils.toHex, // formats paramter 1 + * function(param){ return !!param; } // formats paramter 2 + * ] + * }, + * + * @class [web3] eth + * @constructor + */ + +"use strict"; + +var formatters = require('../formatters'); +var utils = require('../../utils/utils'); +var Method = require('../method'); +var Property = require('../property'); + +var blockCall = function (args) { + return (utils.isString(args[0]) && args[0].indexOf('0x') === 0) ? "eth_getBlockByHash" : "eth_getBlockByNumber"; +}; + +var transactionFromBlockCall = function (args) { + return (utils.isString(args[0]) && args[0].indexOf('0x') === 0) ? 'eth_getTransactionByBlockHashAndIndex' : 'eth_getTransactionByBlockNumberAndIndex'; +}; + +var uncleCall = function (args) { + return (utils.isString(args[0]) && args[0].indexOf('0x') === 0) ? 'eth_getUncleByBlockHashAndIndex' : 'eth_getUncleByBlockNumberAndIndex'; +}; + +var getBlockTransactionCountCall = function (args) { + return (utils.isString(args[0]) && args[0].indexOf('0x') === 0) ? 'eth_getBlockTransactionCountByHash' : 'eth_getBlockTransactionCountByNumber'; +}; + +var uncleCountCall = function (args) { + return (utils.isString(args[0]) && args[0].indexOf('0x') === 0) ? 'eth_getUncleCountByBlockHash' : 'eth_getUncleCountByBlockNumber'; +}; + +/// @returns an array of objects describing web3.eth api methods + +var getBalance = new Method({ + name: 'getBalance', + call: 'eth_getBalance', + params: 2, + inputFormatter: [formatters.inputAddressFormatter, formatters.inputDefaultBlockNumberFormatter], + outputFormatter: formatters.outputBigNumberFormatter +}); + +var getStorageAt = new Method({ + name: 'getStorageAt', + call: 'eth_getStorageAt', + params: 3, + inputFormatter: [null, utils.toHex, formatters.inputDefaultBlockNumberFormatter] +}); + +var getCode = new Method({ + name: 'getCode', + call: 'eth_getCode', + params: 2, + inputFormatter: [formatters.inputAddressFormatter, formatters.inputDefaultBlockNumberFormatter] +}); + +var getBlock = new Method({ + name: 'getBlock', + call: blockCall, + params: 2, + inputFormatter: [formatters.inputBlockNumberFormatter, function (val) { return !!val; }], + outputFormatter: formatters.outputBlockFormatter +}); + +var getUncle = new Method({ + name: 'getUncle', + call: uncleCall, + params: 2, + inputFormatter: [formatters.inputBlockNumberFormatter, utils.toHex], + outputFormatter: formatters.outputBlockFormatter, + +}); + +var getCompilers = new Method({ + name: 'getCompilers', + call: 'eth_getCompilers', + params: 0 +}); + +var getBlockTransactionCount = new Method({ + name: 'getBlockTransactionCount', + call: getBlockTransactionCountCall, + params: 1, + inputFormatter: [formatters.inputBlockNumberFormatter], + outputFormatter: utils.toDecimal +}); + +var getBlockUncleCount = new Method({ + name: 'getBlockUncleCount', + call: uncleCountCall, + params: 1, + inputFormatter: [formatters.inputBlockNumberFormatter], + outputFormatter: utils.toDecimal +}); + +var getTransaction = new Method({ + name: 'getTransaction', + call: 'eth_getTransactionByHash', + params: 1, + outputFormatter: formatters.outputTransactionFormatter +}); + +var getTransactionFromBlock = new Method({ + name: 'getTransactionFromBlock', + call: transactionFromBlockCall, + params: 2, + inputFormatter: [formatters.inputBlockNumberFormatter, utils.toHex], + outputFormatter: formatters.outputTransactionFormatter +}); + +var getTransactionReceipt = new Method({ + name: 'getTransactionReceipt', + call: 'eth_getTransactionReceipt', + params: 1, + outputFormatter: formatters.outputTransactionReceiptFormatter +}); + +var getTransactionCount = new Method({ + name: 'getTransactionCount', + call: 'eth_getTransactionCount', + params: 2, + inputFormatter: [null, formatters.inputDefaultBlockNumberFormatter], + outputFormatter: utils.toDecimal +}); + +var sendRawTransaction = new Method({ + name: 'sendRawTransaction', + call: 'eth_sendRawTransaction', + params: 1, + inputFormatter: [null] +}); + +var sendTransaction = new Method({ + name: 'sendTransaction', + call: 'eth_sendTransaction', + params: 1, + inputFormatter: [formatters.inputTransactionFormatter] +}); + +var call = new Method({ + name: 'call', + call: 'eth_call', + params: 2, + inputFormatter: [formatters.inputCallFormatter, formatters.inputDefaultBlockNumberFormatter] +}); + +var estimateGas = new Method({ + name: 'estimateGas', + call: 'eth_estimateGas', + params: 1, + inputFormatter: [formatters.inputCallFormatter], + outputFormatter: utils.toDecimal +}); + +var compileSolidity = new Method({ + name: 'compile.solidity', + call: 'eth_compileSolidity', + params: 1 +}); + +var compileLLL = new Method({ + name: 'compile.lll', + call: 'eth_compileLLL', + params: 1 +}); + +var compileSerpent = new Method({ + name: 'compile.serpent', + call: 'eth_compileSerpent', + 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, + getCode, + getBlock, + getUncle, + getCompilers, + getBlockTransactionCount, + getBlockUncleCount, + getTransaction, + getTransactionFromBlock, + getTransactionReceipt, + getTransactionCount, + call, + estimateGas, + sendRawTransaction, + sendTransaction, + compileSolidity, + compileLLL, + compileSerpent, + submitWork, + getWork +]; + +/// @returns an array of objects describing web3.eth api properties -},{"./contract":12}],26:[function(require,module,exports){ + +var properties = [ + new Property({ + name: 'coinbase', + getter: 'eth_coinbase' + }), + new Property({ + name: 'mining', + getter: 'eth_mining' + }), + new Property({ + name: 'hashrate', + getter: 'eth_hashrate', + outputFormatter: utils.toDecimal + }), + new Property({ + name: 'gasPrice', + getter: 'eth_gasPrice', + outputFormatter: formatters.outputBigNumberFormatter + }), + new Property({ + name: 'accounts', + getter: 'eth_accounts' + }), + new Property({ + name: 'blockNumber', + getter: 'eth_blockNumber', + outputFormatter: utils.toDecimal + }) +]; + +module.exports = { + methods: methods, + properties: properties +}; + + +},{"../../utils/utils":20,"../formatters":29,"../method":35,"../property":42}],38:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -4098,8 +5230,8 @@ module.exports = contract(abi).at(address); * @date 2015 */ -var utils = require('../utils/utils'); -var Property = require('./property'); +var utils = require('../../utils/utils'); +var Property = require('../property'); /// @returns an array of objects describing web3.eth api methods var methods = [ @@ -4125,7 +5257,229 @@ module.exports = { }; -},{"../utils/utils":7,"./property":27}],27:[function(require,module,exports){ +},{"../../utils/utils":20,"../property":42}],39:[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 shh.js + * @authors: + * Marek Kotewicz + * @date 2015 + */ + +var Method = require('../method'); +var formatters = require('../formatters'); + +var post = new Method({ + name: 'post', + call: 'shh_post', + params: 1, + inputFormatter: [formatters.inputPostFormatter] +}); + +var newIdentity = new Method({ + name: 'newIdentity', + call: 'shh_newIdentity', + params: 0 +}); + +var hasIdentity = new Method({ + name: 'hasIdentity', + call: 'shh_hasIdentity', + params: 1 +}); + +var newGroup = new Method({ + name: 'newGroup', + call: 'shh_newGroup', + params: 0 +}); + +var addToGroup = new Method({ + name: 'addToGroup', + call: 'shh_addToGroup', + params: 0 +}); + +var methods = [ + post, + newIdentity, + hasIdentity, + newGroup, + addToGroup +]; + +module.exports = { + methods: methods +}; + + +},{"../formatters":29,"../method":35}],40:[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 watches.js + * @authors: + * Marek Kotewicz + * @date 2015 + */ + +var Method = require('../method'); + +/// @returns an array of objects describing web3.eth.filter api methods +var eth = function () { + var newFilterCall = function (args) { + var type = args[0]; + + switch(type) { + case 'latest': + args.shift(); + this.params = 0; + return 'eth_newBlockFilter'; + case 'pending': + args.shift(); + this.params = 0; + return 'eth_newPendingTransactionFilter'; + default: + return 'eth_newFilter'; + } + }; + + var newFilter = new Method({ + name: 'newFilter', + call: newFilterCall, + params: 1 + }); + + var uninstallFilter = new Method({ + name: 'uninstallFilter', + call: 'eth_uninstallFilter', + params: 1 + }); + + var getLogs = new Method({ + name: 'getLogs', + call: 'eth_getFilterLogs', + params: 1 + }); + + var poll = new Method({ + name: 'poll', + call: 'eth_getFilterChanges', + params: 1 + }); + + return [ + newFilter, + uninstallFilter, + getLogs, + poll + ]; +}; + +/// @returns an array of objects describing web3.shh.watch api methods +var shh = function () { + var newFilter = new Method({ + name: 'newFilter', + call: 'shh_newFilter', + params: 1 + }); + + var uninstallFilter = new Method({ + name: 'uninstallFilter', + call: 'shh_uninstallFilter', + params: 1 + }); + + var getLogs = new Method({ + name: 'getLogs', + call: 'shh_getMessages', + params: 1 + }); + + var poll = new Method({ + name: 'poll', + call: 'shh_getFilterChanges', + params: 1 + }); + + return [ + newFilter, + uninstallFilter, + getLogs, + poll + ]; +}; + +module.exports = { + eth: eth, + shh: shh +}; + + +},{"../method":35}],41:[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 globalRegistrarAbi = require('../contracts/GlobalRegistrar.json'); +var icapRegistrarAbi= require('../contracts/ICAPRegistrar.json'); + +var globalNameregAddress = '0xc6d9d2cd449a754c494264e1809c50e34d64562b'; +var ibanNameregAddress = '0xa1a111bc074c9cfa781f0c38e63bd51c91b8af00'; + +module.exports = { + namereg: contract(globalRegistrarAbi).at(globalNameregAddress), + ibanNamereg: contract(icapRegistrarAbi).at(ibanNameregAddress) +}; + + +},{"../contracts/GlobalRegistrar.json":1,"../contracts/ICAPRegistrar.json":2,"./contract":25}],42:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -4277,7 +5631,7 @@ Property.prototype.request = function () { module.exports = Property; -},{"../utils/utils":7,"./requestmanager":28}],28:[function(require,module,exports){ +},{"../utils/utils":20,"./requestmanager":43}],43:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -4427,8 +5781,6 @@ RequestManager.prototype.setProvider = function (p) { } }; -/*jshint maxparams:4 */ - /** * Should be used to start polling * @@ -4441,9 +5793,8 @@ RequestManager.prototype.setProvider = function (p) { * @todo cleanup number of params */ RequestManager.prototype.startPolling = function (data, pollId, callback, uninstall) { - this.polls['poll_'+ pollId] = {data: data, id: pollId, callback: callback, uninstall: uninstall}; + this.polls[pollId] = {data: data, id: pollId, callback: callback, uninstall: uninstall}; }; -/*jshint maxparams:3 */ /** * Should be used to stop polling for filter with given id @@ -4452,7 +5803,7 @@ RequestManager.prototype.startPolling = function (data, pollId, callback, uninst * @param {Number} pollId */ RequestManager.prototype.stopPolling = function (pollId) { - delete this.polls['poll_'+ pollId]; + delete this.polls[pollId]; }; /** @@ -4542,77 +5893,7 @@ RequestManager.prototype.poll = function () { module.exports = RequestManager; -},{"../utils/config":5,"../utils/utils":7,"./errors":14,"./jsonrpc":23}],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 shh.js - * @authors: - * Marek Kotewicz - * @date 2015 - */ - -var Method = require('./method'); -var formatters = require('./formatters'); - -var post = new Method({ - name: 'post', - call: 'shh_post', - params: 1, - inputFormatter: [formatters.inputPostFormatter] -}); - -var newIdentity = new Method({ - name: 'newIdentity', - call: 'shh_newIdentity', - params: 0 -}); - -var hasIdentity = new Method({ - name: 'hasIdentity', - call: 'shh_hasIdentity', - params: 1 -}); - -var newGroup = new Method({ - name: 'newGroup', - call: 'shh_newGroup', - params: 0 -}); - -var addToGroup = new Method({ - name: 'addToGroup', - call: 'shh_addToGroup', - params: 0 -}); - -var methods = [ - post, - newIdentity, - hasIdentity, - newGroup, - addToGroup -]; - -module.exports = { - methods: methods -}; - - -},{"./formatters":18,"./method":24}],30:[function(require,module,exports){ +},{"../utils/config":18,"../utils/utils":20,"./errors":26,"./jsonrpc":34}],44:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -4636,36 +5917,37 @@ module.exports = { */ var web3 = require('../web3'); -var ICAP = require('./icap'); -var namereg = require('./namereg'); +var Iban = require('./iban'); +var namereg = require('./namereg').ibanNamereg; var contract = require('./contract'); +var exchangeAbi = require('../contracts/SmartExchange.json'); /** - * Should be used to make ICAP transfer + * Should be used to make Iban transfer * * @method transfer - * @param {String} iban number - * @param {String} from (address) + * @param {String} from + * @param {String} to iban * @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()) { +var transfer = function (from, to, value, callback) { + var iban = new Iban(to); + if (!iban.isValid()) { throw new Error('invalid iban address'); } - if (icap.isDirect()) { - return transferToAddress(from, icap.address(), value, callback); + if (iban.isDirect()) { + return transferToAddress(from, iban.address(), value, callback); } if (!callback) { - var address = namereg.addr(icap.institution()); - return deposit(from, address, value, icap.client()); + var address = namereg.addr(iban.institution()); + return deposit(from, address, value, iban.client()); } - namereg.addr(icap.insitution(), function (err, address) { - return deposit(from, address, value, icap.client(), callback); + namereg.addr(iban.institution(), function (err, address) { + return deposit(from, address, value, iban.client(), callback); }); }; @@ -4674,14 +5956,14 @@ var transfer = function (from, iban, value, callback) { * Should be used to transfer funds to certain address * * @method transferToAddress - * @param {String} address - * @param {String} from (address) + * @param {String} from + * @param {String} to * @param {Value} value to be tranfered * @param {Function} callback, callback */ -var transferToAddress = function (from, address, value, callback) { +var transferToAddress = function (from, to, value, callback) { return web3.eth.sendTransaction({ - address: address, + address: to, from: from, value: value }, callback); @@ -4691,15 +5973,15 @@ var transferToAddress = function (from, address, 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} from + * @param {String} to + * @param {Value} value to be transfered * @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, { +var deposit = function (from, to, value, client, callback) { + var abi = exchangeAbi; + return contract(abi).at(to).deposit(client, { from: from, value: value }, callback); @@ -4708,125 +5990,9 @@ var deposit = function (from, address, value, client, callback) { module.exports = transfer; -},{"../web3":9,"./contract":12,"./icap":21,"./namereg":25}],31:[function(require,module,exports){ -/* - This file is part of ethereum.js. +},{"../contracts/SmartExchange.json":3,"../web3":22,"./contract":25,"./iban":32,"./namereg":41}],45:[function(require,module,exports){ - 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 watches.js - * @authors: - * Marek Kotewicz - * @date 2015 - */ - -var Method = require('./method'); - -/// @returns an array of objects describing web3.eth.filter api methods -var eth = function () { - var newFilterCall = function (args) { - var type = args[0]; - - switch(type) { - case 'latest': - args.shift(); - this.params = 0; - return 'eth_newBlockFilter'; - case 'pending': - args.shift(); - this.params = 0; - return 'eth_newPendingTransactionFilter'; - default: - return 'eth_newFilter'; - } - }; - - var newFilter = new Method({ - name: 'newFilter', - call: newFilterCall, - params: 1 - }); - - var uninstallFilter = new Method({ - name: 'uninstallFilter', - call: 'eth_uninstallFilter', - params: 1 - }); - - var getLogs = new Method({ - name: 'getLogs', - call: 'eth_getFilterLogs', - params: 1 - }); - - var poll = new Method({ - name: 'poll', - call: 'eth_getFilterChanges', - params: 1 - }); - - return [ - newFilter, - uninstallFilter, - getLogs, - poll - ]; -}; - -/// @returns an array of objects describing web3.shh.watch api methods -var shh = function () { - var newFilter = new Method({ - name: 'newFilter', - call: 'shh_newFilter', - params: 1 - }); - - var uninstallFilter = new Method({ - name: 'uninstallFilter', - call: 'shh_uninstallFilter', - params: 1 - }); - - var getLogs = new Method({ - name: 'getLogs', - call: 'shh_getMessages', - params: 1 - }); - - var poll = new Method({ - name: 'poll', - call: 'shh_getFilterChanges', - params: 1 - }); - - return [ - newFilter, - uninstallFilter, - getLogs, - poll - ]; -}; - -module.exports = { - eth: eth, - shh: shh -}; - - -},{"./method":24}],32:[function(require,module,exports){ - -},{}],33:[function(require,module,exports){ +},{}],46:[function(require,module,exports){ ;(function (root, factory) { if (typeof exports === "object") { // CommonJS @@ -5569,7 +6735,7 @@ module.exports = { return CryptoJS; })); -},{}],34:[function(require,module,exports){ +},{}],47:[function(require,module,exports){ ;(function (root, factory, undef) { if (typeof exports === "object") { // CommonJS @@ -5893,7 +7059,7 @@ module.exports = { return CryptoJS.SHA3; })); -},{"./core":33,"./x64-core":35}],35:[function(require,module,exports){ +},{"./core":46,"./x64-core":48}],48:[function(require,module,exports){ ;(function (root, factory) { if (typeof exports === "object") { // CommonJS @@ -6198,7 +7364,7 @@ module.exports = { return CryptoJS; })); -},{"./core":33}],"bignumber.js":[function(require,module,exports){ +},{"./core":46}],"bignumber.js":[function(require,module,exports){ 'use strict'; module.exports = BigNumber; // jshint ignore:line @@ -6206,13 +7372,16 @@ module.exports = BigNumber; // jshint ignore:line },{}],"web3":[function(require,module,exports){ var web3 = require('./lib/web3'); +var namereg = require('./lib/web3/namereg'); web3.providers.HttpProvider = require('./lib/web3/httpprovider'); web3.providers.IpcProvider = require('./lib/web3/ipcprovider'); web3.eth.contract = require('./lib/web3/contract'); -web3.eth.namereg = require('./lib/web3/namereg'); +web3.eth.namereg = namereg.namereg; +web3.eth.ibanNamereg = namereg.ibanNamereg; web3.eth.sendIBANTransaction = require('./lib/web3/transfer'); +web3.eth.iban = require('./lib/web3/iban'); // dont override global variable if (typeof window !== 'undefined' && typeof window.web3 === 'undefined') { @@ -6222,6 +7391,6 @@ if (typeof window !== 'undefined' && typeof window.web3 === 'undefined') { module.exports = web3; -},{"./lib/web3":9,"./lib/web3/contract":12,"./lib/web3/httpprovider":20,"./lib/web3/ipcprovider":22,"./lib/web3/namereg":25,"./lib/web3/transfer":30}]},{},["web3"]) +},{"./lib/web3":22,"./lib/web3/contract":25,"./lib/web3/httpprovider":31,"./lib/web3/iban":32,"./lib/web3/ipcprovider":33,"./lib/web3/namereg":41,"./lib/web3/transfer":44}]},{},["web3"]) //# sourceMappingURL=web3-light.js.map `