Альтернативы для прослушивания контракта Events с web3.py?

Я столкнулся с некоторой проблемой/ошибкой в ​​web3.py, мне нужно прослушать мой контракт событий, но журналы событий всегда пусты. Я знаю следующую проблему в Ganach-CLI , но может быть и другая альтернатива. Я уже пробовал три следующих решения, и ни одно из них не работает, []в качестве вывода...

Новый метод с web3.py v4:

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

Старый метод:

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

И, наконец, попытался создать свой собственный фильтр:

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()

Поэтому я хотел бы знать, есть ли другой способ прослушивания событий? Может быть, я что-то упустил.
Или, может быть, есть другой тестовый сетевой провайдер, кроме Ganach, где работает функция прослушивания событий?

Спасибо за помощь !

Не совсем понял ваш вопрос, но могу рассказать как декодировать событие с помощью web3.py если интересно.
Извините, если я не очень понимаю, о чем я спрашиваю, я просто хочу знать, есть ли другой способ прослушивания событий, кроме трех здесь, потому что на самом деле это не работает для меня. Но мне также интересно узнать, как декодировать событие с помощью web3.py!

Ответы (1)

Вот как вы можете декодировать событие в 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

Где ethтвой Web3.ethэкземпляр.

Пример использования:

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']

Если во время выполнения функции контракта генерируется более одного события, используйте indexдля указания индекса конкретного события, которое вы хотите декодировать (я использовал 0в приведенном выше примере, предполагая, что есть только одно событие).

Вы уверены, что это, ['data']а не ['topics']вместо этого, в вашей функции декодирования? Мой ['data']равен '0x0'.
@Lbrth_BoC: Конечно. Все переменные в вашем событии проиндексированы. Посмотрите на decodeфункцию - она ​​пропускает индексированные переменные по уважительной причине - они не включены в dataполе.
@Lbrth_BoC: Но вы только что дали мне понять, что функция, возможно, неполная, и что вместо того, чтобы пропускать эти переменные, ей может потребоваться получить их из какого-то другого поля в журнале... Я посмотрю на это...
Спасибо за быстрый ответ ! но, на мой взгляд, все индексируемые переменные хранятся внутри ['topics']полей журнала.
@Lbrth_BoC: Вы можете соответствующим образом изменить приведенный выше сценарий и посмотреть, работает ли он для вас. Я попробую то же самое на своей стороне...
@Lbrth_BoC: кажется, что проиндексированные значения действительно хранятся в "topics". Более того, каждое из них хранится отдельно, поэтому, в отличие от неиндексированных значений, хранящихся в "data", вам даже не нужно их декодировать. Сразу отмечу, что они стартуют со второго места (т.е. ['logs'][logIndex]['topics'][0]держат что-то еще, я не совсем уверен что).
да вы правы, я нашел способ ! Спасибо ! Все, что мне нужно, находится в topics, но я не могу восстановить прошлое событие (историческое). Я работаю не с хешем транзакции, а с пользовательским фильтром с адресом контракта.
Специально для этой задачи я собрал библиотеку Python, которая может быть вам полезна — github.com/iamdefinitelyahuman/eth-event