无论你是想开发基于 去中心化应用(dApp) 的创业者,还是正在研究 高性能区块链 的技术极客,掌握 Solana JavaScript 客户端 都是跨不过去的第一关。下面这篇文章用最直白的语言带你完成从“安装”到“与自定义程序交互”的完整闭环,同时保留每一处灵魂细节。
了解 @solana/web3.js 的核心定位
@solana/web3.js 是官方推荐的 JavaScript SDK,封装了 Solana JSON RPC API,让你在前端、Node 或浏览器 bundle 中都能毫秒级调用链上数据、签署交易、与自定义程序交互。
必背术语 30 秒速成
- 程序(Program):Solana 上无状态的可执行逻辑,等同于智能合约。
- 指令(Instruction):程序执行的最小触发单元;一个交易可由多条指令组成。
- 交易(Transaction):原子执行的指令集合,要么全部成功,要么全部回滚。
这些关键词在后续代码里会高频出现,一定要先记牢。
安装 & 环境配置
Node 场景
# yarn
yarn add @solana/web3.js
# npm
npm install --save @solana/web3.js
浏览器场景
<!-- CDN 直接引入,全局变量为 solanaWeb3 -->
<script src="https://unpkg.com/@solana/web3.js@latest/lib/index.iife.min.js"></script>
最短的可用代码片段
- CommonJS
const solanaWeb3 = require("@solana/web3.js"); console.log(solanaWeb3); - ES6 / TypeScript
import * as solanaWeb3 from "@solana/web3.js"; console.log(solanaWeb3);
钥匙管理:钥匙对与钱包
| 方式 | 适用场景 | 安全提示 |
|---|---|---|
| Keypair.generate | 本地测试、空投 | 私钥千万别托管在服务端 |
| wallet-adapter | 生成环境 dApp | 私钥永远隔离在扩展钱包 |
// 1. 创建随机钥匙对
const { Keypair } = require("@solana/web3.js");
const keypair = Keypair.generate();
console.log("公钥:", keypair.publicKey.toString());
一分钟学会发币:从零到上链的交易
import {
Connection, clusterApiUrl, Keypair, Transaction, SystemProgram, LAMPORTS_PER_SOL, sendAndConfirmTransaction
} from "@solana/web3.js";
const connection = new Connection(clusterApiUrl("testnet"));
const from = Keypair.generate(); // 付款人
const to = Keypair.generate(); // 收款人
// 先薅测试网水龙头
const airdropSig = await connection.requestAirdrop(from.publicKey, LAMPORTS_PER_SOL);
await connection.confirmTransaction({ signature: airdropSig });
// 构造转账交易
const tx = new Transaction().add(
SystemProgram.transfer({
fromPubkey: from.publicKey,
toPubkey: to.publicKey,
lamports: 0.5 * LAMPORTS_PER_SOL,
})
);
// 发送并等待确认
const sig = await sendAndConfirmTransaction(connection, tx, [from]);
console.log("交易哈希:", sig);
与自定义程序交互:以 Allocate 指令为例
当你已经熟悉转账,下一步就是让系统程序在指定账户里分配 存储空间。Step by step:
1. 初始化账户 & 水龙头闪电贷
import { struct, u32, ns64 } from "@solana/buffer-layout";
import { Buffer } from "buffer";
import * as web3 from "@solana/web3.js";
const keypair = web3.Keypair.generate();
const payer = web3.Keypair.generate();
const connection = new web3.Connection(web3.clusterApiUrl("testnet"));
const airdrop = await connection.requestAirdrop(payer.publicKey, web3.LAMPORTS_PER_SOL);
await connection.confirmTransaction({ signature: airdrop });
2. 构造参数与数据结构
Rust 中 allocate 指令枚举处于 SystemInstruction::Allocate 第 8 位;字段 space 为 u64 类型。
const allocateStruct = {
index: 8,
layout: struct([u32("instruction"), ns64("space")]),
};
const data = Buffer.alloc(allocateStruct.layout.span);
const params = { space: 100 }; // 分配 100 字节
const fields = Object.assign({ instruction: 8 }, params);
allocateStruct.layout.encode(fields, data);
3. 创建 transaction 并广播
const keys = [{ pubkey: keypair.publicKey, isSigner: true, isWritable: true }];
const allocateTx = new web3.Transaction({ feePayer: payer.publicKey });
allocateTx.add(new web3.TransactionInstruction({
keys,
programId: web3.SystemProgram.programId,
data,
}));
await web3.sendAndConfirmTransaction(connection, allocateTx, [payer, keypair]);
console.log("空间分配完成!");
FAQ:90% 初学者的共同疑问
Q1:测试网、开发网和主网的差异?
A:测试网最接近主网,但每 24h 会自动重启;开发网更频繁重启,适合 CI/CD;主网才是真正资金流动的环境。
Q2:私钥到底放哪才安全?
A:真环境 永远 让钱包扩展或硬件钱包自行保管私钥,dApp 只拿到签名后的交易。
Q3:如何知道交易真的成功了?
A:拿到 signature 后在 区块浏览器 查询即可,3–5 秒可查。
Q4:为什么我请求的空投总是失败?
A:测试网每秒有频率限制,同一个 IP 仅可申请两次/24 小时,间隔 12 小时再试。
Q5:浏览器下用 @solana/buffer-layout 报找不到 Buffer?
A:手动 import { Buffer } from "buffer",window.Buffer = Buffer 即可解决兼容性。
下一步:从调用到构建
当你能轻松完成转账并分配存储空间,下一阶段就是:
- 用 Anchor 框架写 Rust 程序;
- 通过
Connection.simulateTransaction本地测试复杂交易; - 用 Metaplex 创建 NFT 或 SPL Token;