如何用Python解码Uniswap V3 Router 2的交易数据?
Uniswap V3 Router2交易数据解码方案
1. 核心问题定位
Web3的decode_function_input失效,本质是使用的ABI不完整或未包含目标函数定义。你的交易数据前4字节0x5ae401dc对应Uniswap V3 Router2的exactInput函数,该函数的参数是一个包含path字节数组的结构体,必须在ABI中明确结构体定义才能完成解码。
2. 解决方案步骤
第一步:使用正确的ABI
确保ABI包含exactInput函数及对应结构体的定义,以下是关键ABI片段:
[ { "inputs": [ { "components": [ { "internalType": "bytes", "name": "path", "type": "bytes" }, { "internalType": "address", "name": "recipient", "type": "address" }, { "internalType": "uint256", "name": "deadline", "type": "uint256" }, { "internalType": "uint256", "name": "amountIn", "type": "uint256" }, { "internalType": "uint256", "name": "amountOutMinimum", "type": "uint256" }, { "internalType": "uint160", "name": "sqrtPriceLimitX96", "type": "uint160" } ], "internalType": "struct ISwapRouter.ExactInputParams", "name": "params", "type": "tuple" } ], "name": "exactInput", "outputs": [ { "internalType": "uint256", "name": "amountOut", "type": "uint256" } ], "stateMutability": "payable", "type": "function" } ]
第二步:完整解码与路径解析
使用正确ABI解码后,需进一步解析path字节数组提取交易路径中的代币地址和手续费层级,完整代码示例如下:
from web3 import Web3 # 初始化Web3实例 w3 = Web3(Web3.HTTPProvider('你的RPC节点地址')) # Router2地址与交易数据 router_address = "0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45" tx_data = "0x5ae401dc0000000000000000000000000000000000000000000000000000000063bd8fab00000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000e404e45aaf000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000000000000000000000000000000000000000001f4000000000000000000000000dc06b8c890e100ba78888fede3d0c4bc769f41b400000000000000000000000000000000000000000000000000b08416c4bb7d2e0000000000000000000000000000000000000000000000000000000003eb71f4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" # 导入正确的ABI片段 abi = [ { "inputs": [ { "components": [ { "internalType": "bytes", "name": "path", "type": "bytes" }, { "internalType": "address", "name": "recipient", "type": "address" }, { "internalType": "uint256", "name": "deadline", "type": "uint256" }, { "internalType": "uint256", "name": "amountIn", "type": "uint256" }, { "internalType": "uint256", "name": "amountOutMinimum", "type": "uint256" }, { "internalType": "uint160", "name": "sqrtPriceLimitX96", "type": "uint160" } ], "internalType": "struct ISwapRouter.ExactInputParams", "name": "params", "type": "tuple" } ], "name": "exactInput", "outputs": [ { "internalType": "uint256", "name": "amountOut", "type": "uint256" } ], "stateMutability": "payable", "type": "function" } ] # 解码交易输入数据 contract_instance = w3.eth.contract(address=router_address, abi=abi) func_obj, func_params = contract_instance.decode_function_input(tx_data) # 解析Uniswap V3路径字节数组 def parse_uniswap_v3_path(path_bytes): path = [] current_index = 0 # 路径格式:代币地址(20字节) + 手续费(3字节) + 代币地址(20字节) + [手续费+代币地址]... while current_index < len(path_bytes): # 提取代币地址 token_addr = w3.to_checksum_address(path_bytes[current_index:current_index+20].hex()) path.append(token_addr) current_index += 20 # 提取手续费(若剩余字节足够) if current_index + 3 <= len(path_bytes): fee = int.from_bytes(path_bytes[current_index:current_index+3], byteorder='big') path.append(f"手续费: {fee}") current_index += 3 return path # 输出解码结果 path = parse_uniswap_v3_path(func_params['params']['path']) print("解码后的交易参数:") print(f"调用函数: {func_obj.fn_name}") print(f"接收地址: {func_params['params']['recipient']}") print(f"交易截止时间: {func_params['params']['deadline']}") print(f"输入金额: {func_params['params']['amountIn']}") print(f"最小输出金额: {func_params['params']['amountOutMinimum']}") print(f"价格限制: {func_params['params']['sqrtPriceLimitX96']}") print(f"完整交易路径: {' -> '.join(path)}")
3. 关键说明
- 函数签名匹配:必须确保ABI中包含交易数据对应函数的完整定义(包括结构体参数),否则解码会失败。
- 路径解析逻辑:Uniswap V3的
path字节数组遵循固定格式,通过逐段截取20字节的地址和3字节的手续费,即可还原完整交易路径。 - 兼容性扩展:该方法可适配Uniswap V3的其他swap函数(如
exactInputSingle、exactOutput),只需调整ABI和路径解析逻辑即可。
内容的提问来源于stack exchange,提问作者evan
相关产品推荐
相关产品推荐

