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

0.29.0

Anchor - 版本发布说明 0.29.0

Anchor 维护了一份 更新日志,但 理解哪些内容发生了变化、变化带来了什么影响以及如何迁移并不容易。因此,发布说明应运而生,它为每个版本提供了易于理解和操作的视图。


如何更新

  1. 更新 avm

    cargo install --git https://github.com/coral-xyz/anchor --tag v0.29.0 avm --locked
  2. 更新 anchor-cli

    avm install latest
  3. 将 Anchor crate(s) 更新到 0.29.0。可选地,运行 cargo update 以更新 其他依赖到最新的兼容版本。

  4. 将 TS package(s) 更新到 0.29.0

不再支持 Solana 1.14

现在支持的最低 Solana 版本是 1.16.0,因为:

  • 所有集群,包括主网测试版,现在都运行 ^1.16
  • 1.141.16 之间存在 兼容性问题

如果你还在使用 Solana 1.14,通过以下命令更新:

solana-install init 1.17.0

覆盖工作区的工具链

Anchor.toml 现在有一个名为 [toolchain] 的新部分,允许覆盖工作区内的当前工具链版本。

[toolchain]
anchor_version = "0.29.0" # 要使用的 `anchor-cli` 版本
solana_version = "1.17.0" # 要使用的 Solana 版本

注意事项

  • 字段是可选的。
  • anchor_version 需要安装 avm
  • 在此版本之前,Anchor.toml 中的 anchor_versionsolana_version 键仅用于 Docker 可验证构建。现在,所有命令都通过 [toolchain] 部分工作。

通过 avm 从提交安装 CLI

可以通过以下命令从提交安装 CLI:

cargo install --git https://github.com/coral-xyz/anchor --rev 6cf200493a307c01487c7b492b4893e0d6f6cb23 anchor-cli --locked

但这会覆盖 anchor 二进制文件,并且与 avm 配合得不好。

在这个版本中,avm 支持从提交安装和切换。

通过提交安装,使用 avm install <VERSION>-<COMMIT>

# <VERSION>-<COMMIT>
avm install 0.28.0-6cf200493a307c01487c7b492b4893e0d6f6cb23
 
# 完整的提交哈希
avm install 6cf200493a307c01487c7b492b4893e0d6f6cb23
 
# 简短的提交哈希
avm install 6cf200

使用 不同的版本,使用 avm use <VERSION>-<COMMIT>

avm use 0.28.0-6cf200493a307c01487c7b492b4893e0d6f6cb23

指定 toolchain.anchor_version<VERSION>-<COMMIT>

[toolchain]
anchor_version = "0.28.0-6cf200493a307c01487c7b492b4893e0d6f6cb23"

多文件模板

使用 anchor initanchor new 创建的程序只有一个 lib.rs 文件,但并不是每个人都喜欢单文件编程。

将程序拆分为多个文件的流行方式如下所示:

├── constants.rs
├── error.rs
├── instructions
│   ├── initialize.rs
│   └── mod.rs
├── lib.rs
└── state
    └── mod.rs

要初始化一个具有这种程序结构的工作区,请运行:

anchor init <NAME> --template multiple

或者如果你有一个现有的工作区:

anchor new <NAME> --template multiple

测试中的可升级程序

你现在可以在 anchor test 中配置程序的可升级性。

Anchor.toml 中:

[test]
upgradeable = true

或针对单个程序:

[[test.genesis]]
address = "22Y43yTVxuUkoRKdm9thyRhQ3SdgQS7c7kB6UNCiaczD"
program = "swap.so"
upgradeable = true

Lamport 实用工具

由于涉及的类型较为复杂,从 PDA 转移 lamports 相当复杂。

不再使用

**ctx.accounts.from.to_account_info().try_borrow_mut_lamports()? -= amount;
**ctx.accounts.to.to_account_info().try_borrow_mut_lamports()? += amount;

你可以使用

ctx.accounts.from.sub_lamports(amount)?;
ctx.accounts.to.add_lamports(amount)?;

同样地,获取 lamports 时,不再使用

let lamports = ctx.accounts.my_account.to_account_info().lamports();

你可以使用

let lamports = ctx.accounts.my_account.get_lamports();

注意: 新方法不仅更符合人体工程学,而且比之前的示例更高效。这是因为 to_account_info 方法在内部克隆了数据,而新方法使用了底层数据的引用。

