{"author":{"address":"0x2b624faC1616D08684Cf1d21793c2f39CC1895a0","user":"https://learnblockchain.cn/people/2540"},"content":{"body":"本文是对[Solana官网文档](https://solana.com/docs/programs/anchor)的翻译。我会根据**我的实操**对原文修改，并且针对初学者不容易理解的地方做了更多的翻译。\r\n\r\nAnchor框架是让构建Solana程序更加容易的一个工具。无论你是初学者，还是有经验的开发者，Anchor都会让你更加容易地编写、测试和部署Solana程序。\r\n\r\n本文共四个部分：\r\n\r\n1. 创建一个新的Anchor项目\r\n2. 构建并测试你的程序\r\n3. 部署至Solana网络\r\n4. 理解项目文件结构\r\n\r\n\u003e **提示**\r\n\u003e 我的前两篇文章已经带你安装好了环境，并初步认识了项目目录结构，这一讲会带你理解更多关键细节问题，学完本文，你将会对Anchor项目更有掌控感！\r\n\r\n如果你还没有安装环境，请阅读我前面的文章，这里默认你已经安装好了。\r\n\r\n## 创建一个新的Anchor项目\r\n\r\n要创建一个新的Anchor项目，使用`anchor init`命令，后面跟上你的项目名称。如下所示：\r\n\r\n```bash\r\n# 创建项目\r\nanchor init my-project\r\n\r\n# 进人项目目录\r\ncd my-project\r\n```\r\n\r\n这会创建一个默认的Solana程序，位置在`/programs/my-project/src/lib.rs`。以下是完整的代码：\r\n\r\n```rust\r\nuse anchor_lang::prelude::*;\r\n \r\ndeclare_id!(\"3ynNB373Q3VAzKp7m4x238po36hjAGFXFJB4ybN2iTyg\");\r\n \r\n#[program]\r\npub mod my_project {\r\n    use super::*;\r\n \r\n    pub fn initialize(ctx: Context\u003cInitialize\u003e) -\u003e Result\u003c()\u003e {\r\n        msg!(\"Greetings from: {:?}\", ctx.program_id);\r\n        Ok(())\r\n    }\r\n}\r\n \r\n#[derive(Accounts)]\r\npub struct Initialize {}\r\n```\r\n\r\n你可以先不用理解代码，我下一篇文章会详细讲解。其中，在`declare_id!`里面的值是 Program ID，是程序的唯一标识符。\r\n\r\n\u003e 用 EVM 生态的概念作为类比，`智能合约` 对应 `Solana程序`， `合约地址` 对应 `Program ID`。\r\n\r\n当你执行`anchor build`命令，会生成一个密钥对文件（如果不存在），存储在`/target/deploy/my_project-keypair.json`，Program ID 就是这个密钥对的公钥。\r\n\r\nAnchor 也会自动生成一个测试文件，位置在`/tests/my-project.ts`，里面展示了如何使用 Typescript 调用这个程序的 `initialize` 函数。\r\n\r\n如果你更喜欢使用 Rust 编写测试，在初始化项目的时候，加上 `--test-template rust` 标志就可以生成由 Rust 编写的测试用例。如下所示：\r\n\r\n```bash\r\nanchor init --test-template rust my-project\r\n```\r\n\r\n这个 Rust 测试文件生成在 `/tests/src/test_initialize.rs`。\r\n\r\n\r\n## 构建并测试你的程序\r\n\r\n执行`anchor build`命令是构建Solana程序，这将会把程序编译为一个.so文件，位置在`/target/deploy/my_project.so`。当你部署程序时，实际上就是把这个文件内容存储在Solana网络上对应的账户里，称为`可执行程序`。\r\n\r\n\u003e **解释**  \r\n\u003e 这里提到了`.so文件`和`账户`，你先对这些名词有个印象，我下一篇文章会详细讲解。  \r\n\r\n执行`anchor test`命令是测试Solana程序，默认情况下，根目录下`Anchor.toml`配置文件指定了 `localnet` 集群（也就是 Solana 本地网络）。当你在本地网络上开发，执行 anchor test 会自动发生下面的过程：\r\n\r\n1. **启动一个本地 Solana 验证节点**\r\n\r\n2. **构建和部署你的程序至本地集群**  \r\n\r\n3. **运行`tests`文件夹里的测试用例**  \r\n\r\n4. **停止本地 Solana 验证节点**  \r\n\r\n此外，你可以手动启动一个本地 Solana 验证节点，并在这个集群上面运行测试。如果你希望在迭代你的程序时保持验证节点运行，这个非常有用。而且，更方便检查账户和交易日志。\r\n\r\n打开新终端，执行下面命令，手动启动一个本地 Solana 验证节点：\r\n\r\n```bash\r\nsolana-test-validator\r\n```\r\n\r\n打开新终端，执行下面命令，查看交易日志：\r\n\r\n```bash\r\nsolana logs\r\n```\r\n\r\n在项目根目录终端，执行下面命令，运行测试：\r\n\r\n```bash\r\nanchor test --skip-local-validator\r\n```\r\n\r\n因为已经手动启动好了Solana验证节点，使用`--skip-local-validator`标志可以中止自动启动本地Solana验证节点。\r\n\r\n\r\n## 部署至Solana网络\r\n\r\n默认情况下，根目录下`Anchor.toml`配置文件指定了本地集群，如下所示：\r\n\r\n```toml\r\n[provider]  \r\ncluster = \"Localnet\"  \r\nwallet = \"~/.config/solana/id.json\"  \r\n```\r\n\r\n为了将你的程序部署至Solana测试网络，修改以上配置，将 `Localnet` 改为 `Devnet`。**注意，wallet 对应的钱包需要有足够的 SOL 测试币**。这时候无论执行`anchor deploy`命令，还是`anchor test`命令，都会使用最新的配置，也就是会将你的程序部署至Solana测试网络集群。\r\n\r\n如果你要将程序部署至Solana主网集群，同样地，将 `cluster` 的值修改为 `Mainnet` 即可。\r\n\r\n## 更新Solana程序\r\n\r\nSolana程序是可以被更新的，即可以对同一个 Program ID 重复部署不同的程序。当你修改了程序代码，运行`anchor build`命令生成一个新的`.so文件`，再运行`anchor deploy`命令重新部署，这将会更新Solana程序。\r\n\r\n\u003e **提示**\r\n\u003e 如果你了解 EVM 生态，可以把这个过程类比为 **智能合约的升级**。在 EVM 中，升级合约是一件很麻烦的事，而 Solana 天生就支持升级。\r\n\r\n## 关闭Solana程序\r\n\r\n在 Solana 中，有一个**租金**的概念，当你把程序部署至Solana网络集群中，需要支付相应的租金（根据程序大小按比例支付）。然而，这个租金和现实世界的房租不一样，因为，Solana 里的租金可以全额退回。\r\n\r\n为了全额退回你支付的租金，你需要使用 `solana program close \u003cPROGRAM_ID\u003e` 命令关闭你的Solana程序。如下所示：\r\n\r\n```\r\nsolana program close 3ynNB373Q3VAzKp7m4x238po36hjAGFXFJB4ybN2iTyg --bypass-warning\r\n```\r\n\r\n当你关闭程序时，Solana 会给出一个警告，可以使用`--bypass-warning`选项来跳过这些警告。\r\n\r\n**注意：一旦程序被关闭，Program ID 将不能再用于部署新的程序。**\r\n\r\n\r\n## 理解项目文件结构\r\n\r\n\u003e 官网文档对于项目文件结构，介绍的非常简单。你可以看我的上一篇文章，我详细讲解了项目的目录结构，并带着你一步步精简了目录，移除了初学者不必关心的目录和文件。\r\n\r\n### Programs 文件夹\r\n\r\n`/programs`文件夹下面存放了所有的程序，在一个工作空间内，可以包含多个程序。 例如：`/programs/程序1`， `/programs/程序2`， `/programs/程序3`等等。\r\n\r\n### Tests 文件夹\r\n\r\n`/tests`文件夹包含了你的项目里所有的测试文件，创建项目时会自动创建一个默认的测试文件。\r\n\r\n### Target 文件夹\r\n\r\n`/target`文件夹包含了构建时输出的文件。下面是主要的子文件夹：\r\n\r\n- `/deploy` 包含密钥对（公钥就是 Program ID）和你的程序二进制文件（.so文件）\r\n\r\n- `/idl` 包含你的程序 JSON IDL。 （IDL 可以类比为 solidity 的 ABI，用于跟程序交互）\r\n\r\n- `/types` 包含 IDL 的 TypeScript 类型。（/tests文件夹下的测试文件引用了这个类型与Solana程序交互）\r\n\r\n### Anchor.toml 文件\r\n\r\nAnchor.toml 文件配置了你项目的工作区设置。\r\n\r\n### .anchor 文件夹\r\n\r\n包括一个 program-logs 文件夹，里面包含了上次运行测试文件时的交易日志。\r\n\r\n### App 文件夹\r\n\r\n`/app`是一个空文件夹，你可以用来存放你的前端代码，这是可选的。\r\n\r\n到这里，本文就讲完了。下一篇我们来学习Rust主程序，如果你想提前看到我的更新，可以关注我的公众号：`认知那些事`。","title":"Solana笔记 03.认识Anchor框架"},"history":null,"timestamp":1734085724,"version":1}