{"content":{"title":"五种方法查找 Solana 钱包和铸币的关联代币地址","body":"## 概述\r\n\r\n无论你是在查询一个代币账户余额，还是构建一个代币转账指令，了解如何推导出用户的代币账户地址是任何 Solana 开发者的基本技能。在本指南中，我们将介绍五种简单的方法来获取 Solana SPL 关联的代币账户地址：\r\n\r\n- 使用 Solana 的 SPL-Token 命令行接口 (SPL-Token CLI) ( [跳转到 SPL-Token CLI](https://www.quicknode.com/guides/solana-development/spl-tokens/how-to-look-up-the-address-of-a-token-account#link-cli))\r\n- 使用 Solana 的 JavaScript API ( [跳转到 Solana-Web3.js](https://www.quicknode.com/guides/solana-development/spl-tokens/how-to-look-up-the-address-of-a-token-account#link-web3))\r\n- 使用 Solana 的 SPL Token 程序 API ( [跳转到 SPL Token 程序](https://www.quicknode.com/guides/solana-development/spl-tokens/how-to-look-up-the-address-of-a-token-account#link-token-program))\r\n- 使用 cURL 脚本 ( [跳转到 cURL](https://www.quicknode.com/guides/solana-development/spl-tokens/how-to-look-up-the-address-of-a-token-account#link-curl))\r\n- 使用 Rust ( [跳转到 Rust](https://www.quicknode.com/guides/solana-development/spl-tokens/how-to-look-up-the-address-of-a-token-account#link-rust))\r\n\r\n#### 你需要准备的事项\r\n\r\n- 对 [Solana 基础知识](https://learnblockchain.cn/article/11166) 的基本理解\r\n- 安装最新版本的 [Solana CLI](https://docs.solana.com/cli/install-solana-cli-tools)\r\n- 安装最新版本的 [SPL Token 程序 CLI](https://spl.solana.com/token#setup)\r\n- 已安装 [Nodejs](https://nodejs.org/en/)（版本 16.15 或更高）\r\n- 有基本的 JavaScript 经验\r\n- 已安装稳定版本的 [cURL](https://curl.se/)\r\n- 一些要查询的钱包地址和铸币地址（我们将使用钱包：`E645TckHQnDcavVv92Etc6xSWQaq8zzPtPRGBheviRAk` 和 USDC 代币铸币地址，`EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v`）\r\n- （可选）已安装 [Rust](https://www.rust-lang.org/tools/install)（适用于 Rust 方法）\r\n\r\n| 依赖项 | 版本 |\r\n| --- | --- |\r\n| solana-cli | 1.16.14 |\r\n| spl-token-cli | 3.1.1 |\r\n| node.js | 16.15 |\r\n| curl | 8.1.12 |\r\n| @solana/web3.js | 1.78.5 |\r\n| @solana/spl-token | 0.3.7 |\r\n| solana-sdk | 1.16.14 |\r\n| spl-associated-token-account | 2.2.0 |\r\n| cargo | 1.69.0 |\r\n\r\n## SPL 代币账户\r\n\r\n在深入代码之前，让我们花一点时间回顾一下什么是代币账户，以及它与 Solana 钱包地址的区别。与 Solana 生态系统中的大多数元素一样，代币账户是基于 Solana 的账户模型构建的。这意味着代币账户实际上是与特定代币铸币相关联的 Solana 账户。这些账户由 SPL Token 程序（ `TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA`）拥有，并由用户的钱包地址控制。虽然可以有多个代币账户与单个钱包地址关联，但每个代币账户都是特定铸币的唯一账户。为减少代币管理时的摩擦，Solana 引入了 [关联代币程序](https://spl.solana.com/associated-token-account)，这是一个确定性地将用户的钱包映射到关联铸币的代币账户的方法。本指南将重点讨论如何获取给定钱包和铸币的关联代币账户地址。\r\n\r\n## 方法 1 - SPL-Token CLI\r\n\r\n我们首个方法是使用 Solana SPL-Token CLI 检查钱包的余额。如果你尚未安装，请根据你的操作环境访问 [spl.solana.com/token](https://spl.solana.com/token#setup) 的说明进行安装。请通过打开新终端并输入以下命令来确保你的安装成功：\r\n\r\n```\r\nspl-token --version\r\n\r\n```\r\n\r\n你应该会看到类似以下的内容：\r\n\r\n![‘Solana CLI 版本检查’](https://img.learnblockchain.cn/2025/02/24/0-32edaf0b920f0fa750f3ff2502487d4d.png)\r\n\r\n你已经准备好了！只需获取你的钱包地址，你可以直接从 Phantom 或其他钱包复制它：\r\n\r\n![‘Phantom 钱包复制按钮’](https://img.learnblockchain.cn/2025/02/24/1-2b3c30af92eabccca75a2ec999cbd37c.png)\r\n\r\n你还需要查询代币的铸币地址。你可以通过在任何基于 Solana 的区块链浏览器中搜索代币名称找到它，例如 [Solana Explorer](https://explorer.solana.com/)：\r\n\r\n![‘Solana 浏览器’](https://img.learnblockchain.cn/2025/02/24/5-906d196ad6e3b21e2c4bd4fd2d3aded8.png)\r\n\r\n在你的终端中，输入以下命令来获取你的代币账户：\r\n\r\n```\r\nspl-token address --owner OWNER_WALLET_ADDRESS  --token TOKEN_MINT_ADDRESS --verbose -um\r\n\r\n```\r\n\r\n我们仅需通过 `--owner` 标志传递我们要查询的钱包地址，使用 `--token` 标志传递我们要查询的代币铸币地址，以及使用 `--verbose` 标志获得更详细的响应（这是本查询所必需的）。`-um` 标志告诉 CLI 使用 Solana 主网集群（尽管我们的搜索是确定性的并且不需要指定集群，CLI 工具会验证我们的铸币地址确实是该集群上的有效铸币地址）。\r\n\r\n你应该会看到类似以下的内容：\r\n\r\n![‘Solana CLI 结果’](https://img.learnblockchain.cn/2025/02/24/2-d53792f49c73ab1e4de6d2d3aed972cb.png)\r\n\r\n干得好！\r\n\r\n## 方法 2 - Solana-Web3.js\r\n\r\n在你的终端中创建一个新的项目目录和文件 **balance.js**，执行以下命令：\r\n\r\n```\r\nmkdir token-address && cd token-address && echo > address.js\r\n\r\n```\r\n\r\n安装 Solana Web3 依赖项：\r\n\r\n```\r\nyarn init -y\r\nyarn add @solana/web3.js@1\r\n\r\n```\r\n\r\n或者\r\n\r\n```\r\nnpm init -y\r\nnpm install --save @solana/web3.js@1\r\n\r\n```\r\n\r\n打开 **address.js** 文件，在第一行引入 **@solana/web3.js**。我们将从此包中解构 _PublicKey_ 类。\r\n\r\n```\r\nconst { PublicKey } = require('@solana/web3.js');\r\n\r\n```\r\n \r\n\r\n在第 3-6 行，定义你的钱包、铸币和相关程序（代币程序和关联代币程序）：\r\n\r\n```\r\nconst OWNER = new PublicKey('YOUR_WALLET_ADDRESS'); // 例如：E645TckHQnDcavVv92Etc6xSWQaq8zzPtPRGBheviRAk\r\nconst MINT = new PublicKey('YOUR_MINT_ADDRESS');    // 例如：EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v\r\nconst TOKEN_PROGRAM_ID = new PublicKey('TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA');\r\nconst ASSOCIATED_TOKEN_PROGRAM_ID = new PublicKey('ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL');\r\n\r\n```\r\n\r\n最后，通过调用 _PublicKey_ 的 `findProgramAddressSync()` 方法获取你的地址：\r\n\r\n```\r\nconst [address] = PublicKey.findProgramAddressSync(\r\n    [OWNER.toBuffer(), TOKEN_PROGRAM_ID.toBuffer(), MINT.toBuffer()],\r\n    ASSOCIATED_TOKEN_PROGRAM_ID\r\n);\r\n\r\nconsole.log('使用 Solana-Web3.js: ', address.toBase58());\r\n\r\n```\r\n\r\n`findProgramAddressSync` 方法根据种子和程序 ID 确定性地查找程序地址。在本例中，我们传递钱包地址、代币程序 ID 和铸币地址作为种子，并将关联代币程序 ID 作为程序 ID（这些种子及其顺序由 [关联代币程序定义](https://github.com/solana-labs/solana-program-library/blob/74ab831642efb6f12216a3ca700a39c057634de4/associated-token-account/program/src/lib.rs#L62-L76)）。\r\n\r\n运行你的代码。在终端中输入：\r\n\r\n```\r\nnode address\r\n\r\n```\r\n\r\n你应该会看到类似以下的内容：\r\n\r\n![‘Solana-Web3.js 结果’](https://img.learnblockchain.cn/2025/02/24/3-fe079bf1400e7fae6ae32160ee075485.png)\r\n\r\n干得好！\r\n\r\n_注意：你也可以使用 Connection 类向 Solana 集群发送 `getAssociatedTokenAddressSync` 请求。此方法需要网络请求，因此性能不如 `findProgramAddressSync` 方法；但是，它也可以找到在关联代币程序之外创建的任何代币账户。在特定情况下，这可能会很有用。_\r\n\r\n## 方法 3 - Solana 代币程序\r\n\r\n我们上一条指令有点杂乱。Solana SPL 代币 API 使得这个过程简单多了。让我们看看如何使用 SPL 代币 API 获取关联代币账户的地址。\r\n\r\n继续在与前一个方法相同的项目目录中，安装 SPL 代币程序：\r\n\r\n```\r\nyarn add @solana/spl-token\r\n\r\n```\r\n\r\n或者\r\n\r\n```\r\nnpm install --save @solana/spl-token\r\n\r\n```\r\n\r\n打开 **address.js** 文件，在第一行（我们之前的 import 之前）引入 **@solana/spl-token**。我们将解构该包中的 `getAssociatedTokenAddressSync` 方法。\r\n\r\n```\r\nconst { getAssociatedTokenAddressSync } = require('@solana/spl-token');\r\n\r\n```\r\n\r\n现在，在脚本底部，通过传递钱包和铸币地址作为参数调用 `getAssociatedTokenAddressSync` 方法：\r\n\r\n```\r\nconst address2 = getAssociatedTokenAddressSync(MINT, OWNER);\r\n\r\nconsole.log('使用 SPL-Token: ', address2.toBase58());\r\n\r\n```\r\n\r\n更简洁，对吧？这是因为在后台，SPL 代币 API 使用了我们在上一个示例中使用的相同 `findProgramAddressSync` 方法。你可以点击 `getAssociatedTokenAddressSync` 方法查看源代码。\r\n\r\n运行你的代码。在终端中输入：\r\n\r\n```\r\nnode address\r\n\r\n```\r\n\r\n你应该会看到两个方法返回相同的地址：\r\n\r\n![‘Solana 代币程序结果’](https://img.learnblockchain.cn/2025/02/24/4-b18e651c65f2744f31e276b5cff047a5.png)\r\n\r\n干得好！\r\n\r\n## 方法 4 - cURL\r\n\r\ncURL 是一个用于通过 URL 传输数据的命令行工具和库。大多数基于 \\*nix 的系统开箱即用地支持 cURL。通过运行以下命令检查你是否拥有它：\r\n\r\n```\r\ncurl -h\r\n\r\n```\r\n\r\n如果你尚未安装，请前往 [curl.se](https://curl.se/) 设置。\r\n\r\n一旦准备就绪，你只需在终端中输入此 HTTP 请求（确保替换你的端点、钱包地址和铸币地址）。在终端中输入：\r\n\r\n```\r\ncurl https://api.mainnet-beta.solana.com -X POST -H \"Content-Type: application/json\" -d '\r\n  {\r\n    \"jsonrpc\": \"2.0\",\r\n    \"id\": 1,\r\n    \"method\": \"getTokenAccountsByOwner\",\r\n    \"params\": [\\\r\n      \"YOUR_WALLET_ADDRESS\",\\\r\n      {\\\r\n        \"mint\": \"YOUR_MINT_ADDRESS\"\\\r\n      },\\\r\n      {\\\r\n        \"encoding\": \"jsonParsed\"\\\r\n      }\\\r\n    ]\r\n  }\r\n'\r\n\r\n```\r\n\r\n你应该会看到类似以下的内容：\r\n\r\n![‘Solana cURL 结果’](https://img.learnblockchain.cn/2025/02/24/6-3efe69c687985091aaac9b126c480967.png) _注意：如果你愿意，可以使用像 [jq](https://jqlang.github.io/jq/) 这样的包来返回格式化的 JSON 数据。_\r\n\r\n注意 `result.value[0].pubkey` 字段中返回了相同的地址 🙌。有关 `getTokenAccountsByOwner` 方法的更多信息，请查看我们的 [文档](https://www.quicknode.com/docs/solana/getTokenAccountsByOwner)。\r\n\r\n## 方法 5 - Rust\r\n\r\n如果你是 Rust 开发者，你还可以使用 [Solana Rust SDK](https://docs.rs/solana-sdk/latest/solana_sdk/)。在你的项目文件夹内，使用以下命令启动一个新项目：\r\n\r\n```\r\ncargo new token-address\r\n\r\n```\r\n\r\n导航到新创建的目录：\r\n\r\n```\r\ncd token-address\r\n\r\n```\r\n\r\n在你的 **Cargo.toml** 文件中添加必要的依赖：\r\n\r\n```\r\n[dependencies]\r\nsolana-sdk = \"1.16.14\"\r\nspl-associated-token-account = \"2.2.0\"\r\n\r\n```\r\n\r\n打开 **src/main.rs** 文件，在第一行导入必要的包：\r\n\r\n```\r\nuse solana_sdk::pubkey::Pubkey;\r\nuse spl_associated_token_account::get_associated_token_address;\r\nuse std::str::FromStr;\r\n\r\n```\r\n\r\n在第 5-6 行，定义你的所有者和铸币地址：\r\n\r\n```\r\nconst OWNER: &str = \"YOUR_WALLET_ADDRESS\";\r\nconst MINT: &str = \"YOUR_MINT_ADDRESS\";\r\n\r\n```\r\n\r\n最后，修改你的 `main` 函数，通过将所有者和铸币的公钥传递给 `get_associated_token_address` 方法来获取你的地址：\r\n\r\n```\r\nfn main() {\r\n    let owner_pubkey = Pubkey::from_str(OWNER).unwrap();\r\n    let mint_pubkey = Pubkey::from_str(MINT).unwrap();\r\n    let associated_token_address = get_associated_token_address(&owner_pubkey, &mint_pubkey);\r\n\r\n    println!(\"关联代币地址: {}\", associated_token_address);\r\n}\r\n\r\n```\r\n\r\n编译并运行你的代码。在终端中输入：\r\n\r\n```\r\ncargo build\r\ncargo run\r\n\r\n```\r\n\r\n你应该看到你的相同代币地址被返回：\r\n\r\n![‘Solana Rust 结果’](https://img.learnblockchain.cn/2025/02/24/7-9051c6afebec5bccf91822c3b445351f.png)\r\n\r\n干得好！\r\n\r\n## 总结\r\n\r\n干得不错！你现在有五个方便的工具来获取 Solana 关联代币账户的地址。如果你刚刚开始你的 Solana 之旅，这里有一些可能对你有所帮助的资源：\r\n\r\n- [Solana 基础知识](https://learnblockchain.cn/article/11166)\r\n- [Solana 文档](https://www.quicknode.com/docs/solana)\r\n\r\n我们很想听听你在构建什么。请在 [Discord](https://discord.gg/quicknode) 给我们留言，或者在 [Twitter](https://twitter.com/QuickNode) 上关注我们，以获取最新信息！\r\n\r\n \r\n\r\n>- 原文链接： [quicknode.com/guides/sol...](https://www.quicknode.com/guides/solana-development/spl-tokens/how-to-look-up-the-address-of-a-token-account)\r\n>- 登链社区 AI 助手，为大家转译优秀英文文章，如有翻译不通的地方，还请包涵～"},"author":{"user":"https://learnblockchain.cn/people/25306","address":null},"history":null,"timestamp":1740450529,"version":1}