I interacted with a smart contract using Gnosis Safe and sent a transaction to the Sepolia network: https://sepolia.etherscan.io/tx/0xc0aab967e6f87fed78b6215f7ff02e2b661903f324a115ebc062b9308754002c

I need to programmatically decode the transaction to get the bytes data parameter from the execTransaction function so that I can decode the actual transaction data stored in the bytes data parameter.

I am using ethabi to decode the transaction and not having any luck. Can you provide guidance? Thanks!

New contributor
Thomas Hepner is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.

1 Answer 1


If you click on Decode Input Data on the explorer, the value of data param is:


So, using the first 4 bytes i.e., 0xcb836209, we can get the function signature using openchain.xyz as:


Now, you can get the ABI of addCredit() function from the contract corresponding to the to address param i.e., 0xD4f6d393A8299c3B80E03491e2B9CB03C00bdda9.

So, provided with the ABI of execTransaction() of GnosisSafe contract and the ABI of addCredit() function of SecuredLine contract, here is the minimal python script that you can use to decode the parameters:

from web3 import Web3

rpc_url = "https://ethereum-sepolia-rpc.publicnode.com"
web3 = Web3(Web3.HTTPProvider(rpc_url))

tx = web3.eth.get_transaction(

execTransaction_abi = [
        "inputs": [
            {"internalType": "address", "name": "to", "type": "address"},
            {"internalType": "uint256", "name": "value", "type": "uint256"},
            {"internalType": "bytes", "name": "data", "type": "bytes"},
            {"internalType": "uint8", "name": "operation", "type": "uint8"},
            {"internalType": "uint256", "name": "safeTxGas", "type": "uint256"},
            {"internalType": "uint256", "name": "baseGas", "type": "uint256"},
            {"internalType": "uint256", "name": "gasPrice", "type": "uint256"},
            {"internalType": "address", "name": "gasToken", "type": "address"},
            {"internalType": "address", "name": "refundReceiver", "type": "address"},
            {"internalType": "bytes", "name": "signatures", "type": "bytes"},
        "name": "execTransaction",
        "outputs": [],
        "stateMutability": "nonpayable",
        "type": "function",

gnosis_safe_contract = web3.eth.contract(abi=execTransaction_abi)
decoded_input = gnosis_safe_contract.decode_function_input(tx["input"])
decoded_function = decoded_input[0]
decoded_params = decoded_input[1]

bytes_data = decoded_params["data"]

addCredit_abi = [
        "inputs": [
            {"internalType": "uint128", "name": "drate", "type": "uint128"},
            {"internalType": "uint128", "name": "frate", "type": "uint128"},
            {"internalType": "uint256", "name": "amount", "type": "uint256"},
            {"internalType": "address", "name": "token", "type": "address"},
            {"internalType": "address", "name": "lender", "type": "address"},
        "name": "addCredit",
        "outputs": [{"internalType": "bytes32", "name": "", "type": "bytes32"}],
        "stateMutability": "payable",
        "type": "function",

contract = web3.eth.contract(abi=addCredit_abi)
decoded_input = contract.decode_function_input(bytes_data)

decoded_function = decoded_input[0]
decoded_params = decoded_input[1]

drate = decoded_params["drate"]
frate = decoded_params["frate"]
amount = decoded_params["amount"]
token = decoded_params["token"]
lender = decoded_params["lender"]

print("drate:", drate)
print("frate:", frate)
print("amount:", amount)
print("token:", token)
print("lender:", lender)


drate: 700
frate: 700
amount: 2000000000000
token: 0x1BF220B4e6E5ecA30D90a12ea369a68633c0065a
lender: 0x9D6a88Aec1B6894df4bCC08e28F6378CB06aD0a7

Your Answer

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

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