From 09f633596da91818201781cc009e1e1ab6f8d059 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Tue, 27 Jan 2015 15:20:22 +0100 Subject: fixed #23 --- lib/abi.js | 2 ++ lib/web3.js | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/abi.js b/lib/abi.js index 0989f4e15..ba47dca73 100644 --- a/lib/abi.js +++ b/lib/abi.js @@ -211,6 +211,7 @@ var signedIsNegative = function (value) { /// 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)) { @@ -222,6 +223,7 @@ var formatOutputInt = function (value) { /// 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); }; diff --git a/lib/web3.js b/lib/web3.js index 7cf624c9c..622be29b6 100644 --- a/lib/web3.js +++ b/lib/web3.js @@ -233,7 +233,9 @@ var web3 = { /// @returns decimal representaton of hex value prefixed by 0x toDecimal: function (val) { - return (new BigNumber(val.substring(2), 16).toString(10)); + // remove 0x and place 0, if it's required + val = val.length > 2 ? val.substring(2) : "0"; + return (new BigNumber(val, 16).toString(10)); }, /// @returns hex representation (prefixed by 0x) of decimal value -- cgit v1.2.3 From c2cb2bef96e591d68b04cf5f1a6ec29696abb481 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Tue, 27 Jan 2015 16:02:42 +0100 Subject: removed web3.eth.account, fixed #37 --- lib/web3.js | 1 - 1 file changed, 1 deletion(-) (limited to 'lib') diff --git a/lib/web3.js b/lib/web3.js index 622be29b6..7b8bbd28a 100644 --- a/lib/web3.js +++ b/lib/web3.js @@ -98,7 +98,6 @@ var ethProperties = function () { { name: 'listening', getter: 'eth_listening', setter: 'eth_setListening' }, { name: 'mining', getter: 'eth_mining', setter: 'eth_setMining' }, { name: 'gasPrice', getter: 'eth_gasPrice' }, - { name: 'account', getter: 'eth_account' }, { name: 'accounts', getter: 'eth_accounts' }, { name: 'peerCount', getter: 'eth_peerCount' }, { name: 'defaultBlock', getter: 'eth_defaultBlock', setter: 'eth_setDefaultBlock' }, -- cgit v1.2.3 From 1345a8c67c41a31847c0dea23a7e7904bf25779a Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Wed, 28 Jan 2015 00:07:03 +0100 Subject: log error on console, if api returns an error --- lib/providermanager.js | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'lib') diff --git a/lib/providermanager.js b/lib/providermanager.js index 1a550e5f4..25cd14288 100644 --- a/lib/providermanager.js +++ b/lib/providermanager.js @@ -76,6 +76,12 @@ ProviderManager.prototype.send = function(data) { //TODO: handle error here? var result = this.provider.send(data); result = JSON.parse(result); + + if (result.error) { + console.log(result.error); + return null; + } + return result.result; }; -- cgit v1.2.3 From 63d9c070ef7637a3d570a5a45ea931c1680ebc02 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Wed, 28 Jan 2015 10:50:24 +0100 Subject: fixed incoming messages --- lib/filter.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/filter.js b/lib/filter.js index 8c7dc6e33..d93064b58 100644 --- a/lib/filter.js +++ b/lib/filter.js @@ -48,7 +48,7 @@ Filter.prototype.changed = function(callback) { /// trigger calling new message from people Filter.prototype.trigger = function(messages) { for (var i = 0; i < this.callbacks.length; i++) { - for (var j = 0; j < messages; j++) { + for (var j = 0; j < messages.length; j++) { this.callbacks[i].call(this, messages[j]); } } -- cgit v1.2.3 From ea7c2fc673db31f96583e4712aa0fb78f5d709eb Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Wed, 28 Jan 2015 14:20:36 +0100 Subject: abi function type --- lib/abi.js | 15 ++++++++++++--- lib/contract.js | 3 ++- 2 files changed, 14 insertions(+), 4 deletions(-) (limited to 'lib') diff --git a/lib/abi.js b/lib/abi.js index ba47dca73..a0752647f 100644 --- a/lib/abi.js +++ b/lib/abi.js @@ -65,6 +65,14 @@ var getMethodWithName = function (json, methodName) { 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'; + }); +}; + /// @param string string to be padded /// @param number of characters that result string should have /// @param sign, by default 0 @@ -351,7 +359,7 @@ var methodTypeName = function (method) { /// @returns input parser object for given json abi var inputParser = function (json) { var parser = {}; - json.forEach(function (method) { + filterFunctions(json).forEach(function (method) { var displayName = methodDisplayName(method.name); var typeName = methodTypeName(method.name); @@ -374,7 +382,7 @@ var inputParser = function (json) { /// @returns output parser for given json abi var outputParser = function (json) { var parser = {}; - json.forEach(function (method) { + filterFunctions(json).forEach(function (method) { var displayName = methodDisplayName(method.name); var typeName = methodTypeName(method.name); @@ -405,6 +413,7 @@ module.exports = { methodSignature: methodSignature, methodDisplayName: methodDisplayName, methodTypeName: methodTypeName, - getMethodWithName: getMethodWithName + getMethodWithName: getMethodWithName, + filterFunctions: filterFunctions }; diff --git a/lib/contract.js b/lib/contract.js index e71734d0b..65a061502 100644 --- a/lib/contract.js +++ b/lib/contract.js @@ -51,6 +51,7 @@ var contract = function (address, desc) { // workaround for invalid assumption that method.name is the full anonymous prototype of the method. // it's not. it's just the name. the rest of the code assumes it's actually the anonymous // prototype, so we make it so as a workaround. + // TODO: we may not want to modify input params, maybe use copy instead? if (method.name.indexOf('(') === -1) { var displayName = method.name; var typeName = method.inputs.map(function(i){return i.type; }).join(); @@ -84,7 +85,7 @@ var contract = function (address, desc) { }); - desc.forEach(function (method) { + abi.filterFunctions(desc).forEach(function (method) { var displayName = abi.methodDisplayName(method.name); var typeName = abi.methodTypeName(method.name); -- cgit v1.2.3 From 2544d2c952dc003d62bdb99a554b3fa576b202c5 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Wed, 28 Jan 2015 14:39:10 +0100 Subject: tests for abi.filters --- lib/abi.js | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/abi.js b/lib/abi.js index a0752647f..a0c862593 100644 --- a/lib/abi.js +++ b/lib/abi.js @@ -73,6 +73,14 @@ var filterFunctions = function (json) { }); }; +/// 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 @@ -414,6 +422,7 @@ module.exports = { methodDisplayName: methodDisplayName, methodTypeName: methodTypeName, getMethodWithName: getMethodWithName, - filterFunctions: filterFunctions + filterFunctions: filterFunctions, + filterEvents: filterEvents }; -- cgit v1.2.3 From 61e8ae2f7be3ced902007a4aa09ce9130c31b33e Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Wed, 28 Jan 2015 14:55:39 +0100 Subject: events init --- lib/contract.js | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'lib') diff --git a/lib/contract.js b/lib/contract.js index 65a061502..a3e76cfea 100644 --- a/lib/contract.js +++ b/lib/contract.js @@ -85,6 +85,7 @@ var contract = function (address, desc) { }); + // create contract functions abi.filterFunctions(desc).forEach(function (method) { var displayName = abi.methodDisplayName(method.name); @@ -139,6 +140,31 @@ var contract = function (address, desc) { }); + + // create contract events + abi.filterEvents(desc).forEach(function (event) { + + // TODO: rename these methods, cause they are used not only for methods + var displayName = abi.methodDisplayName(event.name); + var typeName = abi.methodTypeName(event.name); + + var impl = function (options) { + var o = options || {}; + o.address = o.address || address; + o.topics = o.topics || []; + o.topics.push(abi.methodSignature(event.name)); + + return web3.eth.watch(o); + }; + + if (result[displayName] === undefined) { + result[displayName] = impl; + } + + result[displayName][typeName] = impl; + + }); + return result; }; -- cgit v1.2.3 From 842b8cf323a3b39d9e29ddd831bc41ddb98279ad Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Thu, 29 Jan 2015 12:35:21 +0100 Subject: event.js --- lib/contract.js | 18 +++++++++++++++--- lib/event.js | 16 ++++++++++++++++ 2 files changed, 31 insertions(+), 3 deletions(-) create mode 100644 lib/event.js (limited to 'lib') diff --git a/lib/contract.js b/lib/contract.js index a3e76cfea..732aa9111 100644 --- a/lib/contract.js +++ b/lib/contract.js @@ -20,7 +20,7 @@ * @date 2014 */ -var web3 = require('./web3'); // jshint ignore:line +var web3 = require('./web3'); var abi = require('./abi'); /** @@ -62,7 +62,17 @@ var contract = function (address, desc) { var inputParser = abi.inputParser(desc); var outputParser = abi.outputParser(desc); - var result = {}; + var result = { + address: address, + }; + + Object.defineProperty(result, 'topics', { + get: function() { + return abi.filterEvents(desc).map(function (event) { + return abi.methodSignature(event.name); + }); + } + }); result.call = function (options) { result._isTransact = false; @@ -148,11 +158,13 @@ var contract = function (address, desc) { var displayName = abi.methodDisplayName(event.name); var typeName = abi.methodTypeName(event.name); + var impl = function (options) { + var signature = abi.methodSignature(event.name); var o = options || {}; o.address = o.address || address; o.topics = o.topics || []; - o.topics.push(abi.methodSignature(event.name)); + o.topics.push(signature); return web3.eth.watch(o); }; diff --git a/lib/event.js b/lib/event.js new file mode 100644 index 000000000..724acde81 --- /dev/null +++ b/lib/event.js @@ -0,0 +1,16 @@ + +var abi = require('./abi'); + +var implementationOfEvent = function (event, address, signature) { + + return function (options) { + var o = options || {}; + o.address = o.address || address; + o.topics = o.topics || []; + o.topics.push(signature); + return o; + }; +}; + +module.exports = implementationOfEvent; + -- cgit v1.2.3 From c8ee08c24bee9ab994822066f9abe94448c4ae89 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Thu, 29 Jan 2015 13:32:32 +0100 Subject: contract.js simplified --- lib/contract.js | 185 ++++++++++++++++++++++++++++++-------------------------- lib/event.js | 2 +- 2 files changed, 100 insertions(+), 87 deletions(-) (limited to 'lib') diff --git a/lib/contract.js b/lib/contract.js index 732aa9111..58a67efe6 100644 --- a/lib/contract.js +++ b/lib/contract.js @@ -22,78 +22,35 @@ var web3 = require('./web3'); var abi = require('./abi'); +var eventImplementation = require('./event'); -/** - * This method should be called when we want to call / transact some solidity method from javascript - * it returns an object which has same methods available as solidity contract description - * usage example: - * - * var abi = [{ - * name: 'myMethod', - * inputs: [{ name: 'a', type: 'string' }], - * outputs: [{name: 'd', type: 'string' }] - * }]; // contract abi - * - * var myContract = web3.eth.contract('0x0123123121', abi); // creation of contract object - * - * myContract.myMethod('this is test string param for call'); // myMethod call (implicit, default) - * myContract.call().myMethod('this is test string param for call'); // myMethod call (explicit) - * myContract.transact().myMethod('this is test string param for transact'); // myMethod transact - * - * @param address - address of the contract, which should be called - * @param desc - abi json description of the contract, which is being created - * @returns contract object - */ - -var contract = function (address, desc) { - - desc.forEach(function (method) { - // workaround for invalid assumption that method.name is the full anonymous prototype of the method. - // it's not. it's just the name. the rest of the code assumes it's actually the anonymous - // prototype, so we make it so as a workaround. - // TODO: we may not want to modify input params, maybe use copy instead? - if (method.name.indexOf('(') === -1) { - var displayName = method.name; - var typeName = method.inputs.map(function(i){return i.type; }).join(); - method.name = displayName + '(' + typeName + ')'; - } - }); - - var inputParser = abi.inputParser(desc); - var outputParser = abi.outputParser(desc); - - var result = { - address: address, - }; - - Object.defineProperty(result, 'topics', { - get: function() { - return abi.filterEvents(desc).map(function (event) { - return abi.methodSignature(event.name); - }); - } - }); - - result.call = function (options) { - result._isTransact = false; - result._options = options; - return result; +var addFunctionRelatedPropertiesToContract = function (contract) { + + contract.call = function (options) { + contract._isTransact = false; + contract._options = options; + return contract; }; - result.transact = function (options) { - result._isTransact = true; - result._options = options; - return result; + contract.transact = function (options) { + contract._isTransact = true; + contract._options = options; + return contract; }; - result._options = {}; + contract._options = {}; ['gas', 'gasPrice', 'value', 'from'].forEach(function(p) { - result[p] = function (v) { - result._options[p] = v; - return result; + contract[p] = function (v) { + contract._options[p] = v; + return contract; }; }); +}; + +var addFunctionsToContract = function (contract, desc, address) { + var inputParser = abi.inputParser(desc); + var outputParser = abi.outputParser(desc); // create contract functions abi.filterFunctions(desc).forEach(function (method) { @@ -106,16 +63,16 @@ var contract = function (address, desc) { var signature = abi.methodSignature(method.name); var parsed = inputParser[displayName][typeName].apply(null, params); - var options = result._options || {}; + var options = contract._options || {}; options.to = address; options.data = signature + parsed; - var isTransact = result._isTransact === true || (result._isTransact !== false && !method.constant); + var isTransact = contract._isTransact === true || (contract._isTransact !== false && !method.constant); var collapse = options.collapse !== false; // reset - result._options = {}; - result._isTransact = null; + contract._options = {}; + contract._isTransact = null; if (isTransact) { // it's used byt natspec.js @@ -142,40 +99,96 @@ var contract = function (address, desc) { return ret; }; - if (result[displayName] === undefined) { - result[displayName] = impl; + if (contract[displayName] === undefined) { + contract[displayName] = impl; } - result[displayName][typeName] = impl; - + contract[displayName][typeName] = impl; }); +}; - - // create contract events - abi.filterEvents(desc).forEach(function (event) { +var addEventRelatedPropertiesToContract = function (contract, desc, address) { + contract.address = address; - // TODO: rename these methods, cause they are used not only for methods - var displayName = abi.methodDisplayName(event.name); - var typeName = abi.methodTypeName(event.name); + Object.defineProperty(contract, 'topics', { + get: function() { + return abi.filterEvents(desc).map(function (e) { + return abi.methodSignature(e.name); + }); + } + }); +}; - var impl = function (options) { - var signature = abi.methodSignature(event.name); - var o = options || {}; - o.address = o.address || address; - o.topics = o.topics || []; - o.topics.push(signature); +var addEventsToContract = function (contract, desc, address) { + // create contract events + abi.filterEvents(desc).forEach(function (e) { + var impl = function () { + var params = Array.prototype.slice.call(arguments); + var signature = abi.methodSignature(e.name); + var eventImpl = eventImplementation(address, signature); + var o = eventImpl.apply(null, params); return web3.eth.watch(o); }; + + // TODO: rename these methods, cause they are used not only for methods + var displayName = abi.methodDisplayName(e.name); + var typeName = abi.methodTypeName(e.name); - if (result[displayName] === undefined) { - result[displayName] = impl; + if (contract[displayName] === undefined) { + contract[displayName] = impl; } - result[displayName][typeName] = impl; + contract[displayName][typeName] = impl; }); +}; + + +/** + * This method should be called when we want to call / transact some solidity method from javascript + * it returns an object which has same methods available as solidity contract description + * usage example: + * + * var abi = [{ + * name: 'myMethod', + * inputs: [{ name: 'a', type: 'string' }], + * outputs: [{name: 'd', type: 'string' }] + * }]; // contract abi + * + * var myContract = web3.eth.contract('0x0123123121', abi); // creation of contract object + * + * myContract.myMethod('this is test string param for call'); // myMethod call (implicit, default) + * myContract.call().myMethod('this is test string param for call'); // myMethod call (explicit) + * myContract.transact().myMethod('this is test string param for transact'); // myMethod transact + * + * @param address - address of the contract, which should be called + * @param desc - abi json description of the contract, which is being created + * @returns contract object + */ + +var contract = function (address, desc) { + + desc.forEach(function (method) { + // workaround for invalid assumption that method.name is the full anonymous prototype of the method. + // it's not. it's just the name. the rest of the code assumes it's actually the anonymous + // prototype, so we make it so as a workaround. + // TODO: we may not want to modify input params, maybe use copy instead? + if (method.name.indexOf('(') === -1) { + var displayName = method.name; + var typeName = method.inputs.map(function(i){return i.type; }).join(); + method.name = displayName + '(' + typeName + ')'; + } + }); + + + + var result = {}; + addFunctionRelatedPropertiesToContract(result); + addFunctionsToContract(result, desc, address); + addEventRelatedPropertiesToContract(result, desc, address); + addEventsToContract(result, desc, address); return result; }; diff --git a/lib/event.js b/lib/event.js index 724acde81..e8312ccdb 100644 --- a/lib/event.js +++ b/lib/event.js @@ -1,7 +1,7 @@ var abi = require('./abi'); -var implementationOfEvent = function (event, address, signature) { +var implementationOfEvent = function (address, signature) { return function (options) { var o = options || {}; -- cgit v1.2.3 From df17c338988260aab4db8f946076a67f3323caba Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Thu, 29 Jan 2015 15:05:43 +0100 Subject: event example --- lib/contract.js | 14 +++++++++++--- lib/event.js | 21 ++++++++++++++++++++- lib/filter.js | 13 +++++++++++++ 3 files changed, 44 insertions(+), 4 deletions(-) (limited to 'lib') diff --git a/lib/contract.js b/lib/contract.js index 58a67efe6..13c48ca10 100644 --- a/lib/contract.js +++ b/lib/contract.js @@ -22,7 +22,7 @@ var web3 = require('./web3'); var abi = require('./abi'); -var eventImplementation = require('./event'); +var eventImpl = require('./event'); var addFunctionRelatedPropertiesToContract = function (contract) { @@ -127,10 +127,18 @@ var addEventsToContract = function (contract, desc, address) { var impl = function () { var params = Array.prototype.slice.call(arguments); var signature = abi.methodSignature(e.name); - var eventImpl = eventImplementation(address, signature); - var o = eventImpl.apply(null, params); + var event = eventImpl(address, signature); + var o = event.apply(null, params); return web3.eth.watch(o); }; + + impl.address = address; + + Object.defineProperty(impl, 'topics', { + 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); diff --git a/lib/event.js b/lib/event.js index e8312ccdb..ae2195381 100644 --- a/lib/event.js +++ b/lib/event.js @@ -1,5 +1,24 @@ +/* + This file is part of ethereum.js. -var abi = require('./abi'); + 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 event.js + * @authors: + * Marek Kotewicz + * @date 2014 + */ var implementationOfEvent = function (address, signature) { diff --git a/lib/filter.js b/lib/filter.js index d93064b58..677b0657c 100644 --- a/lib/filter.js +++ b/lib/filter.js @@ -31,6 +31,19 @@ var Filter = function(options, impl) { this.impl = impl; this.callbacks = []; + if (typeof options !== "string") { + // evaluate lazy properties + options = { + to: options.to, + topics: options.topics, + earliest: options.earliest, + latest: options.latest, + max: options.max, + skip: options.skip, + address: options.address + }; + } + this.id = impl.newFilter(options); web3.provider.startPolling({call: impl.changed, args: [this.id]}, this.id, this.trigger.bind(this)); }; -- cgit v1.2.3 From 8613382869503c6123c3f47772bfdb192f6d3c76 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Thu, 29 Jan 2015 15:17:32 +0100 Subject: moved comment --- lib/contract.js | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'lib') diff --git a/lib/contract.js b/lib/contract.js index 13c48ca10..0bf3ee471 100644 --- a/lib/contract.js +++ b/lib/contract.js @@ -178,11 +178,11 @@ var addEventsToContract = function (contract, desc, address) { var contract = function (address, desc) { + // workaround for invalid assumption that method.name is the full anonymous prototype of the method. + // it's not. it's just the name. the rest of the code assumes it's actually the anonymous + // prototype, so we make it so as a workaround. + // TODO: we may not want to modify input params, maybe use copy instead? desc.forEach(function (method) { - // workaround for invalid assumption that method.name is the full anonymous prototype of the method. - // it's not. it's just the name. the rest of the code assumes it's actually the anonymous - // prototype, so we make it so as a workaround. - // TODO: we may not want to modify input params, maybe use copy instead? if (method.name.indexOf('(') === -1) { var displayName = method.name; var typeName = method.inputs.map(function(i){return i.type; }).join(); @@ -190,8 +190,6 @@ var contract = function (address, desc) { } }); - - var result = {}; addFunctionRelatedPropertiesToContract(result); addFunctionsToContract(result, desc, address); -- cgit v1.2.3