Solana 链上的每一次数据变更,背后都有一次「交易」在默默运行。本篇文章用浅显中文把“创建交易”这件事拆解成可复现的代码范例,同时融入原子性、交易费用、Solana Explorer 等核心关键词,帮助你真正“读”得懂、“写”得会、“测”得稳。若想亲手跑一遍,👉 点击直达高并发网络无阻塞节点,开启 0 等待测试体验。
什么是交易?为什么一定要懂它
在 Solana 世界中,交易(transaction) 就是“打包好的指令集合”:
- 只能整体成功或整体失败(原子性)
- 必须由至少一个签名人支付交易费用
- 任何智能合约状态更新、NFT 铸造、代币转移,最终都靠交易驱动
交易的“四件套”
- Instructions(指令):要做什么
- Accounts(账户):对谁做
- Program ID(程序地址):谁去执行
- Data(字节数组):传哪些参数
借助 @solana/web3.js
,一行代码就能生成转账指令:
const instruction = SystemProgram.transfer({
fromPubkey: sender,
toPubkey: recipient,
lamports: 5_000,
});
创建一个转账交易:一步一步来
第 1 步:环境准备
确保已安装 Node 16+,并准备好:
npm install @solana/web3.js @solana-developers/helpers esrun dotenv
在 .env
写入本地密钥:
SECRET_KEY=[170,231, ... 你的私钥字节数组]
第 2 步:骨架代码
新建文件 transfer.ts
:
import {
Connection,
Transaction,
SystemProgram,
sendAndConfirmTransaction,
PublicKey,
} from "@solana/web3.js";
import "dotenv/config";
import { getKeypairFromEnvironment } from "@solana-developers/helpers";
const suppliedToPubkey = process.argv[2] || null;
if (!suppliedToPubkey) {
console.log("请提供接收方地址: npx esrun transfer.ts <recipient_pubkey>");
process.exit(1);
}
const senderKeypair = getKeypairFromEnvironment("SECRET_KEY");
const toPubkey = new PublicKey(suppliedToPubkey);
const connection = new Connection("https://api.devnet.solana.com", "confirmed");
console.log("✅ 已加载本地密钥并连接至 devnet");
第 3 步:添加转账逻辑
继续补上转账 5000 lamports(≈ 0.000005 SOL):
const transaction = new Transaction();
const instruction = SystemProgram.transfer({
fromPubkey: senderKeypair.publicKey,
toPubkey,
lamports: 5_000,
});
transaction.add(instruction);
const signature = await sendAndConfirmTransaction(connection, transaction, [
senderKeypair,
]);
console.log(`💸 转账完成!签名:${signature}`);
运行效果:
npx esrun transfer.ts 7J4...recipient
# 输出:💸 转账完成!签名:4wxotDPU...
为什么我的交易失败?——常见报错速查
多数新手卡在第一关:余额不足支付交易费用。你会看到:
Transaction simulation failed: Attempt to debit an account but found no record of a prior credit.
在 Devnet 免费领水即可解决:
import { airdropIfRequired } from "@solana-developers/helpers";
await airdropIfRequired(
connection,
senderKeypair.publicKey,
1 * LAMPORTS_PER_SOL,
0.5 * LAMPORTS_PER_SOL,
);
主网无空投,请务必用官方水龙头或交易所充值的小额 SOL 充当 Gas。
在 Solana Explorer 追踪交易
把 signature
粘到 Solana Explorer 查询框:
- 区块高度:交易被打包在第 N 块
- 交易费:本次花费 0.000005 SOL 锁定确定性收费
- Confirmations:只要 RPC 返回 confirmed,通常 1–3 秒即可“终局”
想要实时看网络状态?👉 直达可视化高吞吐 Solana 区块链浏览器
动手实验:把课堂变成小生态
每人公开自己的公钥,互相转账 5000 lamports,谁能最快完成下述任务?
考核项 | 目标值 | 记录方式 |
---|---|---|
耗时 | < 10 秒 | console.time() |
验证次数 | 3 笔 | signature.length === 3 |
失败率 | 0 | catch 错误并打印原因 |
完成后,把代码签入 GitHub,附上 playground 链接,分享你发现的三件事:
- 交易费用与转账金额无关的大小对比
- Devnet 上的 交易确认时间 均值
- 你能用 CLI
solana confirm -v <tx>
追踪到的事件顺序
常见问题 FAQ
Q1:交易费到底是怎么算的?
A:Solana 用 固定基础费 + 交易指令计算单元 (CUs) 双重模型。当前 Devnet 基础费 0.000005 SOL;主网随网络负载动态调整,与转账金额无关。
Q2:为什么广播后还会“Dropped”?
A:大概率是 RPC 拥挤或学费不足。可尝试换高可用节点或重放交易。
Q3:Transaction 的 confirmed
与 finalized
有何区别?
A:
confirmed
= 已由集群投票确认,但理论上可被分叉反冲。finalized
= 超过 31 个区块深度,结点达成共识极难回滚,适合 DeFi 结算。
Q4:能把一次转账拆成多条指令吗?
A:完全可以。把多条 SystemProgram.transfer
塞进同一笔 Transaction,只用付一次总费用,节省开销。
Q5:如何离线签名?
A:用 @solana/web3.js
的 Transaction.populate()
+ Keypair.signTransaction()
完成本地计算,再广播即可。
Q6:主网最低转账数量是多少?
A:技术上 1 lamport(0.000000001 SOL),但需额外支付交易费,因此最佳实践是 ≥ 0.00001 SOL 以保证不欠费。
小结 & 下一步
到这里,你已掌握:
- 交易的三大特征:原子性、费用确定、异步并行
- 用 8 行代码在 Devnet 完成 SOL 转账
- 用 Solana Explorer 观测链上细节
下一步,不妨深入 自定义链上程序(PDA、Anchor 框架),把你的交易逻辑无限扩展!