1

Here is transaction https://etherscan.io/tx/0x1a70dafba58e5cbc10adecb18e2489613b298a4aab0ecb2cbbbfd2ba184cdc39

It makes Swap 0.095 ETH for 1,125.066 VDO on Uniswap V2. If to scroll down, press More details and press Decode input data, we will get this: enter image description here

The questions are

  1. How to decode already decoded input data? As we see in decoded input, there are still hex strings. How can I get useful information about it?
  2. How by get_transaction() I can understand that it makes swap 0.095 ETH for 1,125.066 VDO not calling get_transaction_receipt()? I suppose it's possible because of MEV front running attacks: they listen pending transactions and understand what swap makes.

The same decoded input I see via https://lab.miguelmota.com/ethereum-input-data-decoder/example/.

Uniswap V2 ABI (from etherscan api):

[{"inputs": [{"components": [{"internalType": "address", "name": "permit2", "type": "address"}, {"internalType": "address", "name": "weth9", "type": "address"}, {"internalType": "address", "name": "seaportV1_5", "type": "address"}, {"internalType": "address", "name": "seaportV1_4", "type": "address"}, {"internalType": "address", "name": "openseaConduit", "type": "address"}, {"internalType": "address", "name": "nftxZap", "type": "address"}, {"internalType": "address", "name": "x2y2", "type": "address"}, {"internalType": "address", "name": "foundation", "type": "address"}, {"internalType": "address", "name": "sudoswap", "type": "address"}, {"internalType": "address", "name": "elementMarket", "type": "address"}, {"internalType": "address", "name": "nft20Zap", "type": "address"}, {"internalType": "address", "name": "cryptopunks", "type": "address"}, {"internalType": "address", "name": "looksRareV2", "type": "address"}, {"internalType": "address", "name": "routerRewardsDistributor", "type": "address"}, {"internalType": "address", "name": "looksRareRewardsDistributor", "type": "address"}, {"internalType": "address", "name": "looksRareToken", "type": "address"}, {"internalType": "address", "name": "v2Factory", "type": "address"}, {"internalType": "address", "name": "v3Factory", "type": "address"}, {"internalType": "bytes32", "name": "pairInitCodeHash", "type": "bytes32"}, {"internalType": "bytes32", "name": "poolInitCodeHash", "type": "bytes32"}], "internalType": "struct RouterParameters", "name": "params", "type": "tuple"}], "stateMutability": "nonpayable", "type": "constructor"}, {"inputs": [], "name": "BalanceTooLow", "type": "error"}, {"inputs": [], "name": "BuyPunkFailed", "type": "error"}, {"inputs": [], "name": "ContractLocked", "type": "error"}, {"inputs": [], "name": "ETHNotAccepted", "type": "error"}, {"inputs": [{"internalType": "uint256", "name": "commandIndex", "type": "uint256"}, {"internalType": "bytes", "name": "message", "type": "bytes"}], "name": "ExecutionFailed", "type": "error"}, {"inputs": [], "name": "FromAddressIsNotOwner", "type": "error"}, {"inputs": [], "name": "InsufficientETH", "type": "error"}, {"inputs": [], "name": "InsufficientToken", "type": "error"}, {"inputs": [], "name": "InvalidBips", "type": "error"}, {"inputs": [{"internalType": "uint256", "name": "commandType", "type": "uint256"}], "name": "InvalidCommandType", "type": "error"}, {"inputs": [], "name": "InvalidOwnerERC1155", "type": "error"}, {"inputs": [], "name": "InvalidOwnerERC721", "type": "error"}, {"inputs": [], "name": "InvalidPath", "type": "error"}, {"inputs": [], "name": "InvalidReserves", "type": "error"}, {"inputs": [], "name": "InvalidSpender", "type": "error"}, {"inputs": [], "name": "LengthMismatch", "type": "error"}, {"inputs": [], "name": "SliceOutOfBounds", "type": "error"}, {"inputs": [], "name": "TransactionDeadlinePassed", "type": "error"}, {"inputs": [], "name": "UnableToClaim", "type": "error"}, {"inputs": [], "name": "UnsafeCast", "type": "error"}, {"inputs": [], "name": "V2InvalidPath", "type": "error"}, {"inputs": [], "name": "V2TooLittleReceived", "type": "error"}, {"inputs": [], "name": "V2TooMuchRequested", "type": "error"}, {"inputs": [], "name": "V3InvalidAmountOut", "type": "error"}, {"inputs": [], "name": "V3InvalidCaller", "type": "error"}, {"inputs": [], "name": "V3InvalidSwap", "type": "error"}, {"inputs": [], "name": "V3TooLittleReceived", "type": "error"}, {"inputs": [], "name": "V3TooMuchRequested", "type": "error"}, {"anonymous": false, "inputs": [{"indexed": false, "internalType": "uint256", "name": "amount", "type": "uint256"}], "name": "RewardsSent", "type": "event"}, {"inputs": [{"internalType": "bytes", "name": "looksRareClaim", "type": "bytes"}], "name": "collectRewards", "outputs": [], "stateMutability": "nonpayable", "type": "function"}, {"inputs": [{"internalType": "bytes", "name": "commands", "type": "bytes"}, {"internalType": "bytes[]", "name": "inputs", "type": "bytes[]"}], "name": "execute", "outputs": [], "stateMutability": "payable", "type": "function"}, {"inputs": [{"internalType": "bytes", "name": "commands", "type": "bytes"}, {"internalType": "bytes[]", "name": "inputs", "type": "bytes[]"}, {"internalType": "uint256", "name": "deadline", "type": "uint256"}], "name": "execute", "outputs": [], "stateMutability": "payable", "type": "function"}, {"inputs": [{"internalType": "address", "name": "", "type": "address"}, {"internalType": "address", "name": "", "type": "address"}, {"internalType": "uint256[]", "name": "", "type": "uint256[]"}, {"internalType": "uint256[]", "name": "", "type": "uint256[]"}, {"internalType": "bytes", "name": "", "type": "bytes"}], "name": "onERC1155BatchReceived", "outputs": [{"internalType": "bytes4", "name": "", "type": "bytes4"}], "stateMutability": "pure", "type": "function"}, {"inputs": [{"internalType": "address", "name": "", "type": "address"}, {"internalType": "address", "name": "", "type": "address"}, {"internalType": "uint256", "name": "", "type": "uint256"}, {"internalType": "uint256", "name": "", "type": "uint256"}, {"internalType": "bytes", "name": "", "type": "bytes"}], "name": "onERC1155Received", "outputs": [{"internalType": "bytes4", "name": "", "type": "bytes4"}], "stateMutability": "pure", "type": "function"}, {"inputs": [{"internalType": "address", "name": "", "type": "address"}, {"internalType": "address", "name": "", "type": "address"}, {"internalType": "uint256", "name": "", "type": "uint256"}, {"internalType": "bytes", "name": "", "type": "bytes"}], "name": "onERC721Received", "outputs": [{"internalType": "bytes4", "name": "", "type": "bytes4"}], "stateMutability": "pure", "type": "function"}, {"inputs": [{"internalType": "bytes4", "name": "interfaceId", "type": "bytes4"}], "name": "supportsInterface", "outputs": [{"internalType": "bool", "name": "", "type": "bool"}], "stateMutability": "pure", "type": "function"}, {"inputs": [{"internalType": "int256", "name": "amount0Delta", "type": "int256"}, {"internalType": "int256", "name": "amount1Delta", "type": "int256"}, {"internalType": "bytes", "name": "data", "type": "bytes"}], "name": "uniswapV3SwapCallback", "outputs": [], "stateMutability": "nonpayable", "type": "function"}, {"stateMutability": "payable", "type": "receive"}]

