Solana代币转账跟踪实现
本文介绍如何监控 Solana 上的 SPL 代币转账和关联代币账户(ATAs)。

一键发币: SUI | SOL | BNB | ETH | BASE | ARB | OP | POLYGON | AVAX | FTM | OK
跟踪 Solana 上的代币转账比在以太坊等区块链上更为复杂。在以太坊上,交易直接涉及钱包地址。而在 Solana 上:
- 代币被发送到关联代币账户(ATAs),而不是直接发送到钱包地址。
- 必须动态获取并监控与钱包相关的所有 ATAs 来追踪现有的代币。
- 要检测首次发送的代币(创建新的 ATA),需要监控钱包地址以捕获ATA 创建事件。
有一种两步方法可以解决这个问题:
- 监控所有现有的 ATAs 的余额变化。
- 监控钱包地址本身以检测新 ATA 的创建,并动态更新 ATA 列表。
本指南将解释如何使用 Solana 的工具和 API 高效地实现这样的系统。
1、Solana代币转账跟踪简介
对于有经验的开发者来说,Web3 开发仍然可能令人望而生畏。随着区块链项目的快速增长以及不同生态系统中的独特实现方式,很容易迷失在解决问题的正确方法中。一个看似简单的问题,比如跟踪代币转账,在不同的区块链上可能会有很大的差异。
例如,在以太坊上,监听由智能合约发出的事件来监控 ERC-20 代币的转账非常简单。开发者只需跟踪相关钱包地址即可。然而,在 Solana 上,这个过程要复杂得多。代币不会直接发送到钱包地址,而是发送到与该钱包关联的关联代币账户(ATA)。这可能会让开发者感到困惑,并导致他们在文档中花费大量时间寻找可行的解决方案。
最近,我遇到了一个问题,一位开发者想要构建一个警报系统,当任何代币被发送到 Solana 钱包时通知他们。这个问题突显了 Solana 架构的独特挑战之一,我意识到这是一个澄清如何实现此类系统的绝佳机会。
2、问题陈述
在 Solana 上跟踪代币转账并不像监控钱包地址那么简单。与以太坊不同,以太坊上的交易直接与钱包地址交互,Solana 使用**关联代币账户(ATAs)**来管理 SPL 代币。当代币被发送到钱包时:
- 代币被存入从钱包地址和代币的铸造地址派生出的 ATA 中。
- 钱包地址本身不直接参与交易,因此如果你只监控钱包地址,则无法看到这些交易。
这带来了几个挑战:
- 你不能通过仅仅监听钱包地址来跟踪传入的交易。
- 要检测代币转账,你需要知道代币的铸造地址并预先派生其 ATA。
- 如果代币首次被发送到钱包,ATA 在交易过程中才会创建。
3、初始尝试和观察
一种常见的方法是派生并监控特定代币的 ATA。这种方法在你知道发送的代币时工作得很好,但在系统需要:
- 动态处理任何代币发送到钱包。
- 检测首次代币转账时创建的新 ATA。
这些限制促使我们需要一个更强大且动态的解决方案。
4、提出的解决方案
解决方案包括一种双管齐下的方法:
- 监控与钱包相关的所有现有 ATAs,以追踪已知代币的余额变化。
- 监控钱包地址本身,以检测新的 ATA 创建事件,确保新收到的代币也能被追踪。
这种动态策略确保不会错过任何代币转账,无论是代币已经与钱包关联还是首次发送。
4.1 理解关联代币账户
要在 Solana 上跟踪代币转账,第一步是了解 ATAs 是如何工作的。每个代币都有一个独特的 ATA 对应于一个钱包,通过以下方式派生:
- 钱包的公钥。
- 代币的铸造地址。
ATA 确保每个代币存储在一个单独的账户中,使 Solana 能够高效地管理代币余额。
要为特定代币派生 ATA:
const { PublicKey } = require("@solana/web3.js");
const { getAssociatedTokenAddress } = require("@solana/spl-token");
async function deriveATA(walletAddress, tokenMint) {
const walletPubkey = new PublicKey(walletAddress);
const tokenMintPubkey = new PublicKey(tokenMint); const ata = await getAssociatedTokenAddress(tokenMintPubkey, walletPubkey);
console.log(`关联代币账户(ATA): ${ata.toString()}`);
}
这种方法在追踪特定代币时效果很好,但需要提前知道代币的铸造地址。
4.2 动态获取所有现有的 ATAs
为了处理多种代币,系统需要动态获取与钱包相关的所有现有 ATAs。这可以通过使用 Solana 的 getTokenAccountsByOwner
API 实现:
async function fetchATAs(walletAddress) {
const connection = new Connection("https://api.mainnet-beta.solana.com");
const walletPubkey = new PublicKey(walletAddress);
const accounts = await connection.getTokenAccountsByOwner(walletPubkey, {
programId: new PublicKey("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"), // SPL Token Program ID
}); console.log("获取的 ATAs:", accounts.value.map((account) => account.pubkey.toString()));
return accounts.value.map((account) => account.pubkey.toString());
}
此函数检索钱包的所有 ATAs 及其余额,为监控代币转账提供了基础。
4.3 监控现有的 ATAs
获取 ATAs 后,下一步是监控它们的余额变化:
async function monitorATAs(atas) {
const connection = new Connection("https://api.mainnet-beta.solana.com");
atas.forEach((ata) => {
connection.onLogs(new PublicKey(ata), (logs) => {
console.log(`检测到 ATA 的交易: ${ata}`);
console.log("日志:", logs);
});
});
}
这确保了任何发送到现有 ATA 的代币都能被检测到。
4.4 检测新的 ATA 创建
由于新的 ATAs 在代币首次发送到钱包时动态创建,因此必须监控钱包地址以捕获这些事件。onLogs
方法可以捕获交易日志中的新 ATA 创建。
async function monitorWallet(walletAddress) {
const connection = new Connection("https://api.mainnet-beta.solana.com");
connection.onLogs(new PublicKey(walletAddress), async (logs) => {
console.log(`检测到钱包的交易: ${walletAddress}`);
console.log("日志:", logs); if (logs.signature) {
const txDetails = await connection.getParsedTransaction(logs.signature);
console.log("交易详情:", txDetails); // 检测 ATA 创建并刷新 ATA 列表
const instructions = txDetails.transaction.message.instructions;
for (const instruction of instructions) {
if (instruction.programId.toString() === "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA") {
console.log("检测到新的 ATA!");
const newATAs = await fetchATAs(walletAddress);
monitorATAs(newATAs); // 使用新的 ATAs 更新监控
}
}
}
});
}
4.5 综合一切
通过结合这些方法,系统实现了全面覆盖:
- 获取所有现有的 ATAs 并监控它们。
- 监控钱包地址以检测新的 ATA 创建事件。
- 动态刷新监控的 ATAs 列表。
async function startMonitoring(walletAddress) {
const existingATAs = await fetchATAs(walletAddress);
monitorATAs(existingATAs);
monitorWallet(walletAddress);
}
startMonitoring("YOUR_WALLET_PUBLIC_KEY");
5、结束语
在 Solana 上跟踪代币转账需要应对 ATAs 独特的架构。虽然不像在以太坊上那样简单,但结合 ATA 监控和钱包日志分析确保不会错过任何代币转账。这个解决方案是动态、强大且可扩展的,为开发者提供了一种可靠的方法来跟踪发送到钱包的任何代币。
原文链接:Tracking Token Transfers on Solana: A Developer’s Guide
DefiPlot翻译整理,转载请标明出处
免责声明:本站资源仅用于学习目的,也不应被视为投资建议,读者在采取任何行动之前应自行研究并对自己的决定承担全部责任。