BSC链交易查询Python脚本异常:USDT转账数值显示为0求助
问题描述
我需要一个可接收交易哈希、输出BSC区块链交易详情(含代币名称、数量、BNB/USDT价值、转账日期等)的Python脚本。现有脚本处理BNB转账时可正常输出详情,但处理USDT转账时,value_bnb与value_usd均显示为0,请求协助解决问题。
问题原因
USDT这类ERC-20代币的转账核心数据不在交易的value字段(该字段仅记录BNB转账金额),而是存储在交易的input字段及交易收据的日志中(属于合约调用的编码数据)。同时原脚本未区分代币类型,默认将所有交易标记为BNB,也未提取ERC-20代币的转账数量与对应价值。
修复后的代码
import requests import json from web3 import Web3 # 替换为你的BscScan API密钥 api_key = 'YOUR_BSCSCAN_API_KEY' transaction_hash = 'YOUR_TRANSACTION_HASH' # 初始化Web3连接,用于解码合约交易数据 w3 = Web3(Web3.HTTPProvider('https://bsc-dataseed.binance.org/')) # 1. 获取交易基础信息 tx_url = f'https://api.bscscan.com/api?module=proxy&action=eth_getTransactionByHash&txhash={transaction_hash}&apikey={api_key}' tx_response = requests.get(tx_url) tx_data = tx_response.json()['result'] # 2. 获取交易收据,用于提取实际消耗Gas和代币转账日志 receipt_url = f'https://api.bscscan.com/api?module=proxy&action=eth_getTransactionReceipt&txhash={transaction_hash}&apikey={api_key}' receipt_response = requests.get(receipt_url) receipt_data = receipt_response.json()['result'] # 3. 获取区块时间,即转账日期 block_url = f'https://api.bscscan.com/api?module=proxy&action=eth_getBlockByNumber&tag={tx_data["blockNumber"]}&boolean=true&apikey={api_key}' block_response = requests.get(block_url) block_data = block_response.json()['result'] transfer_date = block_data['timestamp'] # 4. 计算Gas费用相关数据 gas_price_wei = int(tx_data['gasPrice'], 16) gas_used = int(receipt_data['gasUsed'], 16) # 使用实际消耗的Gas,而非预估值 gas_fee_bnb = gas_used * gas_price_wei / 1e18 # 5. 获取BNB和USDT的实时价格 price_url = 'https://api.coingecko.com/api/v3/simple/price?ids=binancecoin,tether&vs_currencies=usd' price_response = requests.get(price_url) price_data = price_response.json() bnb_price_usd = price_data['binancecoin']['usd'] usdt_price_usd = price_data['tether']['usd'] gas_fee_usd = gas_fee_bnb * bnb_price_usd # 初始化交易详情字典 transaction_details = { "transaction_hash": tx_data['hash'], "block_number": int(tx_data['blockNumber'], 16), "transfer_date": transfer_date, "from": tx_data['from'], "gas_price_gwei": gas_price_wei / 1e9, "gas_used": gas_used, "gas_fee_bnb": gas_fee_bnb, "gas_fee_usd": gas_fee_usd } # 处理BNB转账(input字段为空) if tx_data['input'] == '0x': value_bnb = int(tx_data['value'], 16) / 1e18 transaction_details.update({ "token_type": "BNB", "token_amount": value_bnb, "value_bnb": value_bnb, "value_usd": value_bnb * bnb_price_usd, "to": tx_data['to'] }) # 处理USDT等ERC-20代币转账 else: # BSC链上USDT合约地址 usdt_contract_addr = '0x55d398326f99059ff775485246999027b3197955' # Transfer事件的主题哈希 transfer_topic = w3.keccak(text="Transfer(address,address,uint256)").hex() # 遍历交易日志提取Transfer事件数据 for log in receipt_data['logs']: if log['address'].lower() == usdt_contract_addr.lower() and log['topics'][0] == transfer_topic: from_addr = w3.toChecksumAddress(log['topics'][1].hex()) to_addr = w3.toChecksumAddress(log['topics'][2].hex()) # USDT为6位小数,需除以1e6 token_amount = int(log['data'], 16) / 1e6 transaction_details.update({ "token_type": "USDT", "token_amount": token_amount, "value_bnb": token_amount / bnb_price_usd, "value_usd": token_amount * usdt_price_usd, "to": to_addr, "from": from_addr }) break # 输出格式化后的交易详情 print(json.dumps(transaction_details, indent=4))
代码改进说明
- 代币类型区分:通过
input字段判断是否为BNB转账,非空则按ERC-20代币处理 - ERC-20数据解析:利用Web3解码交易日志中的
Transfer事件,提取真实转账数量与地址 - 新增转账日期:从区块数据中获取交易时间戳
- 精准Gas计算:使用交易收据中的实际消耗Gas,替代原脚本的预估Gas值
- 多币种价值转换:同时获取BNB和USDT价格,支持双向价值计算
- 小数精度适配:针对USDT的6位小数特性调整金额计算逻辑(其他ERC-20代币多为18位,需按需修改)
内容的提问来源于stack exchange,提问作者Muluken M
相关产品推荐
相关产品推荐

