0.30.1
Anchor - 发布说明 0.30.1
此次补丁版本中有许多生活质量方面的改进。你可以轻松地从 0.30.0
升级到这个版本,因为没有任何重大的破坏性变更。
如何升级
-
更新
anchor-cli
: -
将 Anchor crate(s) 更新至
0.30.1
。 -
将 TS 包更新至
0.30.1
。
推荐的 Solana 版本
虽然此版本支持高于 1.17.3
的任何版本,但推荐的 Solana 版本是 1.18.17
。你可以通过运行以下命令升级 Solana 工具:
IDL
转换旧版 IDL
IDL crate 中添加了一项新功能,用于将旧版 IDL(Anchor v0.30 之前)转换为新版 IDL。
要以编程方式转换旧版 IDL,请添加:
并使用
convert_idl
函数。
注意: 为了方便起见,此功能也已作为 CLI 命令实现,请参阅 idl convert
命令。
不支持的种子表达式
一些种子表达式,例如 &(my_account.data + 1).to_le_bytes()
:
目前无法存储在 IDL 中,但在 IDL 生成中存在一个回归问题,导致使用这些或类似的不支持表达式时会出现编译错误。
它们不再导致编译错误,但这也意味着客户端无法自动解析它们。
带有 address
约束的字段
使用字段表达式作为地址约束,例如:
在生成 IDL 时不再导致编译错误。
然而,使用非常量值的 address
约束的账户目前无法自动解析。出于这个原因,你可能需要考虑使用 has_one
约束代替:
在构建中覆盖 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:
idl type
命令
此命令从现有的 IDL 文件创建 TypeScript IDL 类型(带有 camelCase 字段):
idl build
工具链覆盖
请参阅 IDL 部分中的 解释。CLI 使用示例:
自动更新程序 ID
在首次构建程序时,如果 Anchor.toml
中没有 [programs.localnet]
条目,程序 ID 声明将自动更新。
请注意,这基本上与运行 anchor keys sync
相同,唯一的区别是它只会自动运行一次。
可升级程序克隆
使用以下方式克隆可升级程序:
由于 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!
会导致编译错误。
使用以下内容会导致编译错误:
- 指令参数中定义的类型(例如
struct
s) - 带有
const
泛型的类型 Vec<u8>
类型- 具有非单位返回类型的指令
- 可选账户(在客户端中)
bytemuckunsafe
账户序列化
另一个问题是元组结构字段是私有的(Rust 默认),现在它们是公开的。
pubkey!
宏
solana-program
提供了
pubkey!
以便轻松声明公钥:
这比 Pubkey::from_str
更方便:
然而,由于宏的实现方式,如果不包含 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
。
代币扩展的堆栈使用
新的 代币扩展约束 的堆栈使用已得到改进。
整数转换错误的传播
你现在可以使用 ?
传播整数转换错误:
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。
TypeScript
ATA 解析
在此版本中, 账户解析 支持已扩展到支持关联代币账户。
如果你在指令中使用 ATA,则在调用 accounts
方法时指定这些账户会导致类型错误。要解决此问题,只需从 accounts
调用中删除所有 ATA。
泛型中的定义类型
使用定义类型(结构体、枚举或类型别名)作为泛型参数,例如:
不再导致错误。
版本化交易
maxSupportedTransactionVersion
需要但未从 AnchorProvider
设置的问题已修复。
新的 errors 包
Anchor 错误已分离到一个新的包
@coral-xyz/anchor-errors
。
完整的显著更改列表请参阅 CHANGELOG。