如何通过Web3利用交易哈希获取交易中的代币兑换数量?
提取 PancakeSwap 交易中的代币兑换数量
你用web3.eth.get_transaction()拿到的只是交易基础数据,要获取实际兑换的代币数量,有两种可靠方法:
方式一:解码交易的input数据
交易的input字段包含了调用合约函数的参数,PancakeSwap Router的Swap函数参数里包含了用户输入的代币数量(最小输出量是预期值,实际量要从日志取)。可以用web3的解码工具解析:
from web3 import Web3 bsc = 'https://bsc-dataseed.binance.org/' web3 = Web3(Web3.HTTPProvider(bsc)) tx_hash = "0x77c5949df82ce8625d9e578fc696bc7264c99dbea4f763ce1fcdbe59dac5f029" tx = web3.eth.get_transaction(tx_hash) # 对应PancakeSwap Router V2的swapExactTokensForTokensSupportingFeeOnTransferTokens函数ABI片段 swap_abi = [{ "inputs": [ {"internalType": "uint256", "name": "amountIn", "type": "uint256"}, {"internalType": "uint256", "name": "amountOutMin", "type": "uint256"}, {"internalType": "address[]", "name": "path", "type": "address[]"}, {"internalType": "address", "name": "to", "type": "address"}, {"internalType": "uint256", "name": "deadline", "type": "uint256"} ], "name": "swapExactTokensForTokensSupportingFeeOnTransferTokens", "outputs": [], "stateMutability": "nonpayable", "type": "function" }] # 解码input数据 function_obj, params = web3.eth.decode_function_input(tx.input) # 输入的BUSD数量(BUSD是18位小数) amount_in = params['amountIn'] / 10**18 print(f"输入BUSD数量: {amount_in}") print(f"兑换路径代币地址: {params['path']}")
方式二:解析交易收据日志(获取实际兑换量)
amountOutMin只是用户设置的最低接收量,实际到账的代币数量要从交易触发的Transfer事件日志提取:
# 获取交易收据 tx_receipt = web3.eth.get_transaction_receipt(tx_hash) # ERC20标准Transfer事件ABI transfer_event_abi = { "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" } # 目标Shitcoin代币地址 target_token = "0x31b35fdaa0780a75dd08a1a631c03e34fcef7173" transfer_topic = web3.eth.event_abi_to_log_topic(transfer_event_abi) # 遍历日志提取Transfer事件 for log in tx_receipt['logs']: if log['address'].lower() == target_token.lower() and log['topics'][0] == transfer_topic: decoded_log = web3.eth.decode_logs([transfer_event_abi], log)[0] # 代币小数位数需对应合约的decimals()方法,这里假设是18位 actual_amount_out = decoded_log['args']['value'] / 10**18 print(f"实际获得Shitcoin数量: {actual_amount_out}")
补充说明
- 你的交易调用的是支持手续费代币的Swap函数(签名
0x5c11d795),这类函数不会在参数里返回实际输出量,必须从Transfer日志提取。 - 代币小数位数不要硬编码,最好调用代币合约的
decimals()方法获取准确值。
内容的提问来源于stack exchange,提问作者Soma Juice
相关产品推荐
相关产品推荐

