1

am trying to decode the Transaction Input Data using Etherscan API in Python, I tried different answers on this, but still can't do it. Maybe someone can Help me figure it out, my Code so far:

transactions_url = "https://api.etherscan.io/api?module=account&action=txlist&address=0x7666ca32ef844ff435506568f66d6de6792e8425&startblock=0&endblock=99999999&sort=asc&apikey={myApiKey}"
response = get(transactions_url)
data = response.json()["result"]
data.sort(key=lambda x: int(x["timeStamp"]))

for tx in data:
    inputdata = tx['input']
    print(inputdata)

My input Data is

 inputdata = 0x246bb536000000000000000000000000000000000000000000000000000023404b7778c00000000000000000000000000000000000000000000000000000000000000064

I want this to be Decoded into:

#   Name    Type    Data
0   _satoshiAmount  uint256 38759051000000
1   _duration   uint256 100
6
  • to do that, for each transaction, you need the ABI of smart contract that the transaction interacted with.
    – kfx
    Mar 25 at 20:19
  • thanks, do you have any example how to bind the abi of smart contract in this example please?
    – Ben
    Mar 25 at 20:22
  • different transactions interact with different smart contracts. to get the ABI for a specific smart contract, you can also use the Etherscan API.
    – kfx
    Mar 27 at 7:45
  • once you have the ABI, there's plenty of examples how to decode the Tx data using the ABI.
    – kfx
    Mar 27 at 7:47
  • thanks for your answers, but I posted this question because I didn't find any example that explains it, tried different examples but none worked, i don't want to use infura or any other 3rd party api, wanted to solve it only with Etherscan API
    – Ben
    Mar 28 at 10:20

2 Answers 2

2

It's not perfect, but it'll get you the data you're looking for without needing to connect to a provider node. Answer edited to retrieve the ABI from Etherscan in the code.

import json
from requests import get
from web3 import Web3
from other_file import ETHERSCAN_API_KEY

ADDRESS = "0x7666ca32ef844ff435506568f66d6de6792e8425"

abi_url = f"https://api.etherscan.io/api?module=contract&action=getabi&address={ADDRESS}&apikey={ETHERSCAN_API_KEY}"
abi_response = get(abi_url)
abi_str = abi_response.json()["result"]
abi = json.loads(abi_str)

w3 = Web3()
contract = w3.eth.contract(address=ADDRESS, abi=abi)

transactions_url = f"https://api.etherscan.io/api?module=account&action=txlist&address={ADDRESS}&startblock=0&endblock=99999999&sort=asc&apikey={ETHERSCAN_API_KEY}"
response = get(transactions_url)
data = response.json()["result"]
data.sort(key=lambda x: int(x["timeStamp"]))

for tx in data:
    inputdata = tx['input']
    try:
        _function_object, function_params = contract.decode_function_input(inputdata)
        print(function_params)
    except:
        print('unable to decode')

This will print out dicts of the data you're looking for. You can format it as you like from there.

1
  • 1
    Thanks a lot for your answer, I tried the code but I am having problems with Importing from web3 import Web3, I get the following Error: ImportError: cannot import name 'Web3' from partially initialized module 'web3' (most likely due to a circular import)
    – Ben
    Apr 5 at 19:06
2

Thanks a lot for your answer @pacrob, I changed my Code according to your answer. I got rid of that circular Import error, by changing the name of the .py file into "bla.py", then I run into an Address Checksum Error, I fixed that by adding w3.to_checksum_address(ADDRESS):

>     w3 = Web3()
>     dbAddress = w3.to_checksum_address(ADDRESS)
>     contract = w3.eth.contract(address=dbAddress, abi=abi)

Now everything is working. Great thanks

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.