diff options
Diffstat (limited to 'dist/ethereum.js')
-rw-r--r-- | dist/ethereum.js | 889 |
1 files changed, 538 insertions, 351 deletions
diff --git a/dist/ethereum.js b/dist/ethereum.js index 6a8c2a78f..282b0e591 100644 --- a/dist/ethereum.js +++ b/dist/ethereum.js @@ -22,191 +22,57 @@ require=(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof requ * @date 2014 */ -// TODO: is these line is supposed to be here? -if ("build" !== 'build') {/* - var BigNumber = require('bignumber.js'); // jshint ignore:line -*/} - -var web3 = require('./web3'); // jshint ignore:line - -BigNumber.config({ ROUNDING_MODE: BigNumber.ROUND_DOWN }); - -var ETH_PADDING = 32; - -/// method signature length in bytes -var ETH_METHOD_SIGNATURE_LENGTH = 4; - -/// Finds first index of array element matching pattern -/// @param array -/// @param callback pattern -/// @returns index of element -var findIndex = function (array, callback) { - var end = false; - var i = 0; - for (; i < array.length && !end; i++) { - end = callback(array[i]); - } - return end ? i - 1 : -1; -}; - -/// @returns a function that is used as a pattern for 'findIndex' -var findMethodIndex = function (json, methodName) { - return findIndex(json, function (method) { - return method.name === methodName; - }); -}; - -/// @returns method with given method name -var getMethodWithName = function (json, methodName) { - var index = findMethodIndex(json, methodName); - if (index === -1) { - console.error('method ' + methodName + ' not found in the abi'); - return undefined; - } - return json[index]; -}; - -/// Filters all function from input abi -/// @returns abi array with filtered objects of type 'function' -var filterFunctions = function (json) { - return json.filter(function (current) { - return current.type === 'function'; - }); -}; - -/// Filters all events form input abi -/// @returns abi array with filtered objects of type 'event' -var filterEvents = function (json) { - return json.filter(function (current) { - return current.type === 'event'; - }); -}; - -/// @param string string to be padded -/// @param number of characters that result string should have -/// @param sign, by default 0 -/// @returns right aligned string -var padLeft = function (string, chars, sign) { - return new Array(chars - string.length + 1).join(sign ? sign : "0") + string; -}; +var web3 = require('./web3'); +var utils = require('./utils'); +var types = require('./types'); +var c = require('./const'); +var f = require('./formatters'); -/// @param expected type prefix (string) -/// @returns function which checks if type has matching prefix. if yes, returns true, otherwise false -var prefixedType = function (prefix) { - return function (type) { - return type.indexOf(prefix) === 0; - }; -}; - -/// @param expected type name (string) -/// @returns function which checks if type is matching expected one. if yes, returns true, otherwise false -var namedType = function (name) { - return function (type) { - return name === type; - }; +var displayTypeError = function (type) { + console.error('parser does not support type: ' + type); }; +/// This method should be called if we want to check if givent type is an array type +/// @returns true if it is, otherwise false var arrayType = function (type) { return type.slice(-2) === '[]'; }; -/// Formats input value to byte representation of int -/// If value is negative, return it's two's complement -/// If the value is floating point, round it down -/// @returns right-aligned byte representation of int -var formatInputInt = function (value) { - var padding = ETH_PADDING * 2; - if (value instanceof BigNumber || typeof value === 'number') { - if (typeof value === 'number') - value = new BigNumber(value); - value = value.round(); - - if (value.lessThan(0)) - value = new BigNumber("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 16).plus(value).plus(1); - value = value.toString(16); - } - else if (value.indexOf('0x') === 0) - value = value.substr(2); - else if (typeof value === 'string') - value = formatInputInt(new BigNumber(value)); - else - value = (+value).toString(16); - return padLeft(value, padding); -}; - -/// Formats input value to byte representation of string -/// @returns left-algined byte representation of string -var formatInputString = function (value) { - return web3.fromAscii(value, ETH_PADDING).substr(2); -}; - -/// Formats input value to byte representation of bool -/// @returns right-aligned byte representation bool -var formatInputBool = function (value) { - return '000000000000000000000000000000000000000000000000000000000000000' + (value ? '1' : '0'); -}; - -/// Formats input value to byte representation of real -/// Values are multiplied by 2^m and encoded as integers -/// @returns byte representation of real -var formatInputReal = function (value) { - return formatInputInt(new BigNumber(value).times(new BigNumber(2).pow(128))); -}; - var dynamicTypeBytes = function (type, value) { // TODO: decide what to do with array of strings if (arrayType(type) || type === 'string') // only string itself that is dynamic; stringX is static length. - return formatInputInt(value.length); + return f.formatInputInt(value.length); return ""; }; -/// Setups input formatters for solidity types -/// @returns an array of input formatters -var setupInputTypes = function () { - - return [ - { type: prefixedType('uint'), format: formatInputInt }, - { type: prefixedType('int'), format: formatInputInt }, - { type: prefixedType('hash'), format: formatInputInt }, - { type: prefixedType('string'), format: formatInputString }, - { type: prefixedType('real'), format: formatInputReal }, - { type: prefixedType('ureal'), format: formatInputReal }, - { type: namedType('address'), format: formatInputInt }, - { type: namedType('bool'), format: formatInputBool } - ]; -}; - -var inputTypes = setupInputTypes(); +var inputTypes = types.inputTypes(); /// Formats input params to bytes -/// @param contract json abi -/// @param name of the method that we want to use +/// @param abi contract method inputs /// @param array of params that will be formatted to bytes /// @returns bytes representation of input params -var toAbiInput = function (json, methodName, params) { +var formatInput = function (inputs, params) { var bytes = ""; - - var method = getMethodWithName(json, methodName); - var padding = ETH_PADDING * 2; + var padding = c.ETH_PADDING * 2; /// first we iterate in search for dynamic - method.inputs.forEach(function (input, index) { + inputs.forEach(function (input, index) { bytes += dynamicTypeBytes(input.type, params[index]); }); - method.inputs.forEach(function (input, i) { + inputs.forEach(function (input, i) { var typeMatch = false; for (var j = 0; j < inputTypes.length && !typeMatch; j++) { - typeMatch = inputTypes[j].type(method.inputs[i].type, params[i]); + typeMatch = inputTypes[j].type(inputs[i].type, params[i]); } if (!typeMatch) { - console.error('input parser does not support type: ' + method.inputs[i].type); + displayTypeError(inputs[i].type); } var formatter = inputTypes[j - 1].format; var toAppend = ""; - if (arrayType(method.inputs[i].type)) + if (arrayType(inputs[i].type)) toAppend = params[i].reduce(function (acc, curr) { return acc + formatter(curr); }, ""); @@ -218,118 +84,44 @@ var toAbiInput = function (json, methodName, params) { return bytes; }; -/// Check if input value is negative -/// @param value is hex format -/// @returns true if it is negative, otherwise false -var signedIsNegative = function (value) { - return (new BigNumber(value.substr(0, 1), 16).toString(2).substr(0, 1)) === '1'; -}; - -/// Formats input right-aligned input bytes to int -/// @returns right-aligned input bytes formatted to int -var formatOutputInt = function (value) { - value = value || "0"; - // check if it's negative number - // it it is, return two's complement - if (signedIsNegative(value)) { - return new BigNumber(value, 16).minus(new BigNumber('ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff', 16)).minus(1); - } - return new BigNumber(value, 16); -}; - -/// Formats big right-aligned input bytes to uint -/// @returns right-aligned input bytes formatted to uint -var formatOutputUInt = function (value) { - value = value || "0"; - return new BigNumber(value, 16); -}; - -/// @returns input bytes formatted to real -var formatOutputReal = function (value) { - return formatOutputInt(value).dividedBy(new BigNumber(2).pow(128)); -}; - -/// @returns input bytes formatted to ureal -var formatOutputUReal = function (value) { - return formatOutputUInt(value).dividedBy(new BigNumber(2).pow(128)); -}; - -/// @returns right-aligned input bytes formatted to hex -var formatOutputHash = function (value) { - return "0x" + value; -}; - -/// @returns right-aligned input bytes formatted to bool -var formatOutputBool = function (value) { - return value === '0000000000000000000000000000000000000000000000000000000000000001' ? true : false; -}; - -/// @returns left-aligned input bytes formatted to ascii string -var formatOutputString = function (value) { - return web3.toAscii(value); -}; - -/// @returns right-aligned input bytes formatted to address -var formatOutputAddress = function (value) { - return "0x" + value.slice(value.length - 40, value.length); -}; - var dynamicBytesLength = function (type) { if (arrayType(type) || type === 'string') // only string itself that is dynamic; stringX is static length. - return ETH_PADDING * 2; + return c.ETH_PADDING * 2; return 0; }; -/// Setups output formaters for solidity types -/// @returns an array of output formatters -var setupOutputTypes = function () { - - return [ - { type: prefixedType('uint'), format: formatOutputUInt }, - { type: prefixedType('int'), format: formatOutputInt }, - { type: prefixedType('hash'), format: formatOutputHash }, - { type: prefixedType('string'), format: formatOutputString }, - { type: prefixedType('real'), format: formatOutputReal }, - { type: prefixedType('ureal'), format: formatOutputUReal }, - { type: namedType('address'), format: formatOutputAddress }, - { type: namedType('bool'), format: formatOutputBool } - ]; -}; - -var outputTypes = setupOutputTypes(); +var outputTypes = types.outputTypes(); /// Formats output bytes back to param list -/// @param contract json abi -/// @param name of the method that we want to use +/// @param contract abi method outputs /// @param bytes representtion of output /// @returns array of output params -var fromAbiOutput = function (json, methodName, output) { +var formatOutput = function (outs, output) { output = output.slice(2); var result = []; - var method = getMethodWithName(json, methodName); - var padding = ETH_PADDING * 2; + var padding = c.ETH_PADDING * 2; - var dynamicPartLength = method.outputs.reduce(function (acc, curr) { + var dynamicPartLength = outs.reduce(function (acc, curr) { return acc + dynamicBytesLength(curr.type); }, 0); var dynamicPart = output.slice(0, dynamicPartLength); output = output.slice(dynamicPartLength); - method.outputs.forEach(function (out, i) { + outs.forEach(function (out, i) { var typeMatch = false; for (var j = 0; j < outputTypes.length && !typeMatch; j++) { - typeMatch = outputTypes[j].type(method.outputs[i].type); + typeMatch = outputTypes[j].type(outs[i].type); } if (!typeMatch) { - console.error('output parser does not support type: ' + method.outputs[i].type); + displayTypeError(outs[i].type); } var formatter = outputTypes[j - 1].format; - if (arrayType(method.outputs[i].type)) { - var size = formatOutputUInt(dynamicPart.slice(0, padding)); + if (arrayType(outs[i].type)) { + var size = f.formatOutputUInt(dynamicPart.slice(0, padding)); dynamicPart = dynamicPart.slice(padding); var array = []; for (var k = 0; k < size; k++) { @@ -338,7 +130,7 @@ var fromAbiOutput = function (json, methodName, output) { } result.push(array); } - else if (prefixedType('string')(method.outputs[i].type)) { + else if (types.prefixedType('string')(outs[i].type)) { dynamicPart = dynamicPart.slice(padding); result.push(formatter(output.slice(0, padding))); output = output.slice(padding); @@ -351,30 +143,18 @@ var fromAbiOutput = function (json, methodName, output) { return result; }; -/// @returns display name for method eg. multiply(uint256) -> multiply -var methodDisplayName = function (method) { - var length = method.indexOf('('); - return length !== -1 ? method.substr(0, length) : method; -}; - -/// @returns overloaded part of method's name -var methodTypeName = function (method) { - /// TODO: make it not vulnerable - var length = method.indexOf('('); - return length !== -1 ? method.substr(length + 1, method.length - 1 - (length + 1)) : ""; -}; - /// @param json abi for contract /// @returns input parser object for given json abi +/// TODO: refactor creating the parser, do not double logic from contract var inputParser = function (json) { var parser = {}; - filterFunctions(json).forEach(function (method) { - var displayName = methodDisplayName(method.name); - var typeName = methodTypeName(method.name); + 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 toAbiInput(json, method.name, params); + return formatInput(method.inputs, params); }; if (parser[displayName] === undefined) { @@ -391,13 +171,13 @@ var inputParser = function (json) { /// @returns output parser for given json abi var outputParser = function (json) { var parser = {}; - filterFunctions(json).forEach(function (method) { + json.forEach(function (method) { - var displayName = methodDisplayName(method.name); - var typeName = methodTypeName(method.name); + var displayName = utils.extractDisplayName(method.name); + var typeName = utils.extractTypeName(method.name); var impl = function (output) { - return fromAbiOutput(json, method.name, output); + return formatOutput(method.outputs, output); }; if (parser[displayName] === undefined) { @@ -410,25 +190,57 @@ var outputParser = function (json) { return parser; }; -/// @param method name for which we want to get method signature -/// @returns (promise) contract method signature for method with given name -var methodSignature = function (name) { - return web3.sha3(web3.fromAscii(name)).slice(0, 2 + ETH_METHOD_SIGNATURE_LENGTH * 2); +/// @param function/event name for which we want to get signature +/// @returns signature of function/event with given name +var signatureFromAscii = function (name) { + return web3.sha3(web3.fromAscii(name)).slice(0, 2 + c.ETH_SIGNATURE_LENGTH * 2); }; module.exports = { inputParser: inputParser, outputParser: outputParser, - methodSignature: methodSignature, - methodDisplayName: methodDisplayName, - methodTypeName: methodTypeName, - getMethodWithName: getMethodWithName, - filterFunctions: filterFunctions, - filterEvents: filterEvents + formatInput: formatInput, + formatOutput: formatOutput, + signatureFromAscii: signatureFromAscii +}; + + +},{"./const":2,"./formatters":6,"./types":10,"./utils":11,"./web3":12}],2:[function(require,module,exports){ +/* + This file is part of ethereum.js. + + ethereum.js is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ethereum.js is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with ethereum.js. If not, see <http://www.gnu.org/licenses/>. +*/ +/** @file const.js + * @authors: + * Marek Kotewicz <marek@ethdev.com> + * @date 2015 + */ + +/// required to define ETH_BIGNUMBER_ROUNDING_MODE +if ("build" !== 'build') {/* + var BigNumber = require('bignumber.js'); // jshint ignore:line +*/} + +module.exports = { + ETH_PADDING: 32, + ETH_SIGNATURE_LENGTH: 4, + ETH_BIGNUMBER_ROUNDING_MODE: { ROUNDING_MODE: BigNumber.ROUND_DOWN } }; -},{"./web3":8}],2:[function(require,module,exports){ +},{}],3:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -453,8 +265,18 @@ module.exports = { var web3 = require('./web3'); var abi = require('./abi'); +var utils = require('./utils'); var eventImpl = require('./event'); +var exportNatspecGlobals = function (vars) { + // it's used byt natspec.js + // TODO: figure out better way to solve this + web3._currentContractAbi = vars.abi; + web3._currentContractAddress = vars.address; + web3._currentContractMethodName = vars.method; + web3._currentContractMethodParams = vars.params; +}; + var addFunctionRelatedPropertiesToContract = function (contract) { contract.call = function (options) { @@ -484,14 +306,14 @@ var addFunctionsToContract = function (contract, desc, address) { var outputParser = abi.outputParser(desc); // create contract functions - abi.filterFunctions(desc).forEach(function (method) { + utils.filterFunctions(desc).forEach(function (method) { - var displayName = abi.methodDisplayName(method.name); - var typeName = abi.methodTypeName(method.name); + var displayName = utils.extractDisplayName(method.name); + var typeName = utils.extractTypeName(method.name); var impl = function () { var params = Array.prototype.slice.call(arguments); - var signature = abi.methodSignature(method.name); + var signature = abi.signatureFromAscii(method.name); var parsed = inputParser[displayName][typeName].apply(null, params); var options = contract._options || {}; @@ -506,12 +328,13 @@ var addFunctionsToContract = function (contract, desc, address) { contract._isTransact = null; if (isTransact) { - // it's used byt natspec.js - // TODO: figure out better way to solve this - web3._currentContractAbi = desc; - web3._currentContractAddress = address; - web3._currentContractMethodName = method.name; - web3._currentContractMethodParams = params; + + exportNatspecGlobals({ + abi: desc, + address: address, + method: method.name, + params: params + }); // transactions do not have any output, cause we do not know, when they will be processed web3.eth.transact(options); @@ -543,8 +366,8 @@ var addEventRelatedPropertiesToContract = function (contract, desc, address) { Object.defineProperty(contract, 'topic', { get: function() { - return abi.filterEvents(desc).map(function (e) { - return abi.methodSignature(e.name); + return utils.filterEvents(desc).map(function (e) { + return abi.signatureFromAscii(e.name); }); } }); @@ -553,27 +376,21 @@ var addEventRelatedPropertiesToContract = function (contract, desc, address) { var addEventsToContract = function (contract, desc, address) { // create contract events - abi.filterEvents(desc).forEach(function (e) { + utils.filterEvents(desc).forEach(function (e) { var impl = function () { var params = Array.prototype.slice.call(arguments); - var signature = abi.methodSignature(e.name); - var event = eventImpl(address, signature); + var signature = abi.signatureFromAscii(e.name); + var event = eventImpl(address, signature, e); var o = event.apply(null, params); return web3.eth.watch(o); }; - - impl.address = address; - - Object.defineProperty(impl, 'topic', { - get: function() { - return [abi.methodSignature(e.name)]; - } - }); - // TODO: rename these methods, cause they are used not only for methods - var displayName = abi.methodDisplayName(e.name); - var typeName = abi.methodTypeName(e.name); + // this property should be used by eth.filter to check if object is an event + impl._isEvent = true; + + var displayName = utils.extractDisplayName(e.name); + var typeName = utils.extractTypeName(e.name); if (contract[displayName] === undefined) { contract[displayName] = impl; @@ -633,7 +450,7 @@ var contract = function (address, desc) { module.exports = contract; -},{"./abi":1,"./event":3,"./web3":8}],3:[function(require,module,exports){ +},{"./abi":1,"./event":4,"./utils":11,"./web3":12}],4:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -656,13 +473,47 @@ module.exports = contract; * @date 2014 */ -var implementationOfEvent = function (address, signature) { +var abi = require('./abi'); +var utils = require('./utils'); + +var inputWithName = function (inputs, name) { + var index = utils.findIndex(inputs, function (input) { + return input.name === name; + }); - return function (options) { + if (index === -1) { + console.error('indexed param with name ' + name + ' not found'); + return undefined; + } + return inputs[index]; +}; + +var indexedParamsToTopics = function (event, indexed) { + // sort keys? + return Object.keys(indexed).map(function (key) { + var inputs = [inputWithName(event.inputs, key)]; + + var value = indexed[key]; + if (value instanceof Array) { + return value.map(function (v) { + return abi.formatInput(inputs, [v]); + }); + } + return abi.formatInput(inputs, [value]); + }); +}; + +var implementationOfEvent = function (address, signature, event) { + + // valid options are 'earliest', 'latest', 'offset' and 'max', as defined for 'eth.watch' + return function (indexed, options) { var o = options || {}; - o.address = o.address || address; - o.topics = o.topics || []; - o.topics.push(signature); + o.address = address; + o.topic = []; + o.topic.push(signature); + if (indexed) { + o.topic = o.topic.concat(indexedParamsToTopics(event, indexed)); + } return o; }; }; @@ -670,7 +521,7 @@ var implementationOfEvent = function (address, signature) { module.exports = implementationOfEvent; -},{}],4:[function(require,module,exports){ +},{"./abi":1,"./utils":11}],5:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -700,16 +551,17 @@ var web3 = require('./web3'); // jshint ignore:line /// should be used when we want to watch something /// it's using inner polling mechanism and is notified about changes +/// TODO: change 'options' name cause it may be not the best matching one, since we have events var Filter = function(options, impl) { - this.impl = impl; - this.callbacks = []; if (typeof options !== "string") { - // evaluate lazy properties + + // topics property is deprecated, warn about it! if (options.topics) { console.warn('"topics" is deprecated, use "topic" instead'); } + // evaluate lazy properties options = { to: options.to, topic: options.topic, @@ -719,7 +571,11 @@ var Filter = function(options, impl) { skip: options.skip, address: options.address }; + } + + this.impl = impl; + this.callbacks = []; this.id = impl.newFilter(options); web3.provider.startPolling({call: impl.changed, args: [this.id]}, this.id, this.trigger.bind(this)); @@ -762,7 +618,163 @@ Filter.prototype.logs = function () { module.exports = Filter; -},{"./web3":8}],5:[function(require,module,exports){ +},{"./web3":12}],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 <http://www.gnu.org/licenses/>. +*/ +/** @file formatters.js + * @authors: + * Marek Kotewicz <marek@ethdev.com> + * @date 2015 + */ + +if ("build" !== 'build') {/* + var BigNumber = require('bignumber.js'); // jshint ignore:line +*/} + +var utils = require('./utils'); +var c = require('./const'); + +/// @param string string to be padded +/// @param number of characters that result string should have +/// @param sign, by default 0 +/// @returns right aligned string +var padLeft = function (string, chars, sign) { + return new Array(chars - string.length + 1).join(sign ? sign : "0") + string; +}; + +/// Formats input value to byte representation of int +/// If value is negative, return it's two's complement +/// If the value is floating point, round it down +/// @returns right-aligned byte representation of int +var formatInputInt = function (value) { + var padding = c.ETH_PADDING * 2; + if (value instanceof BigNumber || typeof value === 'number') { + if (typeof value === 'number') + value = new BigNumber(value); + BigNumber.config(c.ETH_BIGNUMBER_ROUNDING_MODE); + value = value.round(); + + if (value.lessThan(0)) + value = new BigNumber("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 16).plus(value).plus(1); + value = value.toString(16); + } + else if (value.indexOf('0x') === 0) + value = value.substr(2); + else if (typeof value === 'string') + value = formatInputInt(new BigNumber(value)); + else + value = (+value).toString(16); + return padLeft(value, padding); +}; + +/// Formats input value to byte representation of string +/// @returns left-algined byte representation of string +var formatInputString = function (value) { + return utils.fromAscii(value, c.ETH_PADDING).substr(2); +}; + +/// Formats input value to byte representation of bool +/// @returns right-aligned byte representation bool +var formatInputBool = function (value) { + return '000000000000000000000000000000000000000000000000000000000000000' + (value ? '1' : '0'); +}; + +/// Formats input value to byte representation of real +/// Values are multiplied by 2^m and encoded as integers +/// @returns byte representation of real +var formatInputReal = function (value) { + return formatInputInt(new BigNumber(value).times(new BigNumber(2).pow(128))); +}; + + +/// Check if input value is negative +/// @param value is hex format +/// @returns true if it is negative, otherwise false +var signedIsNegative = function (value) { + return (new BigNumber(value.substr(0, 1), 16).toString(2).substr(0, 1)) === '1'; +}; + +/// Formats input right-aligned input bytes to int +/// @returns right-aligned input bytes formatted to int +var formatOutputInt = function (value) { + value = value || "0"; + // check if it's negative number + // it it is, return two's complement + if (signedIsNegative(value)) { + return new BigNumber(value, 16).minus(new BigNumber('ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff', 16)).minus(1); + } + return new BigNumber(value, 16); +}; + +/// Formats big right-aligned input bytes to uint +/// @returns right-aligned input bytes formatted to uint +var formatOutputUInt = function (value) { + value = value || "0"; + return new BigNumber(value, 16); +}; + +/// @returns input bytes formatted to real +var formatOutputReal = function (value) { + return formatOutputInt(value).dividedBy(new BigNumber(2).pow(128)); +}; + +/// @returns input bytes formatted to ureal +var formatOutputUReal = function (value) { + return formatOutputUInt(value).dividedBy(new BigNumber(2).pow(128)); +}; + +/// @returns right-aligned input bytes formatted to hex +var formatOutputHash = function (value) { + return "0x" + value; +}; + +/// @returns right-aligned input bytes formatted to bool +var formatOutputBool = function (value) { + return value === '0000000000000000000000000000000000000000000000000000000000000001' ? true : false; +}; + +/// @returns left-aligned input bytes formatted to ascii string +var formatOutputString = function (value) { + return utils.toAscii(value); +}; + +/// @returns right-aligned input bytes formatted to address +var formatOutputAddress = function (value) { + return "0x" + value.slice(value.length - 40, value.length); +}; + + +module.exports = { + formatInputInt: formatInputInt, + formatInputString: formatInputString, + formatInputBool: formatInputBool, + formatInputReal: formatInputReal, + formatOutputInt: formatOutputInt, + formatOutputUInt: formatOutputUInt, + formatOutputReal: formatOutputReal, + formatOutputUReal: formatOutputUReal, + formatOutputHash: formatOutputHash, + formatOutputBool: formatOutputBool, + formatOutputString: formatOutputString, + formatOutputAddress: formatOutputAddress +}; + + +},{"./const":2,"./utils":11}],7:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -834,7 +846,7 @@ HttpSyncProvider.prototype.send = function (payload) { module.exports = HttpSyncProvider; -},{}],6:[function(require,module,exports){ +},{}],8:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -946,7 +958,7 @@ ProviderManager.prototype.stopPolling = function (pollId) { module.exports = ProviderManager; -},{"./web3":8}],7:[function(require,module,exports){ +},{"./web3":12}],9:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -980,7 +992,203 @@ QtSyncProvider.prototype.send = function (payload) { module.exports = QtSyncProvider; -},{}],8:[function(require,module,exports){ +},{}],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 <http://www.gnu.org/licenses/>. +*/ +/** @file types.js + * @authors: + * Marek Kotewicz <marek@ethdev.com> + * @date 2015 + */ + +var f = require('./formatters'); + +/// @param expected type prefix (string) +/// @returns function which checks if type has matching prefix. if yes, returns true, otherwise false +var prefixedType = function (prefix) { + return function (type) { + return type.indexOf(prefix) === 0; + }; +}; + +/// @param expected type name (string) +/// @returns function which checks if type is matching expected one. if yes, returns true, otherwise false +var namedType = function (name) { + return function (type) { + return name === type; + }; +}; + +/// Setups input formatters for solidity types +/// @returns an array of input formatters +var inputTypes = function () { + + return [ + { type: prefixedType('uint'), format: f.formatInputInt }, + { type: prefixedType('int'), format: f.formatInputInt }, + { type: prefixedType('hash'), format: f.formatInputInt }, + { type: prefixedType('string'), format: f.formatInputString }, + { type: prefixedType('real'), format: f.formatInputReal }, + { type: prefixedType('ureal'), format: f.formatInputReal }, + { type: namedType('address'), format: f.formatInputInt }, + { type: namedType('bool'), format: f.formatInputBool } + ]; +}; + +/// Setups output formaters for solidity types +/// @returns an array of output formatters +var outputTypes = function () { + + return [ + { type: prefixedType('uint'), format: f.formatOutputUInt }, + { type: prefixedType('int'), format: f.formatOutputInt }, + { type: prefixedType('hash'), format: f.formatOutputHash }, + { type: prefixedType('string'), format: f.formatOutputString }, + { type: prefixedType('real'), format: f.formatOutputReal }, + { type: prefixedType('ureal'), format: f.formatOutputUReal }, + { type: namedType('address'), format: f.formatOutputAddress }, + { type: namedType('bool'), format: f.formatOutputBool } + ]; +}; + +module.exports = { + prefixedType: prefixedType, + namedType: namedType, + inputTypes: inputTypes, + outputTypes: outputTypes +}; + + +},{"./formatters":6}],11:[function(require,module,exports){ +/* + This file is part of ethereum.js. + + ethereum.js is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ethereum.js is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with ethereum.js. If not, see <http://www.gnu.org/licenses/>. +*/ +/** @file utils.js + * @authors: + * Marek Kotewicz <marek@ethdev.com> + * @date 2015 + */ + +/// Finds first index of array element matching pattern +/// @param array +/// @param callback pattern +/// @returns index of element +var findIndex = function (array, callback) { + var end = false; + var i = 0; + for (; i < array.length && !end; i++) { + end = callback(array[i]); + } + return end ? i - 1 : -1; +}; + +/// @returns ascii string representation of hex value prefixed with 0x +var toAscii = function(hex) { +// Find termination + var str = ""; + var i = 0, l = hex.length; + if (hex.substring(0, 2) === '0x') { + i = 2; + } + for (; i < l; i+=2) { + var code = parseInt(hex.substr(i, 2), 16); + if (code === 0) { + break; + } + + str += String.fromCharCode(code); + } + + return str; +}; + +var toHex = function(str) { + var hex = ""; + for(var i = 0; i < str.length; i++) { + var n = str.charCodeAt(i).toString(16); + hex += n.length < 2 ? '0' + n : n; + } + + return hex; +}; + +/// @returns hex representation (prefixed by 0x) of ascii string +var fromAscii = function(str, pad) { + pad = pad === undefined ? 0 : pad; + var hex = toHex(str); + while (hex.length < pad*2) + hex += "00"; + return "0x" + hex; +}; + +/// @returns display name for function/event eg. multiply(uint256) -> multiply +var extractDisplayName = function (name) { + var length = name.indexOf('('); + return length !== -1 ? name.substr(0, length) : name; +}; + +/// @returns overloaded part of function/event name +var extractTypeName = function (name) { + /// TODO: make it invulnerable + var length = name.indexOf('('); + return length !== -1 ? name.substr(length + 1, name.length - 1 - (length + 1)) : ""; +}; + +/// Filters all function from input abi +/// @returns abi array with filtered objects of type 'function' +var filterFunctions = function (json) { + return json.filter(function (current) { + return current.type === 'function'; + }); +}; + +/// Filters all events form input abi +/// @returns abi array with filtered objects of type 'event' +var filterEvents = function (json) { + return json.filter(function (current) { + return current.type === 'event'; + }); +}; + +module.exports = { + findIndex: findIndex, + toAscii: toAscii, + fromAscii: fromAscii, + extractDisplayName: extractDisplayName, + extractTypeName: extractTypeName, + filterFunctions: filterFunctions, + filterEvents: filterEvents +}; + + +},{}],12:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -1010,6 +1218,8 @@ if ("build" !== 'build') {/* var BigNumber = require('bignumber.js'); */} +var utils = require('./utils'); + var ETH_UNITS = [ 'wei', 'Kwei', @@ -1175,43 +1385,11 @@ var web3 = { _events: {}, providers: {}, - toHex: function(str) { - var hex = ""; - for(var i = 0; i < str.length; i++) { - var n = str.charCodeAt(i).toString(16); - hex += n.length < 2 ? '0' + n : n; - } - - return hex; - }, - /// @returns ascii string representation of hex value prefixed with 0x - toAscii: function(hex) { - // Find termination - var str = ""; - var i = 0, l = hex.length; - if (hex.substring(0, 2) === '0x') - i = 2; - for(; i < l; i+=2) { - var code = parseInt(hex.substr(i, 2), 16); - if(code === 0) { - break; - } - - str += String.fromCharCode(code); - } - - return str; - }, + toAscii: utils.toAscii, /// @returns hex representation (prefixed by 0x) of ascii string - fromAscii: function(str, pad) { - pad = pad === undefined ? 0 : pad; - var hex = this.toHex(str); - while(hex.length < pad*2) - hex += "00"; - return "0x" + hex; - }, + fromAscii: utils.fromAscii, /// @returns decimal representaton of hex value prefixed by 0x toDecimal: function (val) { @@ -1261,8 +1439,15 @@ var web3 = { return ret; }; }, - watch: function (params) { - return new web3.filter(params, ethWatch); + + /// @param filter may be a string, object or event + /// @param indexed is optional, this is an object with optional event indexed params + /// @param options is optional, this is an object with optional event options ('max'...) + watch: function (filter, indexed, options) { + if (filter._isEvent) { + return filter(indexed, options); + } + return new web3.filter(filter, ethWatch); } }, @@ -1271,8 +1456,10 @@ var web3 = { /// shh object prototype shh: { - watch: function (params) { - return new web3.filter(params, shhWatch); + + /// @param filter may be a string, object or event + watch: function (filter, indexed) { + return new web3.filter(filter, shhWatch); } }, @@ -1309,7 +1496,7 @@ web3.setProvider = function(provider) { module.exports = web3; -},{}],"web3":[function(require,module,exports){ +},{"./utils":11}],"web3":[function(require,module,exports){ var web3 = require('./lib/web3'); var ProviderManager = require('./lib/providermanager'); web3.provider = new ProviderManager(); @@ -1322,7 +1509,7 @@ web3.abi = require('./lib/abi'); module.exports = web3; -},{"./lib/abi":1,"./lib/contract":2,"./lib/filter":4,"./lib/httpsync":5,"./lib/providermanager":6,"./lib/qtsync":7,"./lib/web3":8}]},{},["web3"]) +},{"./lib/abi":1,"./lib/contract":3,"./lib/filter":5,"./lib/httpsync":7,"./lib/providermanager":8,"./lib/qtsync":9,"./lib/web3":12}]},{},["web3"]) //# sourceMappingURL=ethereum.js.map
\ No newline at end of file |