类型安全的上下文 Bumps

在此版本之前,ctx.bumps 是一个 BTreeMap<String, u8>,这并未为键(账户名称)提供类型安全。

let bump = *ctx.bumps.get("my_account").unwrap();

在这个版本中,有一个自动生成的结构体来保存 bump 值。

let bump = ctx.bumps.my_account;

注意: 新方法不仅更直观,而且更高效。这主要是因为 BTreeMap 是堆分配的,并且它必须偶尔调整大小和增长。

idl-build 功能

现在有一种通过编译生成 IDL 的新方法。

在你的程序的 Cargo.toml 中添加 idl-build 功能来尝试它。

[features]
idl-build = ["anchor-lang/idl-build"]

当运行 anchor build 时,IDL 将自动生成,但如果你只想生成 IDL,请运行:

anchor idl build

注意事项

  • 所有用于 IDL 生成的 crate 都需要添加到 idl-build 功能列表中。
[features]
idl-build = [
    "anchor-lang/idl-build",
    "anchor-spl/idl-build",
    "another-program/idl-build"
]
  • 支持编译时检查。
  • 只要外部 crate 有 idl-build 功能,就支持从其他 Anchor 程序引入的外部类型(见 another-program/idl-build)。
  • 可以同时使用冲突的类型名称,例如 some_module::MyTypeanother_module::MyType
  • 由于 Rust 编译时间,生成时间比默认方法(解析)慢得多。
  • 尽管大部分内容都很好用,但仍有一些部分尚未完全完善。如果你遇到问题,请 创建一个问题

类型别名

Anchor IDL 现在支持类型别名。

pub type U8Array = [u8; 8];
 
#[program]
pub mod my_program {
    use super::*;
 
    pub fn type_alias(ctx: Context<TypeAlias>, u8_array: U8Array) -> Result<()> {
        msg!("{:?}", u8_array);
        Ok(())
    }
}
 
#[derive(Accounts)]
pub struct TypeAlias {}

生成以下 IDL:

{
  "version": "0.1.0",
  "name": "my_program",
  "instructions": [
    {
      "name": "typeAlias",
      "accounts": [],
      "args": [
        {
          "name": "u8Array",
          "type": {
            "defined": "U8Array"
          }
        }
      ]
    }
  ],
  "types": [
    {
      "name": "U8Array",
      "type": {
        "kind": "alias",
        "value": {
          "array": ["u8", 8]
        }
      }
    }
  ]
}

注意: 此示例目前仅适用于默认的 IDL 生成方法(解析),因为默认 Rust 类型的类型别名在

idl-build 中无法正常工作 (#2640).

导出 mpl-token-metadata

现在,启用了 metadata 功能的 anchor-spl 会导出 mpl-token-metadata crate。

注意: 考虑移除 mpl-token-metadata 依赖以减少版本冲突的可能性:

[dependencies]
anchor-spl = { version = "0.29.0", features = ["metadata"] }
- mpl-token-metadata = "1.13.1"

并从 anchor-spl 使用导出的 crate:

use anchor_spl::metadata::mpl_token_metadata;

TypeScript SDK 改进

  1. Program.addEventListener 方法现在是强类型的 — 事件名称和回调返回的事件类型正确,而不是 any

  2. anchor.workspace 现在按需懒加载程序。测试中未使用的程序不会被加载,因此不会引发错误。

  3. JavaScript 的惯例是使用驼峰命名法命名属性,但程序是通过帕斯卡命名法访问的,例如 anchor.workspace.MyProgram,这不太直观。在本版本中,两种命名法都可以使用。

    const camel = anchor.workspace.myProgram;
    const pascal = anchor.workspace.MyProgram;
  4. 移除了 assertbase64-js 依赖。

新的 Docker 镜像

之前的镜像(projectserum/build) 现已弃用,新的镜像是 backpackapp/build

要拉取最新镜像,请运行:

docker pull backpackapp/build:v0.29.0

注意: anchor build --verifiable 现在可以与最新镜像配合使用。

性能提升

0.29.0 在各方面性能明显提升,最大的是 二进制文件大小 减少了约 36%(相比 0.28.0)!

类似的基准测试可以在 计算单元栈内存 中找到。

注意: 基准测试结果会因程序而异,但整体趋势应该是一致的。


完整变更列表请参阅 更新日志.