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

如何用JS解码Solana的compiledInstructions获取代币交易信息

解码Solana交易指令提取代币与金额

核心步骤

1. 定位目标程序ID

用第三条指令的programIdIndex:7,从完整交易的message.accountKeys数组中取出对应的PublicKey,确认该程序所属的协议(比如Raydium、Serum等DEX)——不同协议的指令格式完全不同,这是解码的关键前提。

2. 解析指令数据Buffer

根据协议的指令格式手动解码,或借助对应SDK/IDL自动解码:

手动解码示例(以Raydium Swap指令为例)

假设第三条指令是Raydium的Swap操作,其指令数据结构包含amount_in、amount_out_min等参数:

// 从compiledInstructions中取出第三条的data Buffer
const instructionData = compiledInstructions[2].data;

// 前8字节是指令鉴别器(用于区分不同指令类型)
const discriminator = instructionData.slice(0, 8);
// 验证鉴别器是否匹配目标指令(比如Raydium Swap的鉴别器是0x52e177e74e1d2d46)
console.log(discriminator.toString('hex')); // 输出52e177e74e1d2d46,确认是Swap指令

// 提取输入金额(u64类型,小端字节序)
const amountIn = instructionData.slice(8, 16).readBigUInt64LE();
// 提取最小输出金额(u64类型)
const amountOutMin = instructionData.slice(16, 24).readBigUInt64LE();

// 金额需要除以代币的decimals(比如USDC是6,SOL是9),才能得到可读数值
// 这里需要先获取对应代币的decimals,可通过Mint账户查询
const readableAmount = Number(amountOutMin) / Math.pow(10, decimals);

借助Anchor IDL自动解码

如果目标程序是用Anchor开发的(比如多数DEX),可以通过IDL直接解码:

import { Program, AnchorProvider } from '@project-serum/anchor';
// 导入对应程序的IDL文件(可从Solscan或项目GitHub获取)
import ammIdl from './raydium-amm-idl.json';

// 初始化Provider和Program
const provider = AnchorProvider.local();
const programId = transaction.message.accountKeys[7]; // 目标程序ID
const program = new Program(ammIdl, programId, provider);

// 解码指令
const decoded = program.instruction.decode(
  compiledInstructions[2].data,
  compiledInstructions[2].accountKeyIndexes.map(idx => transaction.message.accountKeys[idx])
);

// 直接获取解码后的参数
console.log('最小购买金额:', decoded.amountOutMin.toString());

3. 提取购买的代币地址

第三条指令的accountKeyIndexes数组中的索引,对应交易message.accountKeys里的账户。以Swap指令为例,输出代币的Mint账户就是你购买的代币地址,通常在账户列表的特定位置(比如Raydium Swap的输出代币Mint是第8个账户索引):

// 假设accountKeyIndexes中第8个索引对应输出代币Mint
const mintIndex = compiledInstructions[2].accountKeyIndexes[8];
const purchasedTokenMint = transaction.message.accountKeys[mintIndex].toBase58();
console.log('购买的代币地址:', purchasedTokenMint);

4. 补充代币精度(Decimals)

通过代币Mint地址查询其decimals字段(可通过Solana RPC的getAccountInfo方法,或@solana/spl-token库的getMint方法):

import { getMint } from '@solana/spl-token';
import { Connection } from '@solana/web3.js';

const connection = new Connection('https://api.mainnet-beta.solana.com');
const mintInfo = await getMint(connection, new PublicKey(purchasedTokenMint));
const decimals = mintInfo.decimals;

关键提示

  • 不同协议的指令格式差异极大,必须先确认programIdIndex:7对应的程序是什么,才能正确解码数据。
  • 如果accountKeyIndexes是压缩数组(显示为[Array]),需要展开查看完整索引列表,才能对应到正确的代币Mint账户。
  • 金额存储为u64类型,必须除以代币的decimals才能得到人类可读的数值。

内容的提问来源于stack exchange,提问作者Matěj Pátek

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 22:14:57