SOL交易构造和解析#
Solana 交易构造与解析笔记#
1. 基本概念#
- 交易(Transaction)
- 由一个或多个 指令(Instruction) 构成
- 每个交易包含:
recentBlockhash:防重放feePayer:交易费用支付者signatures:签名数组(按 signer 顺序)
- 指令(Instruction)
- 包含:
programId:目标程序地址accounts:涉及的账户列表(可读/可写、是否需要签名)data:指令数据(通常是 base58 或 base64 编码的字节数组)
- 包含:
- 地址类型:
- Pubkey:32 字节,base58 编码
- Program:智能合约/程序账户
2. 交易构造#
- 准备账户:
- fee payer、signers、接收者
- 构造指令:
programId:调用的智能合约地址accounts:涉及的账户data:按程序 ABI 编码的参数
- 构造 Transaction 对象:
- 添加指令、设置 recentBlockhash 和 fee payer
- 签名:
- 使用私钥对 transaction message 签名
- 多签交易:多个 signer 依次签名
- 序列化 & 广播:
- 将交易序列化成 base58/base64 字符串
- 通过 RPC
sendTransaction或sendRawTransaction广播
3. 交易解析#
- 解码签名 & 最近区块哈希
transaction.signatures→ 校验 signerrecentBlockhash→ 确认交易唯一性
- 解析指令
transaction.message.instructions- 指令数据通常是 base58/base64 字节
- 解析步骤:
- 获取指令的
programId - 获取
accounts列表 - 解码
data:- 按程序的 ABI 或自定义布局解码
- Rust/Anchor 程序通常有
borsh或anchor序列化
- 获取指令的
- 参数类型
- 固定长度: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::Transactionborsh或anchor解码 instruction data
CLI
solana transaction <sig>→ 查看交易内容solana decode-transaction(部分工具)
5. 高级应用#
- 多指令交易
- 一个交易内可以包含多个 instruction
- 每条指令独立解析
- 签名验证
- 对 message hash + signer 校验签名
- 智能合约交互
- Anchor 程序:
Instruction.data由 Anchor 序列化(Borsh)- 必须使用 Anchor IDL 解码
- Anchor 程序:
- 交易重放防护
recentBlockhash+nonce+signer确保唯一性
实际交易场景#
假设你要转 10 USDT:
- 查找你的 USDT Token Account 地址
- 构造指令:
programId: SPL Token 程序地址source: 你的 USDT Token Accountdestination: 对方的 USDT Token Accountamount: 10 * 10^decimals
- 签名并发送交易
交易解析时,指令里的 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