LogoAnchor 中文文档
Anchor 中文文档Anchor 更新Release Notes

0.30.1

Anchor - 发布说明 0.30.1

此次补丁版本中有许多生活质量方面的改进。你可以轻松地从 0.30.0 升级到这个版本,因为没有任何重大的破坏性变更。


如何升级

  1. 更新 anchor-cli

    avm install 0.30.1
  2. 将 Anchor crate(s) 更新至 0.30.1

  3. 将 TS 包更新至 0.30.1

推荐的 Solana 版本

虽然此版本支持高于 1.17.3 的任何版本,但推荐的 Solana 版本是 1.18.17。你可以通过运行以下命令升级 Solana 工具:

solana-install init 1.18.17

IDL

转换旧版 IDL

IDL crate 中添加了一项新功能,用于将旧版 IDL(Anchor v0.30 之前)转换为新版 IDL。

要以编程方式转换旧版 IDL,请添加:

anchor-lang-idl = { version = "0.1.1", features = ["convert"] }

并使用 convert_idl 函数。

注意: 为了方便起见,此功能也已作为 CLI 命令实现,请参阅 idl convert 命令

不支持的种子表达式

一些种子表达式,例如 &(my_account.data + 1).to_le_bytes()

#[derive(Accounts)]
pub struct SeedMathExpr<'info> {
    #[account(seeds = [&(my_account.data + 1).to_le_bytes()], bump)]
    pub math_expr_account: UncheckedAccount<'info>,
    pub my_account: Account<'info, MyAccount>,
}
 
#[account]
pub struct MyAccount {
    data: u64,
}

目前无法存储在 IDL 中,但在 IDL 生成中存在一个回归问题,导致使用这些或类似的不支持表达式时会出现编译错误。

它们不再导致编译错误,但这也意味着客户端无法自动解析它们。

带有 address 约束的字段

使用字段表达式作为地址约束,例如:

#[derive(Accounts)]
pub struct Initialize<'info> {
    #[account(address = my_account.authority)]
    pub authority: UncheckedAccount<'info>,
    pub my_account: Account<'info, MyAccount>,
}
 
#[account]
pub struct MyAccount {
    authority: u64,
}

在生成 IDL 时不再导致编译错误。

然而,使用非常量值的 address 约束的账户目前无法自动解析。出于这个原因,你可能需要考虑使用 has_one 约束代替:

#[derive(Accounts)]
pub struct Initialize<'info> {
    pub authority: UncheckedAccount<'info>,
    #[account(has_one = authority)]
    pub my_account: Account<'info, MyAccount>,
}

在构建中覆盖 nightly 版本

IDL 生成目前使用 nightly 编译器来构建 IDL,这可能会导致在某些 nightly 版本上出现编译错误。

在此版本中,你现在可以使用 RUSTUP_TOOLCHAIN 环境变量覆盖 nightly 版本。

递归生成

在生成时存在递归外部类型解析的编译错误,现已修复。如果你想更详细地了解这个问题,请参阅 此处

新的 spec crate

对 IDL crate 进行更改,例如添加诸如 convert 功能,即使规范本身没有更改,也需要提升版本以获取更改。

为了解决这个问题,引入了一个新的 crate,其中仅包含 IDL 规范。新 crate 的版本将用于 idl.metadata.spec 字段,以区分不同的 IDL。

注意: 可以通过主 IDL crate 从 anchor_lang_idl::types 访问此 crate。

CLI

idl convert 命令

此命令允许你使用新的 anchor idl convert 命令转换旧版 IDL:

anchor idl convert <PATH_TO_IDL_JSON>

idl type 命令

此命令从现有的 IDL 文件创建 TypeScript IDL 类型(带有 camelCase 字段):

anchor idl type <PATH_TO_IDL_JSON>

idl build 工具链覆盖

请参阅 IDL 部分中的 解释。CLI 使用示例:

RUSTUP_TOOLCHAIN="nightly-2024-05-09" anchor idl build

自动更新程序 ID

在首次构建程序时,如果 Anchor.toml 中没有 [programs.localnet] 条目,程序 ID 声明将自动更新。

请注意,这基本上与运行 anchor keys sync 相同,唯一的区别是它只会自动运行一次。

可升级程序克隆

使用以下方式克隆可升级程序:

