Solana Web3.js 2.0 SDK 开发指南:新特性解析与迁移实践

·

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,允许开发者仅引入实际使用的库部分,从而最小化包体积。此外,新版本无外部依赖,确保了构建的轻量化和安全性。

增强的灵活性

开发者现在可以通过以下方式创建高度定制的解决方案:

新的 TypeScript 客户端现托管于 @solana-program GitHub 组织,通过 Codama 自动生成,使开发者能快速为自定义程序生成客户端。

是否应立即迁移至 Web3.js v2?

截至当前:

从 web3.js v1 迁移指南

密钥对处理

Keypair 现替换为 KeyPairSignerKeypair.generate() 改为 generateKeyPairSigner()。密钥对变量名遵循 JS/TS 驼峰命名,如 keyPair。私钥通过 keyPairSigner.privateKey 访问,取代之前的 secretKey

地址与公钥

PublicKey 类型现统一使用 address。例如,KeyPairSigner 具有 address 属性表示公钥。可使用 address 函数将字符串公钥转换为地址类型。

数量表示

金额使用 JavaScript 原生的 BigInt 类型,数字末尾需加 n,如 1 变为 1n

工厂方法

许多功能改为可配置的工厂方法。例如:

这种方式提供了更大的灵活性和配置空间。

使用 Web3.js 2.0 发送交易实战

Helius 近期发布了 Kite 框架,这是一个专为 web3.js v2 设计的 TypeScript 框架,包含了大多数常见 Solana 任务的即用函数。

下面我们将构建一个客户端程序,演示如何将 lamports 转移到另一个钱包,同时采用最佳实践提高交易成功率和确认速度:

  1. 使用确认的承诺级别获取最新区块哈希
  2. 设置基于 Helius 优先费用 API 推荐的优先费用
  3. 优化计算单元分配
  4. 配置交易发送参数(maxRetries=0,skipPreflight=true)

这种方法即使在网络拥堵情况下也能确保最佳性能和可靠性。

环境准备

项目初始化

创建基础 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

各包功能说明:

定义转账地址

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。