Input data:

0x3593564c000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000065b5aaff00000000000000000000000000000000000000000000000000000000000000020b080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000015181ff25a9800000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000015181ff25a98000000000000000000000000000000000000000000000000038fffe2035cb3abf9300000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000002ef8a2ccb058915e00e16aa13cc6e36f19d8893b

Output:

{
  "method": "execute",
  "types": [
    "bytes",
    "bytes[]",
    "uint256"
  ],
  "inputs": [
    "0x0b08",
    [
      "0x0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000015181ff25a98000",
      "0x0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000015181ff25a98000000000000000000000000000000000000000000000000038fffe2035cb3abf9300000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000002ef8a2ccb058915e00e16aa13cc6e36f19d8893b"
    ],
    {
      "type": "BigNumber",
      "hex": "0x65b5aaff"
    }
  ],
  "names": [
    "commands",
    "inputs",
    "deadline"
  ]
}

python code to get transaction and decode:

from web3 import Web3
import json
from pprint import pprint

# testnet = 'https://eth.rpc.blxrbdn.com'
testnet = 'https://eth.merkle.io'

w3 = Web3(Web3.HTTPProvider(testnet))
tx = w3.eth.get_transaction("0x1a70dafba58e5cbc10adecb18e2489613b298a4aab0ecb2cbbbfd2ba184cdc39")
pprint(dict(tx))

