本文介绍了如何使用 Solana Kit(原 Solana Web3.js 2.0)执行基本的 Solana 交易,包括空投和转账。教程详细展示了新 API 的功能式编程风格、模块化设计、pipe 函数以及类型安全等特性,并提供了完整的代码示例和运行步骤。
本指南已更新,以反映 Solana Web3.js 2.0 的新名称 —— Solana Kit。我们正在遵循最新的最佳实践,帮助你保持与时俱进。在此了解 Solana Kit 的更多信息。
Solana 最近宣布 了 Solana Kit,这是其用于与 Solana 区块链交互的 JavaScript 库的重大更新。本指南将教你使用这个新库发送交易的基础知识。
让我们开始吧!
编写一个脚本,使用 Solana Kit 执行基本的 Solana 交易:
| 依赖 | 版本 |
|---|---|
| @solana/kit | >=2.0 |
| @solana-program/system | ^0.5.0 |
| solana cli | 1.18.8 |
让我们开始吧!
Solana Kit 是用于与 Solana 区块链交互的 JavaScript 库的重大更新。它引入了新的 API 设计,专注于可组合性、模块化和改进的开发体验。一些关键特性包括:
有关 API 更改的更多信息,请查看我们的博客:Solana Kit 的新特性。
让我们通过创建一个执行基本转账交易的脚本来探索这些特性。
首先,让我们设置项目:
mkdir solana-transfer-demo && cd solana-transfer-demo
接下来,将项目初始化为 Node.js 项目:
npm init -y
安装依赖:
npm install @solana/kit @solana-program/system && npm install --save-dev @types/node
注意:如果你使用的 Node.js 版本低于 18,则可能需要使用
--legacy-peer-deps标志安装@solana-program/system包。
在项目中添加一个启用 resolveJsonModule 的 tsconfig.json 文件:
tsc --init --resolveJsonModule true
在项目目录中创建一个名为 transfer.ts 的新文件。
echo > transfer.ts
太好了,让我们开始写代码吧!
在 transfer.ts 文件中,让我们开始导入必要的依赖:
import {
airdropFactory,
createKeyPairSignerFromBytes,
createSolanaRpc,
createSolanaRpcSubscriptions,
generateKeyPairSigner,
lamports,
sendAndConfirmTransactionFactory,
pipe,
createTransactionMessage,
setTransactionMessageFeePayer,
setTransactionMessageLifetimeUsingBlockhash,
appendTransactionMessageInstruction,
signTransactionMessageWithSigners,
getSignatureFromTransaction,
address,
} from "@solana/kit";
import { getTransferSolInstruction } from "@solana-program/system";
const LAMPORTS_PER_SOL = BigInt(1_000_000_000);
这里,我们从 Solana Kit 库中导入了各种函数。注意导入的函数式风格——每个函数负责一个特定的任务,促进了模块化和可组合性。LAMPORTS_PER_SOL 常量不再通过 SDK 提供,因此我们必须自己定义。与之前的 SDK 不同,新 SDK 对所有金额使用 bigint(为了更好地兼容 Rust 编程,它支持 u64,这是 Solana 程序中常见的类型)。
接下来,让我们创建包含脚本逻辑的 main 函数:
async function main() {
// 1 - 建立与 Solana 集群的连接
// 2 - 生成签名者
// 3 - 向账户空投 SOL
// 4 - 创建转账交易
// 5 - 签名并发送交易
}
main();
在 main 函数内部,让我们建立与本地 Solana 集群的连接:
// 1 - 建立与 Solana 集群的连接
const httpProvider = 'http://127.0.0.1:8899';
const wssProvider = 'ws://127.0.0.1:8900';
const rpc = createSolanaRpc(httpProvider);
const rpcSubscriptions = createSolanaRpcSubscriptions(wssProvider);
console.log(`✅ - 已建立与 ${httpProvider} 的连接`);
这里,我们使用 createSolanaRpc 和 createSolanaRpcSubscriptions 函数来创建我们的 RPC 连接。如果你熟悉旧的 SDK,可能会注意到新 SDK 使用了不同的方法来建立连接。本指南我们将使用 localhost,但如果你准备连接到远程 Solana 集群,你可以从你的 Quicknode 仪表板 使用你的 Quicknode HTTP Provider 和 WSS Provider 端点。

