网站Logo 北之屿

Anchor 中的账户读取

beiyu
11
2025-10-22

fetch() 的本质:从链上读取账户内容

在 Anchor 框架中,所有被 #[account] (rust编写合约时)标记的结构体(如 MarketConfig 等)都会对应链上的一个账户。

要想读取这些账户的实际数据,必须使用 program.account.xxx.fetch()

📘 示例

// 读取链上账户以获取所需依赖账户
const [configAcct, marketAcct] = await Promise.all([
  program.account.config.fetch(config),
  program.account.market.fetch(market),
]);

此时configAcctmarketAcct实际上是这样的结构:

{
  authority: PublicKey,  // 已经是 PublicKey 实例
  feeRate: BN            // 是一个 BN 对象
}

如何确认 xxx 的结构?

Rust 端使用 #[account] 定义的结构体,在 Anchor 编译后会出现在
IDL(Interface Definition Language)types 部分。

💡 Rust 示例

use anchor_lang::prelude::*;

#[account]
pub struct Config {
    pub authority: Pubkey,
    pub fee_rate: u64,
}

#[account]
pub struct Market {
    pub symbol: String,
    pub config: Pubkey,
}

编译后Anchor 会生成一个 IDL 文件,其中一部分内容长这样👇:

"types": [
{
  "accounts": [
    {
      "name": "config",
      "type": {
        "kind": "struct",
        "fields": [
          { "name": "authority", "type": "publicKey" },
          { "name": "feeRate", "type": "u64" }
        ]
      }
    },
    {
      "name": "market",
      "type": {
        "kind": "struct",
        "fields": [
          { "name": "symbol", "type": "string" },
          { "name": "config", "type": "publicKey" }
        ]
      }
    }
  ]
}
]

💬 说明:

  • 每个 #[account] 都会成为一个 type 定义;

  • kind 固定为 "struct"

  • fields 对应 Rust 中的字段;

  • 所有字段类型会被转换为 Anchor 的标准 IDL 类型(如 publicKeyu64string 等)。

通过 fetch() 获取数据后读取字段

const authority = configAcct.authority;
// feeRate 是 BN,需要转成数字或字符串
const feeRate = configAcct.feeRate.toNumber();
const config = marketAcct.config;
const symbol = marketAcct.symbol;

常见误区

错误写法

原因

new PublicKey(configAcct.authority)

❌ 多此一举:authority 已经是 PublicKey 实例

Number(configAcct.feeRate)

⚠️ 不安全:如果数值超过 JS 的安全整数范围,会失真

configAcct.feeRate / 1000

❌ 报错:BN 不能直接做算术,需要用 .div().mul()

动物装饰