文章介绍了如何使用 Solana 的 getSignaturesForAddress
方法查询钱包、NFT、Candy Machine 等地址的交易历史,并详细讲解了如何设置环境、连接 QuickNode RPC 节点、编写交易查询脚本以及解析交易信息。
需要提取与钱包关联的所有交易吗?想查看与糖果机关联的所有铸币交易?或者查看NFT的交易历史?Solana的 getSignaturesForAddress 方法是一个多功能工具,使获取交易历史变得轻而易举。
喜欢视频教程吗?跟随 Noah 学习如何使用 Solana web3.js 在 15 分钟内获取 Solana 交易日志。
在本指南中,你将深入了解 Solana 交易的精彩世界!你将构建一个简单的脚本,可以查询一个地址(钱包、程序 ID、代币铸币等),并找到与之关联的所有交易历史。
Nodejs(版本 16.15 或更高)
已安装 Yarn
在 Solana 上的基本交易经验。为了复习你的知识,请阅读我们的初学者指南 如何在 Solana 上发送交易
JavaScript 的知识
让我们开始吧!
在终端中创建一个新的项目目录和文件 log.js:
mkdir get_sol_tx
cd get_sol_tx
echo > log.js
安装 Solana web3 依赖项:
yarn init -y
yarn add @solana/web3.js@1
或者
npm init -y
npm install --save @solana/web3.js@1
在你选择的代码编辑器中打开 log.js,并在第 1 行引入 @solana/web3.js 并将其存储在一个常量 solanaWeb3 中:
**
const solanaWeb3 = require('@solana/web3.js');
声明一个你想要搜索的地址:
const searchAddress = 'YOUR_ADDRESS_HERE'; // 示例 'vines1vzrYbzLMRdu58ou5XTby4qAqVRLmqo36NKPTg'
注意:这可以是 Solana 上的任意有效地址(例如,钱包地址、铸币地址、程序地址)。如果你还没有地址,可以使用 'vines1vzrYbzLMRdu58ou5XTby4qAqVRLmqo36NKPTg' 作为示例。
好吧,我们准备开始了!
要在 Solana 上构建,你需要一个 API 端点来连接网络。你可以使用公共节点或自己部署和管理基础设施;然而,如果你希望响应时间快 8 倍,你可以将繁重的工作留给我们。
我们将启动我们的节点在 Solana Devnet 下,但你可以启动符合你需求的节点。复制 HTTP 提供程序链接:
返回 log.js,创建一个常量 endpoint并将其分配给你的 QuickNode url。在下一行,将此常量作为参数传递给 Connection 函数,并将其存储在另一个常量叫 solanaConnection 中:
const endpoint = 'https://example.solana-devnet.quiknode.pro/000000/';
const solanaConnection = new solanaWeb3.Connection(endpoint);
太好了!你准备好构建你的搜索功能了。
getSignaturesForAddress 方法将会在这里做大量的繁重工作。它的工作原理如下:
它将接受两个参数:
选项(可选):包含 3 个可选条目的对象:
before:在特定交易签名之前开始向后搜索
after:在特定交易签名之后开始向前搜索
limit:返回的最大交易数量 (请注意,最大和默认值为1,000)
它将返回一个 Promise,包含一个 ConfirmedSignatureInfo 的数组,这是一个包含关键交易信息的对象:
signature(交易 ID),
slot 和 blockTime(查看交易处理的时间),
err(如果有错误),以及
memo(如果与交易相关的任何备注)
定义一个新的 async 函数 getTransactions,该函数接受两个参数:address 和 numTx。
在我们的函数内部,调用 getSignaturesForAddress 方法,在 solanaConnection 的新实例上,并将输出保存到变量 transactionList:
const getTransactions = async(address, numTx) => {
const pubKey = new solanaWeb3.PublicKey(address);
let transactionList = await solanaConnection.getSignaturesForAddress(pubKey, {limit:numTx});
}
这应该会给我们一个满足搜索条件的所有交易历史的数组。让我们以易于阅读的方式记录结果。
在 getTransactions 内部,创建一个 forEach 循环以记录每笔交易的信息:
const getTransactions = async(address, numTx) => {
const pubKey = new solanaWeb3.PublicKey(address);
let transactionList = await solanaConnection.getSignaturesForAddress(pubKey, {limit:numTx});
transactionList.forEach((transaction, i) => {
const date = new Date(transaction.blockTime*1000);
console.log(`交易编号: ${i+1}`);
console.log(`签名: ${transaction.signature}`);
console.log(`时间: ${date}`);
console.log(`状态: ${transaction.confirmationStatus}`);
console.log(("-").repeat(20));
})
}
如果一切设置正确,你应该可以调用你的函数并看到一些结果!将以下内容添加到 log.js 的末尾:
getTransactions(searchAddress,3);
现在在你的终端中输入:
node log.js
你应该看到类似这样的内容:
哇!好简单,对吧?随便测试几种不同的钱包、NFT 代币地址和糖果机 ID。你可以看到,这个方法应该会产生类似的结果,这使得它在许多不同应用中非常方便。
恭喜!你成功地获取了交易……你可以到此为止,但如果你想看看我们还可以用交易签名做些什么,请继续阅读! 👇
所以我们获得了一些关于交易历史的有用基本信息,但每笔交易做了什么呢?我们可以使用 Solana 的 getParsedTransaction 方法来提供更多详细信息。
getParsedTransaction 方法将接受一个已确认或已完成的交易签名,并返回一个 ParsedTransactionWithMeta 对象:
export type ParsedTransactionWithMeta = {
/** 交易被处理时的插槽 */
slot: number;
/** 交易的详细信息 */
transaction: ParsedTransaction;
/** 交易产生的元数据 */
meta: ParsedTransactionMeta | null;
/** 处理交易时的 Unix 时间戳 */
blockTime?: number | null;
/** 交易消息的版本 */
version?: TransactionVersion;
};
这里有很多信息,我们在这个初级指南中不会进行详细说明,但我们确实想给出一个如何与这些对象互动的示例。
在你的 getTransactions 函数中,我们将声明两个新变量:signatureList 和 transactionDetails。我们将通过映射我们的 transactionList 来生成签名列表,并通过调用这些签名到 getParsedTransactions 来生成每笔交易的详细信息:
const getTransactions = async(address, numTx) => {
const pubKey = new solanaWeb3.PublicKey(address);
let transactionList = await solanaConnection.getSignaturesForAddress(pubKey, {limit:numTx});
//添加此代码
let signatureList = transactionList.map(transaction=>transaction.signature);
let transactionDetails = await solanaConnection.getParsedTransactions(signatureList, {maxSupportedTransactionVersion:0});
//--新代码结束
transactionList.forEach((transaction, i) => {
const date = new Date(transaction.blockTime*1000);
console.log(`交易编号: ${i+1}`);
console.log(`签名: ${transaction.signature}`);
console.log(`时间: ${date}`);
console.log(`状态: ${transaction.confirmationStatus}`);
console.log(("-").repeat(20));
})
}
当我们的 Promise 返回时,transactionDetails 将生成一个 ParsedTransactionWithMeta 对象的数组。让我们尝试查找一些有用的信息。
假设我们有兴趣找出针对特定交易我们交互的所有程序或智能合约。在我们原来的 forEach 循环中,在 date 声明后,创建一个新变量,transactionInstructions:
const transactionInstructions = transactionDetails[i].transaction.message.instructions;
这将利用我们的索引 i 来查找与循环中正在查询的相同交易的详细交易信息。由于每笔交易可以有多个指令或程序迭代,我们需要另一个循环来获取交易中的每个程序交互。在我们的循环中,在 确认状态 日志后,添加以下内容:
transactionInstructions.forEach((instruction, n)=>{
console.log(`---指令 ${n+1}: ${instruction.programId.toString()}`);
})
我们在这里要做的是,对于每笔交易,查看每个交易指令并记录程序名称(如果存在)和程序 ID。
最终的函数应该如下所示:
const getTransactions = async(address, numTx) => {
const pubKey = new solanaWeb3.PublicKey(address);
let transactionList = await solanaConnection.getSignaturesForAddress(pubKey, {limit:numTx});
let signatureList = transactionList.map(transaction=>transaction.signature);
let transactionDetails = await solanaConnection.getParsedTransactions(signatureList, {maxSupportedTransactionVersion:0});
transactionList.forEach((transaction, i) => {
const date = new Date(transaction.blockTime*1000);
const transactionInstructions = transactionDetails[i].transaction.message.instructions;
console.log(`交易编号: ${i+1}`);
console.log(`签名: ${transaction.signature}`);
console.log(`时间: ${date}`);
console.log(`状态: ${transaction.confirmationStatus}`);
transactionInstructions.forEach((instruction, n)=>{
console.log(`---指令 ${n+1}: ${instruction.programId.toString()}`);
})
console.log(("-").repeat(20));
})
}
现在,再次运行你的脚本。在你的终端中输入:
node log.js
你应该看到类似这样的内容:
干得好!我们的交易结果现在包括了我们交互的不同程序的详细信息!
如果愿意,你可以通过 这里 在 Solana explorer 上比较你的结果(确保在页面右上角更改以搜索相同的网络)。
干得好!你现在已经深入了解 Solana 交易的精彩世界!
我们将在未来的指南中进一步介绍这些内容;但如果你渴望继续探索,请尝试通过运行一些类似查询来对你的 transactionDetails 数组进行实验,查看:
transactionDetails[i].meta
transactionDetails[i].transaction.message.accountKeys
要将这些概念付诸实践,请查看我们其他 Solana 教程 这里。
订阅我们的 新闻通讯 以获取更多关于 Solana 的文章和指南。如果你有任何反馈,欢迎通过 Twitter 与我们联系。你也可以在我们的 Discord 社区服务器与我们聊天,这里有一些你见过的最酷的开发者 :)
- 原文链接: quicknode.com/guides/sol...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!