使用web3.py查询Arbitrum Uniswap V3池缺失指定代币对问题
问题排查与解决
1. 代码语法逻辑错误
你的if语句存在明显语法问题,末尾多余的== ""导致条件完全不成立——哪怕找到对应代币的池,也不会触发打印逻辑。原错误条件:
if each["token0"].lower() == "0xc8ccbd97b96834b976c995a67bf46e5754e2c48e" or each["token1"].lower() == "0xc8ccbd97b96834b976c995a67bf46e5754e2c48e" == "":
需直接删除末尾的== "",恢复正常的代币地址判断逻辑。
2. 日志获取方法错误
web3.py中,contract.events.PoolCreated.getLogs()会直接返回日志条目列表,不存在.get_all_entries()方法——错误调用这个方法会导致日志丢失或报错,这也是你只拿到486个池的原因之一。
3. 全量区块查询的限制
一次性从区块0查询到最新区块,Infura等RPC服务商会限制单请求返回的日志数量,无法返回全部结果。必须分页查询,比如每次查询10000个区块,循环遍历直到覆盖所有区块范围。
4. 合约ABI缺失风险
你代码中的ABI变量未定义,如果ABI不正确,解析出的token0、token1等字段会出错,甚至无法获取数据。Uniswap V3 Factory的PoolCreated事件ABI片段必须包含:
{ "anonymous": false, "inputs": [ {"indexed": true, "internalType": "address", "name": "token0", "type": "address"}, {"indexed": true, "internalType": "address", "name": "token1", "type": "address"}, {"indexed": true, "internalType": "uint24", "name": "fee", "type": "uint24"}, {"indexed": false, "internalType": "int24", "name": "tickSpacing", "type": "int24"}, {"indexed": false, "internalType": "address", "name": "pool", "type": "address"} ], "name": "PoolCreated", "type": "event" }
5. 验证目标池的创建区块
先通过区块浏览器查询PLX/WETH池(0x7e48e98c9841bdd965986d2a4b37457938b27ee3)的创建交易所在区块,确保你的查询范围包含该区块。如果to_block设置值小于这个区块,自然查不到目标池。
修正后的代码示例
from web3 import Web3 # 替换为你的Infura ID INFURA_ID = "your-infura-id-here" RPC_URL = f"https://arbitrum-mainnet.infura.io/v3/{INFURA_ID}" web3 = Web3(Web3.HTTPProvider(RPC_URL)) # Arbitrum上的Uniswap V3 Factory合约地址 FACTORY_ADDR = "0x1F98431c8aD98523631AE4a59f267346ea31F984" # 包含PoolCreated事件的ABI片段 ABI = [ { "anonymous": False, "inputs": [ {"indexed": True, "internalType": "address", "name": "token0", "type": "address"}, {"indexed": True, "internalType": "address", "name": "token1", "type": "address"}, {"indexed": True, "internalType": "uint24", "name": "fee", "type": "uint24"}, {"indexed": False, "internalType": "int24", "name": "tickSpacing", "type": "int24"}, {"indexed": False, "internalType": "address", "name": "pool", "type": "address"} ], "name": "PoolCreated", "type": "event" } ] contract = web3.eth.contract(address=FACTORY_ADDR, abi=ABI) # 目标代币地址(PLX) TARGET_TOKEN = "0xc8ccbd97b96834b976c995a67bf46e5754e2c48e".lower() # 分页查询参数 start_block = 0 end_block = web3.eth.block_number batch_size = 10000 found_pool = None # 循环分页查询日志 for from_block in range(start_block, end_block + 1, batch_size): to_block = min(from_block + batch_size - 1, end_block) print(f"正在查询区块范围: {from_block} - {to_block}") try: logs = contract.events.PoolCreated.getLogs(fromBlock=from_block, toBlock=to_block) except Exception as e: print(f"查询失败: {str(e)}") continue # 遍历日志查找目标池 for log in logs: token0 = log["args"]["token0"].lower() token1 = log["args"]["token1"].lower() if token0 == TARGET_TOKEN or token1 == TARGET_TOKEN: print(f"找到目标池地址: {log['args']['pool']}") print(f"代币对: {token0} <-> {token1}") print(f"手续费率: {log['args']['fee']}") found_pool = log break if found_pool: break if not found_pool: print("未找到目标池,请检查区块范围、代币地址或RPC服务状态")
额外注意事项
- Infura有API额度限制,频繁分页查询可能触发限流,建议测试时先缩小区块范围
- 查找Ramses代币的池,只需替换
TARGET_TOKEN为0xaaa6c1e32c55a7bfa8066a6fae9b42650f262418.lower()即可
内容的提问来源于stack exchange,提问作者juju
相关产品推荐
相关产品推荐