uniswap_v2_abi = json.loads('[{"inputs": [{"components": [{"internalType": "address", "name": "permit2", "type": "address"}, {"internalType": "address", "name": "weth9", "type": "address"}, {"internalType": "address", "name": "seaportV1_5", "type": "address"}, {"internalType": "address", "name": "seaportV1_4", "type": "address"}, {"internalType": "address", "name": "openseaConduit", "type": "address"}, {"internalType": "address", "name": "nftxZap", "type": "address"}, {"internalType": "address", "name": "x2y2", "type": "address"}, {"internalType": "address", "name": "foundation", "type": "address"}, {"internalType": "address", "name": "sudoswap", "type": "address"}, {"internalType": "address", "name": "elementMarket", "type": "address"}, {"internalType": "address", "name": "nft20Zap", "type": "address"}, {"internalType": "address", "name": "cryptopunks", "type": "address"}, {"internalType": "address", "name": "looksRareV2", "type": "address"}, {"internalType": "address", "name": "routerRewardsDistributor", "type": "address"}, {"internalType": "address", "name": "looksRareRewardsDistributor", "type": "address"}, {"internalType": "address", "name": "looksRareToken", "type": "address"}, {"internalType": "address", "name": "v2Factory", "type": "address"}, {"internalType": "address", "name": "v3Factory", "type": "address"}, {"internalType": "bytes32", "name": "pairInitCodeHash", "type": "bytes32"}, {"internalType": "bytes32", "name": "poolInitCodeHash", "type": "bytes32"}], "internalType": "struct RouterParameters", "name": "params", "type": "tuple"}], "stateMutability": "nonpayable", "type": "constructor"}, {"inputs": [], "name": "BalanceTooLow", "type": "error"}, {"inputs": [], "name": "BuyPunkFailed", "type": "error"}, {"inputs": [], "name": "ContractLocked", "type": "error"}, {"inputs": [], "name": "ETHNotAccepted", "type": "error"}, {"inputs": [{"internalType": "uint256", "name": "commandIndex", "type": "uint256"}, {"internalType": "bytes", "name": "message", "type": "bytes"}], "name": "ExecutionFailed", "type": "error"}, {"inputs": [], "name": "FromAddressIsNotOwner", "type": "error"}, {"inputs": [], "name": "InsufficientETH", "type": "error"}, {"inputs": [], "name": "InsufficientToken", "type": "error"}, {"inputs": [], "name": "InvalidBips", "type": "error"}, {"inputs": [{"internalType": "uint256", "name": "commandType", "type": "uint256"}], "name": "InvalidCommandType", "type": "error"}, {"inputs": [], "name": "InvalidOwnerERC1155", "type": "error"}, {"inputs": [], "name": "InvalidOwnerERC721", "type": "error"}, {"inputs": [], "name": "InvalidPath", "type": "error"}, {"inputs": [], "name": "InvalidReserves", "type": "error"}, {"inputs": [], "name": "InvalidSpender", "type": "error"}, {"inputs": [], "name": "LengthMismatch", "type": "error"}, {"inputs": [], "name": "SliceOutOfBounds", "type": "error"}, {"inputs": [], "name": "TransactionDeadlinePassed", "type": "error"}, {"inputs": [], "name": "UnableToClaim", "type": "error"}, {"inputs": [], "name": "UnsafeCast", "type": "error"}, {"inputs": [], "name": "V2InvalidPath", "type": "error"}, {"inputs": [], "name": "V2TooLittleReceived", "type": "error"}, {"inputs": [], "name": "V2TooMuchRequested", "type": "error"}, {"inputs": [], "name": "V3InvalidAmountOut", "type": "error"}, {"inputs": [], "name": "V3InvalidCaller", "type": "error"}, {"inputs": [], "name": "V3InvalidSwap", "type": "error"}, {"inputs": [], "name": "V3TooLittleReceived", "type": "error"}, {"inputs": [], "name": "V3TooMuchRequested", "type": "error"}, {"anonymous": false, "inputs": [{"indexed": false, "internalType": "uint256", "name": "amount", "type": "uint256"}], "name": "RewardsSent", "type": "event"}, {"inputs": [{"internalType": "bytes", "name": "looksRareClaim", "type": "bytes"}], "name": "collectRewards", "outputs": [], "stateMutability": "nonpayable", "type": "function"}, {"inputs": [{"internalType": "bytes", "name": "commands", "type": "bytes"}, {"internalType": "bytes[]", "name": "inputs", "type": "bytes[]"}], "name": "execute", "outputs": [], "stateMutability": "payable", "type": "function"}, {"inputs": [{"internalType": "bytes", "name": "commands", "type": "bytes"}, {"internalType": "bytes[]", "name": "inputs", "type": "bytes[]"}, {"internalType": "uint256", "name": "deadline", "type": "uint256"}], "name": "execute", "outputs": [], "stateMutability": "payable", "type": "function"}, {"inputs": [{"internalType": "address", "name": "", "type": "address"}, {"internalType": "address", "name": "", "type": "address"}, {"internalType": "uint256[]", "name": "", "type": "uint256[]"}, {"internalType": "uint256[]", "name": "", "type": "uint256[]"}, {"internalType": "bytes", "name": "", "type": "bytes"}], "name": "onERC1155BatchReceived", "outputs": [{"internalType": "bytes4", "name": "", "type": "bytes4"}], "stateMutability": "pure", "type": "function"}, {"inputs": [{"internalType": "address", "name": "", "type": "address"}, {"internalType": "address", "name": "", "type": "address"}, {"internalType": "uint256", "name": "", "type": "uint256"}, {"internalType": "uint256", "name": "", "type": "uint256"}, {"internalType": "bytes", "name": "", "type": "bytes"}], "name": "onERC1155Received", "outputs": [{"internalType": "bytes4", "name": "", "type": "bytes4"}], "stateMutability": "pure", "type": "function"}, {"inputs": [{"internalType": "address", "name": "", "type": "address"}, {"internalType": "address", "name": "", "type": "address"}, {"internalType": "uint256", "name": "", "type": "uint256"}, {"internalType": "bytes", "name": "", "type": "bytes"}], "name": "onERC721Received", "outputs": [{"internalType": "bytes4", "name": "", "type": "bytes4"}], "stateMutability": "pure", "type": "function"}, {"inputs": [{"internalType": "bytes4", "name": "interfaceId", "type": "bytes4"}], "name": "supportsInterface", "outputs": [{"internalType": "bool", "name": "", "type": "bool"}], "stateMutability": "pure", "type": "function"}, {"inputs": [{"internalType": "int256", "name": "amount0Delta", "type": "int256"}, {"internalType": "int256", "name": "amount1Delta", "type": "int256"}, {"internalType": "bytes", "name": "data", "type": "bytes"}], "name": "uniswapV3SwapCallback", "outputs": [], "stateMutability": "nonpayable", "type": "function"}, {"stateMutability": "payable", "type": "receive"}]')
contract = w3.eth.contract(address=tx["to"], abi=uniswap_v2_abi)
func_obj, func_params = contract.decode_function_input(tx["input"])

