From 504beeb2f321c6c35cfcc3edfff1669bdebc939b Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Wed, 4 Oct 2017 13:30:00 +0300 Subject: Add filtering by topic --- src/contract_wrappers/contract_wrapper.ts | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) (limited to 'src/contract_wrappers') diff --git a/src/contract_wrappers/contract_wrapper.ts b/src/contract_wrappers/contract_wrapper.ts index 6f074a976..7732f2f50 100644 --- a/src/contract_wrappers/contract_wrapper.ts +++ b/src/contract_wrappers/contract_wrapper.ts @@ -1,5 +1,6 @@ import * as _ from 'lodash'; import * as Web3 from 'web3'; +import * as ethUtil from 'ethereumjs-util'; import {Web3Wrapper} from '../web3_wrapper'; import {AbiDecoder} from '../utils/abi_decoder'; import { @@ -13,6 +14,8 @@ import { } from '../types'; import {utils} from '../utils/utils'; +const TOPIC_LENGTH = 32; + export class ContractWrapper { protected _web3Wrapper: Web3Wrapper; private _abiDecoder?: AbiDecoder; @@ -23,11 +26,11 @@ export class ContractWrapper { protected async _getLogsAsync(address: string, eventName: ContractEvents, subscriptionOpts: SubscriptionOpts, indexFilterValues: IndexedFilterValues, abi: Web3.ContractAbi): Promise { - // TODO include indexFilterValues in topics - const eventAbi = _.find(abi, {name: eventName}) as Web3.EventAbi; + const eventAbi = _.filter(abi, {name: eventName})[0] as Web3.EventAbi; const eventSignature = this._getEventSignatureFromAbiByName(eventAbi, eventName); const topicForEventSignature = this._web3Wrapper.keccak256(eventSignature); - const topics = [topicForEventSignature]; + const topicsForIndexedArgs = this._getTopicsForIndexedArgs(eventAbi, indexFilterValues); + const topics = [topicForEventSignature, ...topicsForIndexedArgs]; const filter = { fromBlock: subscriptionOpts.fromBlock, toBlock: subscriptionOpts.toBlock, @@ -57,4 +60,21 @@ export class ContractWrapper { const signature = `${eventAbi.name}(${types.join(',')})`; return signature; } + private _getTopicsForIndexedArgs(abi: Web3.EventAbi, indexFilterValues: IndexedFilterValues): Array { + const topics: Array = []; + for (const eventInput of abi.inputs) { + if (eventInput.indexed) { + if (_.isUndefined(indexFilterValues[eventInput.name])) { + topics.push(null); + } else { + const value = indexFilterValues[eventInput.name] as string; + const buffer = ethUtil.toBuffer(value); + const paddedBuffer = ethUtil.setLengthLeft(buffer, TOPIC_LENGTH); + const topic = ethUtil.bufferToHex(paddedBuffer); + topics.push(topic); + } + } + } + return topics; + } } -- cgit v1.2.3