请求协助:解析BSC原始十六进制交易数据计算代币兑换价格
BSC Swap交易日志解析:将十六进制数据转换为代币兑换价格
我正在开发一款工具,需要从Binance Smart Chain(BSC)获取最新Swap交易数据,目标是把日志输出的原始十六进制数据转换为实际的代币兑换价格。
提供的Swap日志示例(PERRY/WBNB交易对)
{ 'address': '0x560a3375c67c8ad4c13018c87633e6066477151f', 'topics': [ '0x19b47279256b2a23a1665c810c8d55a1758940ee09377d4f8d26497a3577dc83', '0x00000000000000000000000013f4ea83d0bd40e75c8222255bc855a974568dd4', '0x00000000000000000000000068f9dd546d6dadf72862fda46910e5d9bed93321' ], 'data': '0xffffffffffffffffffffffffffffffffffffffffffffbc79ad35ea205f38ecd30000000000000000000000000000000000000000000000001bac1c6f72210000000000000000000000000000000000000000000000a3f94aae886f87faa0174e000000000000000000000000000000000000000000000f0a82803a369f4c9774fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe2bf500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016ab4dc5620000', 'blockNumber': '0x2c7f78c', 'transactionHash': '0x468655b34618fef300638a2cf72e4668f7f7851bcbd69543b52081743dc55f43', 'transactionIndex': '0x2', 'blockHash': '0xff7781a757058ada921f5f12696825c8b772ee071dc67bef97b74273f78b3004', 'logIndex': '0x9', 'removed': False }
我尝试的代码(无法得到正确价格)
from web3 import Web3 data = "0x00000000000000000000000000000000000000000000cd27cac5635ee2dc3373ffffffffffffffffffffffffffffffffffffffffffffffffcc666e6a579a81c40000000000000000000000000000000000000000007f5079c6974c18eb15de37000000000000000000000000000000000000000000000ee6581d2f59caeb088afffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe182f0000000000000000000000000000000000000000000000a81036b2e7516aca810000000000000000000000000000000000000000000000000000000000000000" decoded_data = Web3.to_bytes(hexstr=data) chunks = [decoded_data[i:i+32] for i in range(0, len(decoded_data), 32)] values = [int.from_bytes(chunk, byteorder="big", signed=True) for chunk in chunks] for i, value in enumerate(values): print(f"Slot {i}: {value}") amount_in = abs(values[2]) / 1e18 amount_out = abs(values[3]) / 1e18 swap_price = amount_out / amount_in
解决方案:用ABI解码Swap事件
你的问题出在手动分割数据并错误处理有符号整数上。BSC上的Swap交易大多基于Uniswap V2协议,其Swap事件有固定的ABI,直接用Web3的ABI解码工具才能准确提取数据。
步骤1:使用Uniswap V2 Swap事件ABI
[ { "anonymous": false, "inputs": [ {"indexed": true, "internalType": "address", "name": "sender", "type": "address"}, {"indexed": false, "internalType": "uint256", "name": "amount0In", "type": "uint256"}, {"indexed": false, "internalType": "uint256", "name": "amount1In", "type": "uint256"}, {"indexed": false, "internalType": "uint256", "name": "amount0Out", "type": "uint256"}, {"indexed": false, "internalType": "uint256", "name": "amount1Out", "type": "uint256"}, {"indexed": true, "internalType": "address", "name": "to", "type": "address"} ], "name": "Swap", "type": "event" } ]
步骤2:正确的解码代码
from web3 import Web3 # Swap事件ABI swap_abi = [ { "anonymous": False, "inputs": [ {"indexed": True, "internalType": "address", "name": "sender", "type": "address"}, {"indexed": False, "internalType": "uint256", "name": "amount0In", "type": "uint256"}, {"indexed": False, "internalType": "uint256", "name": "amount1In", "type": "uint256"}, {"indexed": False, "internalType": "uint256", "name": "amount0Out", "type": "uint256"}, {"indexed": False, "internalType": "uint256", "name": "amount1Out", "type": "uint256"}, {"indexed": True, "internalType": "address", "name": "to", "type": "address"} ], "name": "Swap", "type": "event" } ] # 你的Swap日志数据 log = { 'address': '0x560a3375c67c8ad4c13018c87633e6066477151f', 'topics': ['0x19b47279256b2a23a1665c810c8d55a1758940ee09377d4f8d26497a3577dc83', '0x00000000000000000000000013f4ea83d0bd40e75c8222255bc855a974568dd4', '0x00000000000000000000000068f9dd546d6dadf72862fda46910e5d9bed93321'], 'data': '0xffffffffffffffffffffffffffffffffffffffffffffbc79ad35ea205f38ecd30000000000000000000000000000000000000000000000001bac1c6f72210000000000000000000000000000000000000000000000a3f94aae886f87faa0174e000000000000000000000000000000000000000000000f0a82803a369f4c9774fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe2bf500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016ab4dc5620000', 'blockNumber': '0x2c7f78c', 'transactionHash': '0x468655b34618fef300638a2cf72e4668f7f7851bcbd69543b52081743dc55f43', 'transactionIndex': '0x2', 'blockHash': '0xff7781a757058ada921f5f12696825c8b772ee071dc67bef97b74273f78b3004', 'logIndex': '0x9', 'removed': False } # 初始化Web3实例(无需连接节点即可解码) w3 = Web3() # 解码日志数据 decoded_swap = w3.eth.abi.decode_log(swap_abi[0]['inputs'], log['data'], log['topics']) # 提取金额参数 amount0_in = decoded_swap['amount0In'] amount1_in = decoded_swap['amount1In'] amount0_out = decoded_swap['amount0Out'] amount1_out = decoded_swap['amount1Out'] # 假设交易对中token0是PERRY,token1是WBNB,两者小数位数均为18 perry_decimals = 18 wbnb_decimals = 18 # 判断交易方向并计算价格 if amount0_in > 0 and amount1_out > 0: # PERRY兑换WBNB:1 PERRY = X WBNB perry_amount = amount0_in / (10 ** perry_decimals) wbnb_amount = amount1_out / (10 ** wbnb_decimals) price = wbnb_amount / perry_amount print(f"1 PERRY = {price:.8f} WBNB") elif amount1_in > 0 and amount0_out > 0: # WBNB兑换PERRY:1 WBNB = X PERRY wbnb_amount = amount1_in / (10 ** wbnb_decimals) perry_amount = amount0_out / (10 ** perry_decimals) price = perry_amount / wbnb_amount print(f"1 WBNB = {price:.8f} PERRY") else: print("无效的Swap交易数据")
关键说明
- ABI解码更可靠:手动分割十六进制数据容易出错,ABI定义了事件的参数类型和顺序,解码结果准确。
- 无符号整数处理:Swap事件的金额都是
uint256(无符号整数),不需要用signed=True解析,避免负数错误。 - 代币小数位数:不同代币的小数位数可能不同,需要提前确认(比如WBNB是18位,PERRY需查询合约确认)。
内容的提问来源于stack exchange,提问作者luminusresearch
相关产品推荐
相关产品推荐

