parent
9cf7b9b496
commit
c28ce1b86a
@ -1,123 +0,0 @@ |
|||||||
'use strict' |
|
||||||
var ethJSABI = require('ethereumjs-abi') |
|
||||||
var txHelper = require('../execution/txHelper') |
|
||||||
|
|
||||||
/** |
|
||||||
* Register to txListener and extract events |
|
||||||
* |
|
||||||
*/ |
|
||||||
class EventsDecoder { |
|
||||||
constructor (opt = {}) { |
|
||||||
this._api = opt.api |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* use Transaction Receipt to decode logs. assume that the transaction as already been resolved by txListener. |
|
||||||
* logs are decoded only if the contract if known by remix. |
|
||||||
* |
|
||||||
* @param {Object} tx - transaction object |
|
||||||
* @param {Function} cb - callback |
|
||||||
*/ |
|
||||||
parseLogs (tx, contractName, compiledContracts, cb) { |
|
||||||
if (tx.isCall) return cb(null, { decoded: [], raw: [] }) |
|
||||||
this._api.resolveReceipt(tx, (error, receipt) => { |
|
||||||
if (error) return cb(error) |
|
||||||
this._decodeLogs(tx, receipt, contractName, compiledContracts, cb) |
|
||||||
}) |
|
||||||
} |
|
||||||
|
|
||||||
_decodeLogs (tx, receipt, contract, contracts, cb) { |
|
||||||
if (!contract || !receipt) { |
|
||||||
return cb('cannot decode logs - contract or receipt not resolved ') |
|
||||||
} |
|
||||||
if (!receipt.logs) { |
|
||||||
return cb(null, { decoded: [], raw: [] }) |
|
||||||
} |
|
||||||
this._decodeEvents(tx, receipt.logs, contract, contracts, cb) |
|
||||||
} |
|
||||||
|
|
||||||
_eventABI (contract) { |
|
||||||
var eventABI = {} |
|
||||||
contract.abi.forEach(function (funABI, i) { |
|
||||||
if (funABI.type !== 'event') { |
|
||||||
return |
|
||||||
} |
|
||||||
var hash = ethJSABI.eventID(funABI.name, funABI.inputs.map(function (item) { return item.type })) |
|
||||||
eventABI[hash.toString('hex')] = { event: funABI.name, inputs: funABI.inputs } |
|
||||||
}) |
|
||||||
return eventABI |
|
||||||
} |
|
||||||
|
|
||||||
_eventsABI (compiledContracts) { |
|
||||||
var eventsABI = {} |
|
||||||
txHelper.visitContracts(compiledContracts, (contract) => { |
|
||||||
eventsABI[contract.name] = this._eventABI(contract.object) |
|
||||||
}) |
|
||||||
return eventsABI |
|
||||||
} |
|
||||||
|
|
||||||
_event (hash, eventsABI) { |
|
||||||
for (var k in eventsABI) { |
|
||||||
if (eventsABI[k][hash]) { |
|
||||||
return eventsABI[k][hash] |
|
||||||
} |
|
||||||
} |
|
||||||
return null |
|
||||||
} |
|
||||||
|
|
||||||
_decodeEvents (tx, logs, contractName, compiledContracts, cb) { |
|
||||||
var eventsABI = this._eventsABI(compiledContracts) |
|
||||||
var events = [] |
|
||||||
for (var i in logs) { |
|
||||||
// [address, topics, mem]
|
|
||||||
var log = logs[i] |
|
||||||
var topicId = log.topics[0] |
|
||||||
var abi = this._event(topicId.replace('0x', ''), eventsABI) |
|
||||||
if (abi) { |
|
||||||
var event |
|
||||||
try { |
|
||||||
var decoded = new Array(abi.inputs.length) |
|
||||||
event = abi.event |
|
||||||
var indexed = 1 |
|
||||||
var nonindexed = [] |
|
||||||
// decode indexed param
|
|
||||||
abi.inputs.map(function (item, index) { |
|
||||||
if (item.indexed) { |
|
||||||
var encodedData = log.topics[indexed].replace('0x', '') |
|
||||||
try { |
|
||||||
decoded[index] = ethJSABI.rawDecode([item.type], new Buffer(encodedData, 'hex'))[0] |
|
||||||
if (typeof decoded[index] !== 'string') { |
|
||||||
decoded[index] = ethJSABI.stringify([item.type], decoded[index]) |
|
||||||
} |
|
||||||
} catch (e) { |
|
||||||
decoded[index] = encodedData |
|
||||||
} |
|
||||||
indexed++ |
|
||||||
} else { |
|
||||||
nonindexed.push(item.type) |
|
||||||
} |
|
||||||
}) |
|
||||||
// decode non indexed param
|
|
||||||
var nonindexededResult = ethJSABI.rawDecode(nonindexed, new Buffer(log.data.replace('0x', ''), 'hex')) |
|
||||||
nonindexed = ethJSABI.stringify(nonindexed, nonindexededResult) |
|
||||||
// ordering
|
|
||||||
var j = 0 |
|
||||||
abi.inputs.map(function (item, index) { |
|
||||||
if (!item.indexed) { |
|
||||||
decoded[index] = nonindexed[j] |
|
||||||
j++ |
|
||||||
} |
|
||||||
}) |
|
||||||
} catch (e) { |
|
||||||
decoded = log.data |
|
||||||
} |
|
||||||
events.push({ topic: topicId, event: event, args: decoded }) |
|
||||||
} else { |
|
||||||
events.push({ data: log.data, topics: log.topics }) |
|
||||||
} |
|
||||||
} |
|
||||||
cb(null, { decoded: events, raw: logs }) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
module.exports = EventsDecoder |
|
Loading…
Reference in new issue