2

I'm facing some issue/bug on web3.py, I need to listen my event contract, but event logs are always empty. I know the following issue on Ganach-CLI but may be there is other alternative. I already tried the three followings solutions and no one works, have [] as output...

The new method with web3.py v4 :

my_filter = mycontract.events.<event_name>.createFilter({'fromBlock':0,'to':'latest'})
my_filter.get_all_entries()

The old method :

my_filter = mycontract.eventFilter('EventName',{'fromBlock':0,'toBlock':'latest'})
my_filter.get_all_entries()

And finally tried to build my own filter :

event_hexa = w3.sha3(text='EventTest(address indexed _seller, string indexed)').hex()
    
event_filter = w3.eth.filter({
'fromBlock':0,
'toBlock':'latest',
'address': mycontract_address,
'topics':[str(event_hexa)]
})

event_filter.get_all_entries()

So I would like to know if there are other way to listen events ? May be I missed out on something.
Or may be there is other test net provider than Ganach where feature to listen event is working ?

Thanks for the help !

2
  • Did not quite understand your question, but I can tell you how to decode an event with web3.py if you're interested. May 8, 2018 at 8:10
  • Sorry if I'm not very clear about what I'm asking, I just want to know if there is other way to listen events, than the three here, because actually it's not working for me. But I'm also interested to know how to decode event with web3.py !
    – Lbrth_BoC
    May 8, 2018 at 8:16

1 Answer 1

1

Here is how you can decode an event in web3.py:

def decode(hash,index,params):
    event = {}
    index1 = 1
    index2 = 2
    log = eth.getTransactionReceipt(hash)['logs'][index]
    for param in params:
        if param['indexed']:
            event[param['name']] = int(log['topics'][index1],16)
            index1 += 1
        else:
            size = param['size']//4
            event[param['name']] = int(log['data'][index2:index2+size],16)
            index2 += size
    return event

Where eth is your Web3.eth instance.

Usage example:

hash = mycontract.func(x)

index = 0

params = [
    {'name': 'addr', 'size': 160, 'indexed': True},
    {'name': 'input', 'size': 256, 'indexed': False},
    {'name': 'output', 'size': 256, 'indexed': False},
]

event = decode(hash, index, params)

addr = event['addr']
input = event['input']
output = event['output']

If more than one event is emitted during the execution of the contract's function, then use index to indicate the index of the specific event that you want to decode (I've used 0 in the example above, assuming that there's only one event).

8
  • Are you sure its ['data'] and not ['topics'] instead, in your decode function ? My ['data'] is equal to '0x0'.
    – Lbrth_BoC
    May 10, 2018 at 12:10
  • @Lbrth_BoC: Of course it is. All the variables in your event are indexed. Have a look at the decode function - it skips indexed variables for a good reason - they are not included in the data field. May 10, 2018 at 12:14
  • @Lbrth_BoC: But you've just made me realize that the function is perhaps incomplete, and that instead of skipping these variables, it may need to fetch them from some other field in the log... I will look into it... May 10, 2018 at 12:16
  • thanks for your quick reply ! but in my mind, all variables which are indexed are store inside ['topics'] fields of the log.
    – Lbrth_BoC
    May 10, 2018 at 12:39
  • 1
    @Lbrth_BoC: It seems that the indexed values are indeed stored under "topics". Moreover, each one of them is stored separately, so unlike the non-indexed values stored under "data", you don't even need to decode them. Just note that they start at the second place (i.e., ['logs'][logIndex]['topics'][0] holds something else, I'm not quite sure what). May 10, 2018 at 13:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.