print('func_obj:')
print(func_obj)

print('func_params:')
print(func_params)

output:

{'accessList': [],
 'blockHash': HexBytes('0x6ee9e0c8a714b81f8444a3ab8e4444f681cea6dba83ee2a91ac8809edc5cd2d9'),
 'blockNumber': 19101665,
 'chainId': 1,
 'from': '0x7Fc81933624f44F0e6464f015a8F3Bdcd50cbEd3',
 'gas': 238792,
 'gasPrice': 12090651376,
 'hash': HexBytes('0x1a70dafba58e5cbc10adecb18e2489613b298a4aab0ecb2cbbbfd2ba184cdc39'),
 'input': HexBytes('0x3593564c000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000065b5aaff00000000000000000000000000000000000000000000000000000000000000020b080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000015181ff25a9800000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000015181ff25a98000000000000000000000000000000000000000000000000038fffe2035cb3abf9300000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000002ef8a2ccb058915e00e16aa13cc6e36f19d8893b'),
 'maxFeePerGas': 15063049570,
 'maxPriorityFeePerGas': 100000000,
 'nonce': 0,
 'r': HexBytes('0x7dd947bc38fdccaaa7d2c829de722bd4adeb242b3f75af089c5fc92ecd6a86c6'),
 's': HexBytes('0x73fe2db03f722cd91878d4245bcca78d1ee07dd85c9037f84f6c79adde547b46'),
 'to': '0x3fC91A3afd70395Cd496C647d5a6CC9D4B2b7FAD',
 'transactionIndex': 140,
 'type': 2,
 'v': 0,
 'value': 95000000000000000,
 'yParity': 0}
