I need simply to get Transfer
data values from transaction with 1 log https://etherscan.io/tx/0x6465187a7bb43a6db42ee63e5f5cc30fb094393957a7f1ce6c08b5afddf3e0bc. It sends +7,601.747 LINK.
The problem is Etherscan's ABI returns different hex hash than in transaction receipt, that's why I can not decode and get amount in transaction. How to fix that? For example below I attached 2 more transactions witch success result.
As we see below, on last transaction topic[0]
is 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef
, but in ABI there are no topic with this hex! But we can see anyway Transfer()
topic e19260aff97b920c7df27010903aeb9c8d2be5d310a2c67824cf3f15396e4c16
in ABI and it has a little bit different params. How this can happen? Etherescan returns wrong ABI? How to fix it and get Transfer values? If I try to replace hex from that topic to correct, than in get_event_data(w3.codec, event_abi, log_)
I get error:
web3.exceptions.MismatchedABI: The event signature did not match the provided ABI
Output:
tx_hash=0xff8db775b90935b1ade58182054c0be04f613ea23f9e1df73a6114a726e76237
1) log['address']=0xf21661D0D1d76d3ECb8e1B9F1c923DBfffAe4097
-> topic hex=8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925 {'anonymous': False, 'inputs': [{'indexed': True, 'internalType': 'address', 'name': 'owner', 'type': 'address'}, {'indexed': True, 'internalType': 'address', 'name': 'spender', 'type': 'address'}, {'indexed': False, 'internalType': 'uint256', 'name': 'value', 'type': 'uint256'}], 'name': 'Approval', 'type': 'event'}
-> topic hex=bd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff {'anonymous': False, 'inputs': [{'indexed': True, 'internalType': 'bytes32', 'name': 'role', 'type': 'bytes32'}, {'indexed': True, 'internalType': 'bytes32', 'name': 'previousAdminRole', 'type': 'bytes32'}, {'indexed': True, 'internalType': 'bytes32', 'name': 'newAdminRole', 'type': 'bytes32'}], 'name': 'RoleAdminChanged', 'type': 'event'}
-> topic hex=2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d {'anonymous': False, 'inputs': [{'indexed': True, 'internalType': 'bytes32', 'name': 'role', 'type': 'bytes32'}, {'indexed': True, 'internalType': 'address', 'name': 'account', 'type': 'address'}, {'indexed': True, 'internalType': 'address', 'name': 'sender', 'type': 'address'}], 'name': 'RoleGranted', 'type': 'event'}
-> topic hex=f6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b {'anonymous': False, 'inputs': [{'indexed': True, 'internalType': 'bytes32', 'name': 'role', 'type': 'bytes32'}, {'indexed': True, 'internalType': 'address', 'name': 'account', 'type': 'address'}, {'indexed': True, 'internalType': 'address', 'name': 'sender', 'type': 'address'}], 'name': 'RoleRevoked', 'type': 'event'}
-> topic hex=ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef {'anonymous': False, 'inputs': [{'indexed': True, 'internalType': 'address', 'name': 'from', 'type': 'address'}, {'indexed': True, 'internalType': 'address', 'name': 'to', 'type': 'address'}, {'indexed': False, 'internalType': 'uint256', 'name': 'value', 'type': 'uint256'}], 'name': 'Transfer', 'type': 'event'}
searching topics[0]=0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef
Transfer 95352033474036727055914
------------------------------
tx_hash=0x7bdfe6c2a9309773ddeafddc2624edc2b38f13ec257182576d95d8b5f5ea2cd1
1) log['address']=0xe28b3B32B6c345A34Ff64674606124Dd5Aceca30
-> topic hex=8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925 {'anonymous': False, 'inputs': [{'indexed': True, 'internalType': 'address', 'name': 'owner', 'type': 'address'}, {'indexed': True, 'internalType': 'address', 'name': 'spender', 'type': 'address'}, {'indexed': False, 'internalType': 'uint256', 'name': 'value', 'type': 'uint256'}], 'name': 'Approval', 'type': 'event'}
-> topic hex=ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef {'anonymous': False, 'inputs': [{'indexed': True, 'internalType': 'address', 'name': 'from', 'type': 'address'}, {'indexed': True, 'internalType': 'address', 'name': 'to', 'type': 'address'}, {'indexed': False, 'internalType': 'uint256', 'name': 'value', 'type': 'uint256'}], 'name': 'Transfer', 'type': 'event'}
searching topics[0]=0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef
Transfer 29000000000000000000
------------------------------
tx_hash=0x6465187a7bb43a6db42ee63e5f5cc30fb094393957a7f1ce6c08b5afddf3e0bc
1) log['address']=0x514910771AF9Ca656af840dff83E8264EcF986CA
-> topic hex=e19260aff97b920c7df27010903aeb9c8d2be5d310a2c67824cf3f15396e4c16 {'anonymous': False, 'inputs': [{'indexed': True, 'name': 'from', 'type': 'address'}, {'indexed': True, 'name': 'to', 'type': 'address'}, {'indexed': False, 'name': 'value', 'type': 'uint256'}, {'indexed': False, 'name': 'data', 'type': 'bytes'}], 'name': 'Transfer', 'type': 'event'}
-> topic hex=8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925 {'anonymous': False, 'inputs': [{'indexed': True, 'name': 'owner', 'type': 'address'}, {'indexed': True, 'name': 'spender', 'type': 'address'}, {'indexed': False, 'name': 'value', 'type': 'uint256'}], 'name': 'Approval', 'type': 'event'}
searching topics[0]=0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef
ABI event not found!
Code:
# python 3.11.6
# web3==6.15.1
# eth-utils==4.0.0
# hexbytes==0.3.1
import requests
import json
from web3 import Web3
from web3._utils.events import get_event_data
from eth_utils import event_abi_to_log_topic
from hexbytes import HexBytes
import time
transactions = [
'0xff8db775b90935b1ade58182054c0be04f613ea23f9e1df73a6114a726e76237', # Transfer +95352033474036727055914 RIO
'0x7bdfe6c2a9309773ddeafddc2624edc2b38f13ec257182576d95d8b5f5ea2cd1', # Transfer +29000000000000000000 INJ
'0x6465187a7bb43a6db42ee63e5f5cc30fb094393957a7f1ce6c08b5afddf3e0bc', # ABI not found. But must be +7,601.747 LINK
]
testnet = 'https://eth.rpc.blxrbdn.com'
#testnet = 'https://eth.merkle.io'
w3 = Web3(Web3.HTTPProvider(testnet))
for t_hash in transactions:
print(f"tx_hash={t_hash}")
tx_receipt = w3.eth.get_transaction_receipt(t_hash)
for i, log in enumerate(tx_receipt['logs']):
print(f" {i+1}) log['address']={log['address']}")
abi = json.loads(json.loads(requests.get(f"https://api.etherscan.io/api?module=contract&action=getabi&address={log['address']}").text)['result'])
contract = w3.eth.contract(log["address"], abi=abi)
event_abi = [a for a in contract.abi if a["type"] == "event"]
for ea in event_abi:
print(f"-> topic hex={event_abi_to_log_topic(ea).hex()} {ea}")
topic2abi = {event_abi_to_log_topic(_): _ for _ in event_abi}
log_ = {
'address': None, #Web3.toChecksumAddress(address),
'blockHash': None, #HexBytes(blockHash),
'blockNumber': None,
'data': log['data'],
'logIndex': None,
'topics': [HexBytes(_) for _ in log["topics"]],
'transactionHash': None, #HexBytes(transactionHash),
'transactionIndex': None
}
try:
print(f"searching topics[0]={log['topics'][0].hex()}")
event_abi = topic2abi[log['topics'][0]]
data = get_event_data(w3.codec, event_abi, log_)['args']
print(f" {event_abi['name']} {data['value']}")
except KeyError as e:
exit('ABI event not found!')
print()
print('-'*30)
print()
time.sleep(2) # limits etherscan without API key