[test.validator]
url = "https://api.mainnet-beta.solana.com"
 
[[test.validator.clone]]
address = "TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb"

由于 Solana 1.17.12 中的破坏性更改,会导致程序无法使用。

此问题已从 Anchor 和 Solana 的方面修复。但是,它要求使用 solana-cli >=1.18.10

文件系统错误改进

当文件系统中找不到文件时,默认的 Rust 错误不会记录文件路径,这使得调试变得困难。

在此版本中,文件系统相关的错误还包括文件的路径。

Lang

使用旧版 IDL 的 declare_program!

declare_program! 宏现在可以与旧版 IDL(Anchor v0.30 之前)一起使用。

只要程序能够正确描述旧版 IDL 规范,这就可以很好地工作。然而,如果程序使用非默认功能,例如零拷贝或 repr 修改,则程序的声明要么无法编译,要么无效。在这种情况下,主要有两种解决方案:

  • 使用 idl convert 命令,并手动修复无效部分
  • 通过将程序升级到 Anchor v0.30 来生成程序的 IDL

后一个选项是首选,因为它不容易出错。如果在升级时遇到依赖问题,只需在生成 IDL 时删除它们,因为 IDL 生成只关心签名,所有程序逻辑,包括所有依赖项(Anchor 除外),都可以在生成 IDL 时删除。这里 是一个你可以从中生成 IDL 的示例程序。

简而言之,IDL 应该优先使用 v0.30 生成,而不是转换方法,因为如果旧规范足够可靠地描述程序,就不需要新的 IDL 规范。

declare_program! 修复

在许多情况下,新的 declare_program! 会导致编译错误。

使用以下内容会导致编译错误:

  • 指令参数中定义的类型(例如 structs)
  • 带有 const 泛型的类型
  • Vec<u8> 类型
  • 具有非单位返回类型的指令
  • 可选账户(在客户端中)
  • bytemuckunsafe 账户序列化

另一个问题是元组结构字段是私有的(Rust 默认),现在它们是公开的。

pubkey!

solana-program 提供了 pubkey! 以便轻松声明公钥:

let key = pubkey!("11111111111111111111111111111111");

这比 Pubkey::from_str 更方便:

use std::str::FromStr;
let key = Pubkey::from_str("11111111111111111111111111111111").unwrap();

然而,由于宏的实现方式,如果不包含 solana-program 到你的依赖列表中,就无法从 Anchor 使用它,因为宏专门使用了 ::solana_program

你现在可以直接使用 pubkey!,因为它已从 anchor_lang::prelude 导出。

请注意,由于 solana_program 是从 anchor_lang 导出的,如果 pubkey! 是你添加它的原因,你也可以从你的 Cargo.toml 中删除 solana-program 依赖项。

ID_CONST 常量

declare_id!declare_program! 声明的程序 ID 具有 ID 作为 static 声明,这不允许编译时检查。

这两个宏现在都有一个新的常量(ID_CONST),它基本上与 ID 相同,但被声明为 const 而不是 static

代币扩展的堆栈使用

新的 代币扩展约束 的堆栈使用已得到改进。

整数转换错误的传播

你现在可以使用 ? 传播整数转换错误:

let n: i32 = u32::MAX.try_into()?;

SPL

导出 ATA crate

[spl-associated-token-account](https://crates.io/crates/spl-associated-token-account) crate 现在从 anchor_spl::associated_token` 重新导出。

类似于你可以 移除 mpl-token-metadata crate 的方式,你也可以移除 spl-associated-token-accounts crate。

[dependencies]
anchor-spl = "0.30.1"
- spl-associated-token-account = "3.0.2"

TypeScript

ATA 解析

在此版本中, 账户解析 支持已扩展到支持关联代币账户。

如果你在指令中使用 ATA,则在调用 accounts 方法时指定这些账户会导致类型错误。要解决此问题,只需从 accounts 调用中删除所有 ATA。

泛型中的定义类型

使用定义类型(结构体、枚举或类型别名)作为泛型参数,例如:

param: GenericStruct<MyStruct>,

不再导致错误。

版本化交易

maxSupportedTransactionVersion 需要但未从 AnchorProvider 设置的问题已修复。

新的 errors 包

Anchor 错误已分离到一个新的包 @coral-xyz/anchor-errors


完整的显著更改列表请参阅 CHANGELOG