Raydium V4 Swap追踪:如何确定日志所属池与代币?
解决Raydium V4 Swap日志关联特定池/代币的问题
核心问题
已订阅Raydium Liquidity Pool V4主程序地址「675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8」,能解析log_type为3/4的swap日志,但无法关联到具体交易对应的池,且逐个订阅目标池成本过高。
可行解决方案
1. 从交易指令中提取池地址
Raydium V4的swap交易里,主程序的调用指令会携带池账户地址作为参数。捕获到含ray_log的交易后,可按以下步骤解析:
- 定位调用主程序「675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8」的指令
- 从指令的accounts列表中,找到对应池的账户(通常是第3或第4个账户,可对照Raydium V4指令结构确认)
- 该账户的公钥即为当前swap对应的池地址
2. 预存目标池元数据映射
提前收集关注的特定池信息,存入本地Map或数据库:
const targetPools = new Map([ [ "目标池地址1", { baseToken: "基础代币地址1", baseDecimals: 9, quoteToken: "报价代币地址1", quoteDecimals: 6 } ], // 其他目标池信息 ]);
通过步骤1获取池地址后,直接在映射中匹配是否为目标池,再结合解析后的日志数据(如amount_in、out_amount)换算实际代币数量,完成关联。
3. 结合交易账户信息明确代币类型
从交易指令的accounts中提取base token和quote token的地址,再配合解析出的direction字段(1=base→quote,2=quote→base),就能直接判断amount_in/out_amount对应的代币类型。
代码示例补充
获取交易对象后,提取池和代币地址的简化逻辑:
// 假设tx为捕获到的Solana交易对象 const raydiumProgramId = new PublicKey("675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8"); const swapInstruction = tx.instructions.find(inst => inst.programId.equals(raydiumProgramId)); if (swapInstruction) { // Raydium V4 swap指令的accounts结构中,池账户通常为索引2(需根据实际结构调整) const poolAddress = swapInstruction.accounts[2].pubkey.toString(); const baseTokenAddress = swapInstruction.accounts[4].pubkey.toString(); const quoteTokenAddress = swapInstruction.accounts[5].pubkey.toString(); // 匹配目标池并处理数据 if (targetPools.has(poolAddress)) { const poolMeta = targetPools.get(poolAddress); const decodedLog = logTypeToStruct.get(logType).decode(logData); // 根据方向计算实际代币数量 const amountInDecimals = decodedLog.direction === 1n ? poolMeta.baseDecimals : poolMeta.quoteDecimals; const actualAmountIn = Number(decodedLog.amount_in) / Math.pow(10, amountInDecimals); // 后续业务逻辑处理 } }
内容的提问来源于stack exchange,提问作者Mayga Fatmawati
相关产品推荐
相关产品推荐

