SOL交易构造和解析

SOL交易构造和解析#

Solana 交易构造与解析笔记#

1. 基本概念#

  • 交易(Transaction)
    • 由一个或多个 指令(Instruction) 构成
    • 每个交易包含:
      • recentBlockhash:防重放
      • feePayer:交易费用支付者
      • signatures:签名数组(按 signer 顺序)
  • 指令(Instruction)
    • 包含:
      • programId:目标程序地址
      • accounts:涉及的账户列表(可读/可写、是否需要签名)
      • data:指令数据(通常是 base58 或 base64 编码的字节数组)
  • 地址类型:
    • Pubkey:32 字节,base58 编码
    • Program:智能合约/程序账户

2. 交易构造#

  1. 准备账户:
    • fee payer、signers、接收者
  2. 构造指令:
    • programId:调用的智能合约地址
    • accounts:涉及的账户
    • data:按程序 ABI 编码的参数
  3. 构造 Transaction 对象:
    • 添加指令、设置 recentBlockhash 和 fee payer
  4. 签名:
    • 使用私钥对 transaction message 签名
    • 多签交易:多个 signer 依次签名
  5. 序列化 & 广播:
    • 将交易序列化成 base58/base64 字符串
    • 通过 RPC sendTransaction 或 sendRawTransaction 广播

3. 交易解析#

  1. 解码签名 & 最近区块哈希
    • transaction.signatures → 校验 signer
    • recentBlockhash → 确认交易唯一性
  2. 解析指令
    • transaction.message.instructions
    • 指令数据通常是 base58/base64 字节
    • 解析步骤:
      1. 获取指令的 programId
      2. 获取 accounts 列表
      3. 解码 data:
        • 按程序的 ABI 或自定义布局解码
        • Rust/Anchor 程序通常有 borsh 或 anchor 序列化
  3. 参数类型
    • 固定长度:u64、u8、Pubkey
    • 动态长度:Vec / string / 可变数组

4. 常用工具#

  • 在线 / GUI

  • 编程库

    • JavaScript/TypeScript:

      import { Transaction, PublicKey } from '@solana/web3.js';
      const tx = Transaction.from(Buffer.from(rawTx, 'base64'));
      console.log(tx.instructions);
    • Rust:

      • solana_sdk::transaction::Transaction
      • borsh 或 anchor 解码 instruction data
  • CLI

    • solana transaction <sig> → 查看交易内容
    • solana decode-transaction (部分工具)

5. 高级应用#

  • 多指令交易
    • 一个交易内可以包含多个 instruction
    • 每条指令独立解析
  • 签名验证
    • 对 message hash + signer 校验签名
  • 智能合约交互
    • Anchor 程序:
      • Instruction.data 由 Anchor 序列化(Borsh)
      • 必须使用 Anchor IDL 解码
  • 交易重放防护
    • recentBlockhash + nonce + signer 确保唯一性

实际交易场景#

假设你要转 10 USDT:

  1. 查找你的 USDT Token Account 地址
  2. 构造指令:
    • programId: SPL Token 程序地址
    • source: 你的 USDT Token Account
    • destination: 对方的 USDT Token Account
    • amount: 10 * 10^decimals
  3. 签名并发送交易

交易解析时,指令里的 accounts 会显示:

  • fee payer(普通账户)
  • source Token Account
  • destination Token Account
  • token program ID

Solana instruction 三个核心字段#

例如:

programId: 9WwG... (AMM program)

accounts:
[ user,
  sourceTokenAccount,
  poolTokenAccount,
  poolAuthority,
  destinationTokenAccount,
  tokenProgram
]

data:
3Bxs4p...

解释:

programId  → 调用哪个程序
accounts   → 程序要操作的账户
data       → 参数

instruction data 的编码#

RPC 返回一般是:

base58

例如:

3Bxs4p9s3h7...

第一步要:

base58 → bytes

解析后可能得到:

[9, 64, 66, 15, 0, 0, 0, 0, ...]

完整解析流程#

真正解析一笔 swap:

1 找 swap instruction
2 base58 decode data
3 识别 discriminator
4 按 struct 解析参数
5 看 accounts 确定 token
6 查询 mint decimals
7 计算真实金额

Solana 和 EVM 最大差别#

EVM:

data 里有全部参数

Solana:

data + accounts

很多关键数据在 accounts。

所以解析必须同时看:

instruction.data
instruction.accounts