Solana Web3.js SDK 2.0 是一次重大版本更新,为开发者带来了显著的性能提升、更小的应用包体积以及更强的开发灵活性。本文将深入解析其核心特性,提供详细的迁移指南,并通过实战示例展示如何利用新 SDK 发送交易,帮助开发者快速上手并优化应用性能。
引言
Solana Web3.js SDK 是一个强大的 TypeScript/JavaScript 库,用于在 Node.js、Web 和 React Native 平台上构建 Solana 应用。2024年11月,Anza 发布了备受期待的 2.0 版本,引入了现代 JavaScript 特性,包括对大整数和加密原生类型的支持,同时大幅减少了包体积。对于正在使用旧版本 @solana/web3.js 的开发者,需要将项目迁移至新版本或明确锁定为 v1.x。
本文假设读者已具备 Solana 基础概念知识(如交易发送、账户模型、区块哈希和优先费用)以及 TypeScript 或 JavaScript 开发经验。让我们开始探索这次更新的核心内容。
Web3.js 2.0 的新特性
性能提升
新 SDK 利用现代 JavaScript 环境(如 Node.js 和最新浏览器)的原生加密 API,使密钥对生成、交易签名和消息验证等操作速度提升了 10倍。
更小的应用体积
Web3.js 2.0 全面支持 tree-shaking,允许开发者仅引入实际使用的库部分,从而最小化包体积。此外,新版本无外部依赖,确保了构建的轻量化和安全性。
增强的灵活性
开发者现在可以通过以下方式创建高度定制的解决方案:
- 使用自定义方法定义 RPC 实例
- 采用专用网络传输或交易签名器
- 为网络、交易确认和编解码器组合自定义原语
新的 TypeScript 客户端现托管于 @solana-program GitHub 组织,通过 Codama 自动生成,使开发者能快速为自定义程序生成客户端。
是否应立即迁移至 Web3.js v2?
截至当前:
- 若你正在使用 JS/TS 开发新的 Solana 应用,并依赖系统程序、代币程序等现有程序,可立即采用 web3.js v2。
- 若使用 Anchor 构建自定义链上应用,建议等待未来更新以获取兼容支持。作为替代方案,可使用 Codama 生成 TypeScript 客户端,但需注意工作量稍大。
从 web3.js v1 迁移指南
密钥对处理
原 Keypair 现替换为 KeyPairSigner。Keypair.generate() 改为 generateKeyPairSigner()。密钥对变量名遵循 JS/TS 驼峰命名,如 keyPair。私钥通过 keyPairSigner.privateKey 访问,取代之前的 secretKey。
地址与公钥
原 PublicKey 类型现统一使用 address。例如,KeyPairSigner 具有 address 属性表示公钥。可使用 address 函数将字符串公钥转换为地址类型。
数量表示
金额使用 JavaScript 原生的 BigInt 类型,数字末尾需加 n,如 1 变为 1n。
工厂方法
许多功能改为可配置的工厂方法。例如:
- 发送并确认交易:通过
sendAndConfirmTransactionFactory()创建自定义的sendAndConfirmTransaction()函数 - 获取空投:通过
airdropFactory()创建自定义的airdrop()函数
这种方式提供了更大的灵活性和配置空间。
使用 Web3.js 2.0 发送交易实战
Helius 近期发布了 Kite 框架,这是一个专为 web3.js v2 设计的 TypeScript 框架,包含了大多数常见 Solana 任务的即用函数。
下面我们将构建一个客户端程序,演示如何将 lamports 转移到另一个钱包,同时采用最佳实践提高交易成功率和确认速度:
- 使用确认的承诺级别获取最新区块哈希
- 设置基于 Helius 优先费用 API 推荐的优先费用
- 优化计算单元分配
- 配置交易发送参数(maxRetries=0,skipPreflight=true)
这种方法即使在网络拥堵情况下也能确保最佳性能和可靠性。
环境准备
- 安装 Node.js
- 准备兼容的 IDE(如 VS Code 或 Cursor)
项目初始化
创建基础 Node.js 项目并安装必要依赖:
npm init -y
mkdir src
touch src/index.ts
npm install @solana/web3.js@2 @solana-program/system @solana-program/compute-budget esrun各包功能说明:
@solana/web3.js: Solana Web3.js 2.0 SDK 核心库@solana-program/system: 提供 Solana 系统程序访问@solana-program/compute-budget: 设置优先费用和计算单元优化esrun: 直接运行 TypeScript 应用的便捷工具
定义转账地址
在 index.ts 中定义源地址和目标地址:
import { address, createKeyPairSignerFromBytes, getBase58Encoder } from "@solana/web3.js";
const destinationAddress = address("目标公钥字符串");
const secretKey = "你的私钥";
const sourceKeypair = await createKeyPairSignerFromBytes(getBase58Encoder().encode(secretKey));配置 RPC 连接
建立与 RPC 服务器的 HTTP 和 WebSocket 连接:
import {
createSolanaRpcSubscriptions,
createSolanaRpc,
sendAndConfirmTransactionFactory,
} from "@solana/web3.js";
const rpc_url = "https://mainnet.helius-rpc.com/?api-key=<你的密钥>";
const wss_url = "wss://mainnet.helius-rpc.com/?api-key=<你的密钥>";
const rpc = createSolanaRpc(rpc_url);
const rpcSubscriptions = createSolanaRpcSubscriptions(wss_url);
const sendAndConfirmTransaction = sendAndConfirmTransactionFactory({
rpc,
rpcSubscriptions,
});创建转账指令
获取最新区块哈希并创建转账指令:
import { lamports } from "@solana/web3.js";
import { getTransferSolInstruction } from "@solana-program/system";
const { value: latestBlockhash } = await rpc.getLatestBlockhash().send();
const instruction = getTransferSolInstruction({
amount: lamports(1n),
destination: destinationAddress,
source: sourceKeypair,
});构建交易消息
使用函数式编程方式构建交易消息:
import {
pipe,
createTransactionMessage,
setTransactionMessageFeePayer,
setTransactionMessageLifetimeUsingBlockhash,
appendTransactionMessageInstruction,
} from "@solana/web3.js";
const transactionMessage = pipe(
createTransactionMessage({ version: 0 }),
(message) => setTransactionMessageFeePayer(sourceKeypair.address, message),
(message) => setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, message),
(message) => appendTransactionMessageInstruction(instruction, message)
);签署交易
使用签名者对交易进行签名:
import { signTransactionMessageWithSigners } from "@solana/web3.js";
const signedTransaction = await signTransactionMessageWithSigners(transactionMessage);评估优先费用
通过 Helius 优先费用 API 获取推荐费用:
import { getBase64EncodedWireTransaction } from "@solana/web3.js";
const base64EncodedWireTransaction = getBase64EncodedWireTransaction(signedTransaction);
const response = await fetch(rpc_url, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
jsonrpc: "2.0",
id: "helius-example",
method: "getPriorityFeeEstimate",
params: [{
transaction: base64EncodedWireTransaction,
options: {
transactionEncoding: "base64",
priorityLevel: "High",
},
}],
}),
});
const { result } = await response.json();
const priorityFee = result.priorityFeeEstimate;优化计算单元
评估并优化交易的计算单元消耗:
import { getComputeUnitEstimateForTransactionMessageFactory } from "@solana/web3.js";
const getComputeUnitEstimateForTransactionMessage = getComputeUnitEstimateForTransactionMessageFactory({ rpc });
let computeUnitsEstimate = await getComputeUnitEstimateForTransactionMessage(transactionMessage);
computeUnitsEstimate = computeUnitsEstimate < 1000 ? 1000 : Math.ceil(computeUnitsEstimate * 1.1);重建并签署最终交易
获取新区块哈希,添加优先费用和计算单元指令,重新签署交易:
import { appendTransactionMessageInstructions, setTransactionMessageLifetimeUsingBlockhash } from "@solana/web3.js";
import { getSetComputeUnitPriceInstruction, getSetComputeUnitLimitInstruction } from "@solana-program/compute-budget";
const { value: finalLatestBlockhash } = await rpc.getLatestBlockhash().send();
const finalTransactionMessage = appendTransactionMessageInstructions(
[
getSetComputeUnitPriceInstruction({ microLamports: priorityFee }),
getSetComputeUnitLimitInstruction({ units: computeUnitsEstimate }),
],
transactionMessage
);
setTransactionMessageLifetimeUsingBlockhash(finalLatestBlockhash, finalTransactionMessage);
const finalSignedTransaction = await signTransactionMessageWithSigners(finalTransactionMessage);发送并确认交易
最后发送并确认交易:
import { getSignatureFromTransaction } from "@solana/web3.js";
await sendAndConfirmTransaction(finalSignedTransaction, {
commitment: "confirmed",
maxRetries: 0n,
skipPreflight: true,
});
console.log("转账确认: ", getSignatureFromTransaction(finalSignedTransaction));运行代码:
npx esrun send-transaction.ts常见问题
Web3.js 2.0 的主要优势是什么?
新版本提供了显著的性能提升,特别是加密操作速度提高10倍。同时支持tree-shaking大幅减少包体积,无外部依赖提高安全性,并通过工厂方法提供更强的定制灵活性。
迁移到 v2 版本需要注意什么?
需要注意密钥对处理方式变化(KeyPairSigner替代Keypair)、地址表示方式(address替代PublicKey)、数量类型(使用BigInt)以及工厂方法的使用模式。这些变化虽然需要适应,但带来了更好的类型安全和开发体验。
如何优化交易成功率?
建议使用最新区块哈希、设置适当的优先费用、优化计算单元分配,并在可靠的环境下跳过预检检查。这些措施能显著提高网络拥堵时的交易成功概率。
是否所有项目都应立即迁移?
新项目建议直接使用v2版本。使用Anchor框架的项目可等待官方兼容支持,或使用Codama生成自定义客户端。现有项目可根据维护情况和性能需求决定迁移时机。
如何获取实时交易状态?
👉 查看实时交易状态工具 可以帮助开发者监控和验证交易执行情况,提供更直观的区块链交互体验。
优先费用设置有哪些策略?
除了使用High级别外,还可根据网络状况动态调整费用策略,结合历史数据分析和实时网络负载评估,实现成本与成功率的优化平衡。
结语
Solana Web3.js 2.0 SDK 的发布标志着开发者体验的重大飞跃,通过现代 JavaScript 标准和性能优化,为构建高效、可扩展的 Solana 应用提供了强大基础。掌握新版本的特性和迁移技巧,将帮助开发者在 Solana 生态中创造更出色的产品。
随着区块链技术的快速发展,保持对最新工具和方法的了解至关重要。继续探索和实践,将能使你的区块链开发技能不断提升,适应不断变化的技术 landscape。