You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 06:05:54