func_obj:
<Function execute(bytes,bytes[],uint256)>
func_params:
{'commands': b'\x0b\x08', 'inputs': [b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01Q\x81\xff%\xa9\x80\x00', b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01Q\x81\xff%\xa9\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x008\xff\xfe 5\xcb:\xbf\x93\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc0*\xaa9\xb2#\xfe\x8d\n\x0e\\O'\xea\xd9\x08<ul\xc2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00.\xf8\xa2\xcc\xb0X\x91^\x00\xe1j\xa1<\xc6\xe3o\x19\xd8\x89;"], 'deadline': 1706404607}

1 Answer 1

1

Depending on the commands parameter the inputs parameter elements should be decoded in different way ( check the Dispatcher.sol contract ).

For example the inputs in this specific transaction can be decoded like this:

const { ethers } = require("ethers");
const AbiCoder = new ethers.AbiCoder();

console.log(AbiCoder.decode(['address', 'uint256'], '0x0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000015181ff25a98000'));
console.log(AbiCoder.decode(['address', 'uint256', 'uint256', 'bytes', 'bool'], '0x0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000015181ff25a98000000000000000000000000000000000000000000000000038fffe2035cb3abf9300000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000002ef8a2ccb058915e00e16aa13cc6e36f19d8893b'));

I'm sharing how it could be done with ethers.js since I don't use the python's web3 lib, but now you know what analog to seek for. This specific script that I share returns the following output:

Result(2) [
  '0x0000000000000000000000000000000000000002',
  95000000000000000n
]
Result(5) [
  '0x0000000000000000000000000000000000000001',
  95000000000000000n,
  1051463884666906001299n,
  '0x0000',
  false
]
2
  • 1
    You can use eth-abi's decode function to achieve the same in Python. eth-abi.readthedocs.io/en/stable/decoding.html
    – pacrob
    Commented Feb 20 at 14:23
  • You put ['address', 'uint256'] in decode() function as input param. But in my example I have b'\x0b\x08'. How to solve this?
    – sirjay
    Commented Feb 24 at 19:16

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.