event refactor in progress
This commit is contained in:
parent
99a3696e51
commit
ea6bda4cbb
|
@ -14,9 +14,9 @@
|
||||||
You should have received a copy of the GNU Lesser General Public License
|
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/>.
|
along with ethereum.js. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
/** @file contract.js
|
/**
|
||||||
* @authors:
|
* @file contract.js
|
||||||
* Marek Kotewicz <marek@ethdev.com>
|
* @author Marek Kotewicz <marek@ethdev.com>
|
||||||
* @date 2014
|
* @date 2014
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -27,23 +27,9 @@ var solUtils = require('../solidity/utils');
|
||||||
var eventImpl = require('./event');
|
var eventImpl = require('./event');
|
||||||
var signature = require('./signature');
|
var signature = require('./signature');
|
||||||
var SolidityFunction = require('./function');
|
var SolidityFunction = require('./function');
|
||||||
|
var SolidityEvent = eventImpl.SolidityEvent;
|
||||||
|
|
||||||
var addFunctionRelatedPropertiesToContract = function (contract) {
|
var addFunctionsToContract = function (contract, desc) {
|
||||||
|
|
||||||
contract.call = function (options) {
|
|
||||||
contract._isTransaction = false;
|
|
||||||
contract._options = options;
|
|
||||||
return contract;
|
|
||||||
};
|
|
||||||
|
|
||||||
contract.sendTransaction = function (options) {
|
|
||||||
contract._isTransaction = true;
|
|
||||||
contract._options = options;
|
|
||||||
return contract;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
var addFunctionsToContract = function (contract, desc, address) {
|
|
||||||
desc.filter(function (json) {
|
desc.filter(function (json) {
|
||||||
return json.type === 'function';
|
return json.type === 'function';
|
||||||
}).map(function (json) {
|
}).map(function (json) {
|
||||||
|
@ -71,34 +57,41 @@ var addEventRelatedPropertiesToContract = function (contract, desc, address) {
|
||||||
};
|
};
|
||||||
|
|
||||||
var addEventsToContract = function (contract, desc, address) {
|
var addEventsToContract = function (contract, desc, address) {
|
||||||
// create contract events
|
desc.filter(function (json) {
|
||||||
solUtils.filterEvents(desc).forEach(function (e) {
|
return json.type === 'event';
|
||||||
|
}).map(function (json) {
|
||||||
var impl = function () {
|
return new SolidityEvent(json, address);
|
||||||
var params = Array.prototype.slice.call(arguments);
|
}).forEach(function (e) {
|
||||||
var sign = signature.eventSignatureFromAscii(e.name);
|
e.attachToContract(contract);
|
||||||
var event = eventImpl.inputParser(address, sign, e);
|
|
||||||
var o = event.apply(null, params);
|
|
||||||
var outputFormatter = function (data) {
|
|
||||||
var parser = eventImpl.outputParser(e);
|
|
||||||
return parser(data);
|
|
||||||
};
|
|
||||||
return web3.eth.filter(o, undefined, undefined, outputFormatter);
|
|
||||||
};
|
|
||||||
|
|
||||||
// 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
contract[displayName][typeName] = impl;
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
// create contract events
|
||||||
|
//solUtils.filterEvents(desc).forEach(function (e) {
|
||||||
|
|
||||||
|
//var impl = function () {
|
||||||
|
//var params = Array.prototype.slice.call(arguments);
|
||||||
|
//var sign = signature.eventSignatureFromAscii(e.name);
|
||||||
|
//var event = eventImpl.inputParser(address, sign, e);
|
||||||
|
//var o = event.apply(null, params);
|
||||||
|
//var outputFormatter = function (data) {
|
||||||
|
//var parser = eventImpl.outputParser(e);
|
||||||
|
//return parser(data);
|
||||||
|
//};
|
||||||
|
//return web3.eth.filter(o, undefined, undefined, outputFormatter);
|
||||||
|
//};
|
||||||
|
|
||||||
|
//// 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;
|
||||||
|
//}
|
||||||
|
|
||||||
|
//contract[displayName][typeName] = impl;
|
||||||
|
|
||||||
|
//});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -145,6 +138,8 @@ var Contract = function (abi, options) {
|
||||||
});
|
});
|
||||||
|
|
||||||
this.address = '';
|
this.address = '';
|
||||||
|
this._isTransaction = null;
|
||||||
|
this._options = {};
|
||||||
if (utils.isAddress(options)) {
|
if (utils.isAddress(options)) {
|
||||||
this.address = options;
|
this.address = options;
|
||||||
} else { // is an object!
|
} else { // is an object!
|
||||||
|
@ -156,11 +151,22 @@ var Contract = function (abi, options) {
|
||||||
this.address = web3.eth.sendTransaction(options);
|
this.address = web3.eth.sendTransaction(options);
|
||||||
}
|
}
|
||||||
|
|
||||||
addFunctionRelatedPropertiesToContract(this);
|
addFunctionsToContract(this, abi);
|
||||||
addFunctionsToContract(this, abi, this.address);
|
|
||||||
addEventRelatedPropertiesToContract(this, abi, this.address);
|
addEventRelatedPropertiesToContract(this, abi, this.address);
|
||||||
addEventsToContract(this, abi, this.address);
|
addEventsToContract(this, abi, this.address);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Contract.prototype.call = function (options) {
|
||||||
|
this._isTransaction = false;
|
||||||
|
this._options = options;
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
Contract.prototype.sendTransaction = function (options) {
|
||||||
|
this._isTransaction = true;
|
||||||
|
this._options = options;
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
module.exports = contract;
|
module.exports = contract;
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,8 @@
|
||||||
var abi = require('../solidity/abi');
|
var abi = require('../solidity/abi');
|
||||||
var utils = require('../utils/utils');
|
var utils = require('../utils/utils');
|
||||||
var signature = require('./signature');
|
var signature = require('./signature');
|
||||||
|
var coder = require('../solidity/coder');
|
||||||
|
var web3 = require('../web3');
|
||||||
|
|
||||||
/// filter inputs array && returns only indexed (or not) inputs
|
/// filter inputs array && returns only indexed (or not) inputs
|
||||||
/// @param inputs array
|
/// @param inputs array
|
||||||
|
@ -128,11 +130,100 @@ var getMatchingEvent = function (events, payload) {
|
||||||
}
|
}
|
||||||
return undefined;
|
return undefined;
|
||||||
};
|
};
|
||||||
|
//////////
|
||||||
|
|
||||||
|
var SolidityEvent = function (json, address) {
|
||||||
|
this._params = json.inputs;
|
||||||
|
this._name = json.name;
|
||||||
|
this._address = address;
|
||||||
|
};
|
||||||
|
|
||||||
|
SolidityEvent.prototype.types = function (indexed) {
|
||||||
|
return this._params.filter(function (i) {
|
||||||
|
return i.indexed === indexed;
|
||||||
|
}).map(function (i) {
|
||||||
|
return i.type;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
SolidityEvent.prototype.displayName = function () {
|
||||||
|
return utils.extractDisplayName(this._name);
|
||||||
|
};
|
||||||
|
|
||||||
|
SolidityEvent.prototype.typeName = function () {
|
||||||
|
return utils.extractTypeName(this._name);
|
||||||
|
};
|
||||||
|
|
||||||
|
SolidityEvent.prototype.signature = function () {
|
||||||
|
return web3.sha3(web3.fromAscii(this._name)).slice(2);
|
||||||
|
};
|
||||||
|
|
||||||
|
SolidityEvent.prototype.encode = function (indexed, options) {
|
||||||
|
indexed = indexed || {};
|
||||||
|
options = options || {};
|
||||||
|
|
||||||
|
options.address = this._address;
|
||||||
|
options.topics = options.topics || [];
|
||||||
|
options.topics.push('0x' + this.signature());
|
||||||
|
|
||||||
|
var indexedTopics = this._params.filter(function (i) {
|
||||||
|
return i.indexed === true;
|
||||||
|
}).map(function (i) {
|
||||||
|
var value = indexed[i.name];
|
||||||
|
if (value !== undefined) {
|
||||||
|
return '0x' + coder.encodeParam(i.type, value);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
|
||||||
|
options.topics = options.topics.concat(indexedTopics);
|
||||||
|
|
||||||
|
return options;
|
||||||
|
};
|
||||||
|
|
||||||
|
SolidityEvent.prototype.decode = function (data) {
|
||||||
|
var result = {
|
||||||
|
event: this.displayName(),
|
||||||
|
number: data.number,
|
||||||
|
hash: data.hash,
|
||||||
|
args: {}
|
||||||
|
};
|
||||||
|
|
||||||
|
data.data = data.data || '';
|
||||||
|
|
||||||
|
var indexedData = data.topics.slice(1).map(function (topics) { return topics.slice(2); }).join("");
|
||||||
|
var indexedParams = coder.decodeParams(this.types(true), indexedData);
|
||||||
|
|
||||||
|
var notIndexedData = data.data.slice(2);
|
||||||
|
var notIndexedParams = coder.decodeParams(this.types(false), notIndexedData);
|
||||||
|
|
||||||
|
result.args = this._params.reduce(function (acc, current) {
|
||||||
|
acc[current.name] = current.indexed ? indexedParams.shift() : notIndexedParams.shift();
|
||||||
|
return acc;
|
||||||
|
}, {});
|
||||||
|
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
|
SolidityEvent.prototype.execute = function (indexed, options) {
|
||||||
|
var o = this.encode(indexed, options);
|
||||||
|
var formatter = this.decode.bind(this);
|
||||||
|
return web3.eth.filter(o, undefined, undefined, formatter);
|
||||||
|
};
|
||||||
|
|
||||||
|
SolidityEvent.prototype.attachToContract = function (contract) {
|
||||||
|
var execute = this.execute.bind(this);
|
||||||
|
var displayName = this.displayName();
|
||||||
|
if (!contract[displayName]) {
|
||||||
|
contract[displayName] = execute;
|
||||||
|
}
|
||||||
|
contract[displayName][this.typeName()] = this.execute.bind(this, contract);
|
||||||
|
};
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
inputParser: inputParser,
|
inputParser: inputParser,
|
||||||
outputParser: outputParser,
|
outputParser: outputParser,
|
||||||
getMatchingEvent: getMatchingEvent
|
getMatchingEvent: getMatchingEvent,
|
||||||
|
SolidityEvent: SolidityEvent
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -42,6 +42,9 @@ var getOptions = function (options) {
|
||||||
// make sure topics, get converted to hex
|
// make sure topics, get converted to hex
|
||||||
options.topics = options.topics || [];
|
options.topics = options.topics || [];
|
||||||
options.topics = options.topics.map(function(topic){
|
options.topics = options.topics.map(function(topic){
|
||||||
|
if (topic === null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
return utils.toHex(topic);
|
return utils.toHex(topic);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -63,7 +63,8 @@ describe('web3.eth.contract', function () {
|
||||||
assert.deepEqual(payload.params[0], {
|
assert.deepEqual(payload.params[0], {
|
||||||
topics: [
|
topics: [
|
||||||
sha3,
|
sha3,
|
||||||
'0x1234567890123456789012345678901234567890'
|
'0x1234567890123456789012345678901234567890',
|
||||||
|
null
|
||||||
],
|
],
|
||||||
address: '0x1234567890123456789012345678901234567890'
|
address: '0x1234567890123456789012345678901234567890'
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue