如何使用 Solana Web3.js 2.0 发送交易
- 原文链接:www.quicknode.com/guides...
- 译者:AI翻译官,校对:翻译小组
- 本文链接:learnblockchain.cn/article…
Solana 最近宣布 了 Solana Web3.js 2.0 的发布候选版本,这是他们与 Solana 区块链交互的 JavaScript 库的重要更新。本指南将教你使用这个新库发送交易的基础知识。
让我们开始吧!
编写一个脚本,以使用 Solana Web3.js 2.0 库执行基本的 Solana 交易:
依赖项 | 版本 |
---|---|
@solana/web3.js | >=2.0 |
@solana-program/system | ^0.5.0 |
solana cli | 1.18.8 |
让我们开始吧!
Solana Web3.js 2.0 是与 Solana 区块链交互的 JavaScript 库的重要更新。它引入了一种新的 API 设计,专注于可组合性、模块化和改进的开发者体验。一些关键特性包括:
有关 API 更改的更多信息,请查看我们的( 博客:Solana Web3.js 2.0 中的新特性 )。
让我们通过创建一个脚本来执行基本转账交易来探索这些功能。
首先,让我们设置项目:
mkdir solana-transfer-demo && cd solana-transfer-demo
接下来,将你的项目初始化为 Node.js 项目:
npm init -y
安装依赖项:
npm install @solana/web3.js@2 @solana-program/system && npm install --save-dev @types/node
注意:如果你使用的 Node.js 版本低于 18,你可能需要使用
--legacy-peer-deps
标志安装@solana-program/system
包。
向项目中添加一个 tsconfig.json
文件,并启用 resolveJsonModule
:
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/web3.js";
import { getTransferSolInstruction } from "@solana-program/system";
const LAMPORTS_PER_SOL = BigInt(1_000_000_000);
在这里,我们正在从新的 Solana Web3.js 2.0 库中导入各种函数。请注意导入的函数式风格 - 每个函数负责特定的任务,促使模块化和可组合性。LAMPORTS_PER_SOL
常量不再通过 SDK 提供,因此我们必须自己定义它。与以前的 SDK 不同,新的 SDK 对所有金额使用 bigint(以更好地与 Rust 编程兼容,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 使用不同的方法来建立连接。我们将在本指南中使用本地主机,但如果你准备好连接到远程 Solana 集群,你可以使用你的 QuickNode HTTP Provider 和 WSS Provider 端点,从你的 QuickNode Dashboard。
如果你还没有 QuickNode 账户,你可以 在这里 免费创建一个。
现在,让我们为我们的交易生成两个签名者:
// 2 - 生成签名者
const user1 = await generateKeyPairSigner();
console.log(`✅ - 新的 user1 地址已创建:${user1.address}`);
const user2 = await createKeyPairSignerFromBytes(new Uint8Array([/* 在这里填写你的私钥字节 */]));
console.log(`✅ - 从文件生成 user2 地址:${user2.address}`);
出于学习目的,我们将采用两种方式生成密钥对。首先,使用 generateKeyPairSigner
为 user1 创建新的密钥对,然后使用 createKeyPairSignerFromBytes
从现有后秘钥创建 user2 的密钥对。如果你还没有私钥,可以使用 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
函数:
```js
// 3 - 向账户空投 SOL
// 使用 RPC 方法
const tx1 = await rpc.requestAirdrop(
user1.address,
lamports(LAMPORTS_PER_SOL),
{ commitment: 'processed' }
).send();
console.log(`✅ - user1 使用 RPC 方法空投 1 SOL`);
console.log(`✅ - tx1: ${tx1}`);
// 使用工厂函数
const airdrop = airdropFactory({ rpc, rpcSubscriptions });
const tx2 = await airdrop({
commitment: 'processed',
lamports: lamports(LAMPORTS_PER_SOL),
recipientAddress: user2.address
});
console.log(`✅ - user2 使用工厂函数空投 1 SOL`);
console.log(`✅ - tx2: ${tx2}`);
这两种方法同样可行,因此你可以选择最适合你用例的方法。无论采用哪种方法,你都需要传递目标地址、要空投的 SOL 数量(请注意,新 SDK 要求我们使用 lamports
函数,这实际上扩展了 bigint
类型)和承诺级别。在这种情况下,我们使用 lamports
函数将 SOL 转换为 lamports,后者是 Solana 使用的计量单位。
现在,让我们创建并发送我们的转账交易。此过程展示了新 Solana Web3.js 2.0 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
)
);
让我们逐步分析:
.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";
将程序特定指令分隔到自己的库中是 Web3.js 2.0 中的一种新模式。这有助于更好的代码组织和对不同 Solana 程序的管理。你可以期待看到更多程序特定库遵循这一模式,从而使与各种 Solana 程序的交互更加简单。
细化的交易构建: 注意交易是如何逐步组装的:
createTransactionMessage({ version: 0 })
: 初始化新的交易消息。setTransactionMessageFeePayer
: 设置交易的手续费支付者。setTransactionMessageLifetimeUsingBlockhash
: 使用最近的区块哈希设置交易的生命周期。appendTransactionMessageInstruction
: 将转账指令添加到交易中。这种细化的方法使开发人员可以更好地控制交易的每个方面,并使得构建带有多条指令的复杂交易变得更加容易。
利用这些特性,新 Solana Web3.js 2.0 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);
}
本节展示了 Web3.js 2.0 的几个关键特性:
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('SOME_OTHER_ADDRESS'),
source: user1,
}),
tx
)
练习是提升技能的最佳方式,因此请随意尝试不同的指令和交易。 如果你想查看本指南的源代码,可以在这里找到它。 祝编码愉快!
本指南通过创建一个脚本以执行基本转账交易,探索了新的 Solana Web3.js 2.0 库。通过其函数式编程风格和工厂函数的使用,新的 API 促进了模块化、可组合性和提高的开发者体验。
一些关键要点:
pipe
函数允许操作的清晰和可读的组合。随着你继续探索 Web3.js 2.0,你将发现更多强大的功能和改进。祝编码愉快!
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!