如果你还没有 Quicknode 账户,可以免费创建一个 在这里。
现在,让我们为交易生成两个签名者:
// 2 - 生成签名者
const user1 = await generateKeyPairSigner();
console.log(`✅ - 新用户1地址已创建: ${user1.address}`);
const user2 = await createKeyPairSignerFromBytes(new Uint8Array([/* 你的私钥字节放这里 */]));
console.log(`✅ - 从文件生成的用户2地址: ${user2.address}`);
为了学习目的,我们将以两种方式生成密钥对。首先,使用 generateKeyPairSigner 为用户1创建新密钥对,并使用 createKeyPairSignerFromBytes 从现有私钥为用户2创建密钥对。如果你还没有私钥,可以使用 Solana CLI 生成一个:
solana-keygen new --no-bip39-passphrase --outfile ./my-keypair.json
如果你更倾向于从文件加载密钥,可以使用 import 语句(因为我们在 tsconfig.json 文件中使用了 --resolveJsonModule 标志):
// 添加到你的导入中
import secret from './my-keypair.json';
// 将下面的 `user2` 行替换为:
const user2 = await createKeyPairSignerFromBytes(new Uint8Array(secret));
在我们转账 SOL 之前,需要为账户提供资金。同样,为了演示,我们将使用两种不同的方法(一种使用原生的 requestAirdrop 方法,另一种使用 airdropFactory 函数)。将以下代码添加到 main 函数中:
// 3 - 向账户空投 SOL
// 使用 RPC 方法
const tx1 = await rpc.requestAirdrop(
user1.address,
lamports(LAMPORTS_PER_SOL),
{ commitment: 'processed' }
).send();
console.log(`✅ - 使用 RPC 方法向用户1空投了 1 SOL`);
console.log(`✅ - 交易1: ${tx1}`);
// 使用工厂函数
const airdrop = airdropFactory({ rpc, rpcSubscriptions });
const tx2 = await airdrop({
commitment: 'processed',
lamports: lamports(LAMPORTS_PER_SOL),
recipientAddress: user2.address
});
console.log(`✅ - 使用工厂函数向用户2空投了 1 SOL`);
console.log(`✅ - 交易2: ${tx2}`);
两种方法都可行,你可以根据用例选择最合适的一种。无论采用哪种方法,都需要传递目标地址、要空投的 SOL 数量(注意新 SDK 要求我们使用 lamports 函数,它实际上是对 bigint 类型的扩展)以及提交级别。这里,我们使用 lamports 函数将 SOL 转换为 lamports,这是 Solana 使用的计量单位。
现在,让我们创建并发送转账交易。这个过程展示了新 Solana Kit SDK 的几个重要特性:
// 4 - 创建转账交易
const { value: latestBlockhash } = await rpc.getLatestBlockhash().send();
const transactionMessage = pipe(
createTransactionMessage({ version: 0 }),
tx => setTransactionMessageFeePayer(user1.address, tx),
tx => setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, tx),
tx => appendTransactionMessageInstruction(
getTransferSolInstruction({
amount: lamports(LAMPORTS_PER_SOL / BigInt(2)),
destination: user2.address,
source: user1,
}),
tx
)
);
让我们分解一下:
RPC 调用与 .send() 方法:
新 SDK 引入了一种使用 .send() 方法进行 RPC 调用的一致模式。这在 getLatestBlockhash() 调用中很明显:
const { value: latestBlockhash } = await rpc.getLatestBlockhash().send();
这种模式将 RPC 请求的构建与其执行分离,从而在发起请求时提供更大的灵活性和可组合性。
使用管道进行交易构建:
pipe 函数是新 SDK 中的一个关键特性,借鉴自函数式编程概念。如果你不熟悉管道,它们允许你将多个操作链接在一起,将每个操作的结果作为下一个操作的输入。
const transactionMessage = pipe(
createTransactionMessage({ version: 0 }),
tx => setTransactionMessageFeePayer(user1.address, tx),
// ... 更多操作
);
管道中的每个函数都将前一个函数的结果作为输入,逐步修改交易消息。这种方法使得交易构建过程更加可读和可维护,尤其对于复杂交易而言。
来自独立库的程序指令:
getTransferSolInstruction 函数是从 @solana-program/system 库中导入的:
import { getTransferSolInstruction } from "@solana-program/system";
将特定于程序的指令分离到它们自己的库中是 Kit 中的一种新模式。它允许更好的代码组织以及更轻松地管理不同的 Solana 程序。你可以期待看到更多遵循此模式的特定于程序的库,使得与各种 Solana 程序的交互更容易。
细粒度的交易构建: 注意交易是如何逐步组装的:
createTransactionMessage({ version: 0 }):初始化一个新的交易消息。setTransactionMessageFeePayer:设置交易的费用支付者。setTransactionMessageLifetimeUsingBlockhash:使用最近的区块哈希设置交易的生命周期。appendTransactionMessageInstruction:将转账指令添加到交易中。这种细粒度的方法让开发者对交易的每个方面有更多控制,并且更容易构造包含多个指令的复杂交易。
类型安全与不可变性: 使用单独的函数进行交易构建的每个步骤,结合 TypeScript,提供了更好的类型安全性,确保错误被尽早捕获。每个函数返回一个新的交易对象,而不是修改现有对象,促进了不可变性并减少了意外副作用的可能性。
通过利用这些特性,新的 Solana Kit SDK 旨在提供一种更稳健、更灵活且对开发者更友好的方式来与 Solana 区块链交互。随着你继续使用该 SDK,你会发现这些模式使得为你的 Solana 应用程序编写清晰、可维护且不易出错的代码变得更容易。
// 5 - 签名并发送交易
const signedTransaction = await signTransactionMessageWithSigners(transactionMessage);
const sendAndConfirmTransaction = sendAndConfirmTransactionFactory({ rpc, rpcSubscriptions });
try {
await sendAndConfirmTransaction(
signedTransaction,
{ commitment: 'confirmed', skipPreflight: true }
);
const signature = getSignatureFromTransaction(signedTransaction);
console.log('✅ - 转账交易已发送:', signature);
} catch (e) {
console.error('转账失败:', e);
}
这一部分展示了 Kit 的几个关键特性:
signTransactionMessageWithSigners 来使用可能存储在指令账户元数据中的任何签名者对交易进行签名。如果你回顾一下我们的 getTransferSolInstruction 函数,你会看到在 source 参数中,我们传入了 user1 密钥对(源账户的签名者)。然后 signTransactionMessageWithSigners 会使用该签名者对交易进行签名。sendAndConfirmTransactionFactory 函数创建了一个 sendAndConfirmTransaction 函数。sendAndConfirmTransaction 函数发送已签名的交易,并返回交易签名,我们使用 getSignatureFromTransaction 函数获取该签名。在本指南中,我们将使用本地 Solana 验证器。打开一个新的终端窗口并启动验证器:
solana-test-validator -r
要运行我们的脚本,请使用以下命令:
ts-node transfer.ts
你应该会看到显示成功连接、空投和转账交易的输出:

干得好!
如果你愿意,可以随意向转账交易追加更多指令。例如,你可以将以下指令添加到你的 pipe 中,以向另一个账户转账 SOL:
tx => appendTransactionMessageInstruction(
getTransferSolInstruction({
amount: lamports(LAMPORTS_PER_SOL / BigInt(3)),
destination: address('其他地址'),
source: user1,
}),
tx
)
练习是提高技能的最佳方式,所以请随意尝试不同的指令和交易。如果你想查看本指南的源代码,可以 在这里 找到它。 编码愉快!
本指南通过创建一个执行基本转账交易的脚本,探索了新的 Solana Kit 库。通过函数式编程风格和工厂函数的使用,新 API 促进了模块化、可组合性并改善了开发者体验。
一些关键要点:
pipe 函数允许清晰且可读的操作组合。随着你继续探索 Kit,你会发现更多强大的特性和改进。编码愉快!
告诉我们 如果你有任何反馈或新主题的请求。我们期待听到你的声音。
- 原文链接: quicknode.com/guides/sol...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!
作者暂未设置收款二维码