跟我一起从0开始学习Solana合约开发,一起实操,一起做项目。这是一个系列文章,系统地记录了我的学习笔记。
当你第一次看到anchor init
初始化的项目里有那么多文件夹和文件,你什么感觉?
我特别想重命名一些文件,想删除一些文件,但是做不到啊……因为编译会报错!我心一横,干脆把每个目录都搞清楚,当足够了解就可以自如的控制它们的去留……呵呵。
接下来,我们拆解所有目录和文件,把初学者不必关心的全部清理掉,专注于学习智能合约的开发。
在solana中,
智能合约
称为程序
,这和evm中编写的solidity智能合约叫法不同。因此,在你阅读本系列文章的时候,无论见到solana智能合约
还是solana程序
,它们都是指的同一个东西。
下面是我们初始化生成的目录结构:
我先按顺序给出一个简单解释:
目录或文件 | 简要说明 |
---|---|
app | 存放前端项目,html、css、js等 |
migrations | 存放部署脚本 |
node_modules | yarn命令自动生成的js依赖库 |
programs | solana主程序目录,写合约的地方 |
target | anchor命令自动生成的目标文件 |
tests | 写合约测试代码的地方 |
.gitignore | git仓库忽略文件 |
.prettierignore | prettier忽略文件 |
Anchor.toml | anchor项目的主配置文件 |
Cargo.toml | rust项目的主配置文件 |
package.json | nodejs依赖包管理 |
tsconfig.json | typescript配置 |
yarn.lock | yarn命令自动生成 |
对于一个刚开始学习solana开发的人员,以上哪些文件和目录不是必须的?如果要删除一些目录和文件,减少初学者不必要的注意力,该删除哪些?
app
目录是前端代码的存放位置,初学者可以直接删除。
node_modules
, target
, yarn.lock
都是由相应工具管理并自动生成的,忽略即可。
.gitignore
, .prettierignore
已经在初始化项目的时候自动写好了忽略文件和目录,提交Git仓库必须要的文件。
package.json
, tsconfig.json
这是nodejs依赖管理,和typescript配置,必须保留,因为要测试solana程序,需要编写ts脚本。
以上都比较简单,了解一下即可,接下来我们就要详细说说剩余的目录了。
先给出结论:migrations这个文件夹可以放心地删除,下面我们说说原因。
migrations/deploy.ts
的作用是允许用户自定义部署逻辑。例如:
1.配置更复杂的部署流程(如多程序依赖)。
2.执行额外的操作(如为程序分配初始账户、设置状态等)。
3.自定义部署顺序(例如多个程序需要按顺序部署)。
然而对于初学者,我们暂时不需要那么复杂的部署流程,等到我们学到一定程度,需要的时候再增加这个目录即可。
也许你会有疑问:删除之后,会影响到anchor deploy
和 anchor test
命令的执行吗?
答案是:不会!我们分别看一下它们的执行原理:
对于anchor deploy
,它的行为主要有三步:
1.读取 Anchor.toml 中定义的程序路径。
2.自动编译 programs/ 下的所有程序。
3.将程序部署到配置的 Solana 网络(如 localnet 或 devnet)。
对于anchor test
,它的行为主要有两步:
1.编译和部署 programs/ 下的程序。
2.在 tests/ 目录中查找测试脚本(例如 solana-guide.ts),并运行其中的测试。
以上两个过程都与 migrations/deploy.ts 完全无关,tests/ 和 migrations/ 也是独立的,因此,删除migrations文件夹不会影响正常的部署和测试。
上面提到了 Anchor.toml,所以我们先来说这个文件。从前面的叙述可以看到,它们都是依赖根目录下的 Anchor.toml 定义的程序路径,直接读取并自动编译 programs/ 下的所有程序,这是项目的核心配置文件。
至于里面的配置信息,我们这一讲先不关心,你只记住它必须保留即可。
programs
是主程序目录,是编写solana智能合约的地方。下面是它的目录结构:
敲黑板!重点来了,我们需要修改的东西主要都在这个目录下,接下来就要详细讲讲这里面的知识。
1.这些文件夹名称能修改吗?
programs
不能修改,这是anchor框架预定义好的,每次编译都会自动找这个目录,它下面的每一个子目录都代表一个solana程序(智能合约)。子目录solana-guide
可以修改,本文末尾会给出修改的流程,将目录改为guide_1
方便按学习顺序扩展多个程序。
2.如何界定哪些代码属于同一个智能合约?
在solidity中,智能合约是用关键字contract
界定边界,每个 contract 是一个独立的逻辑单元,部署为单独的合约地址。然而,在solana中没有 contract 这一概念,按照anchor框架的标准,programs下面的每一个子目录都会编译为一个二进制文件,即一个智能合约
。
3.删除src目录可以吗?rust代码都必须放在src目录下吗?
不是必须,但最好这样。src目录存放源文件,删除src目录后,将.rs文件
和.toml文件
放在同级目录并不是一个好主意。虽然你可以这么做,但这只适用于简单代码,一旦需要模块化,有多个.rs文件,就不好管理了,也无法和标准的项目兼容。
4.这个目录下的 Cargo.toml 和 根目录下的Cargo.toml有什么区别?
当前目录下的Cargo.toml
是这个Solana程序
的专用配置文件,不会影响到其他的子程序。根目录下的Cargo.toml
管理整个项目的依赖,工作区配置,跨所有程序的依赖。
5.Xargo.toml是什么?
这是针对solana的交叉编译配置文件,当你需要把程序嵌入到设备或其他情况下才有用,一般不需要修改,可以删除。
这个目录存放测试代码,用typescript编写,我们需要学习测试solana程序,需要保留。
我们在学习的过程中,要开发多个程序,总不能每次都执行anchor init {项目名}
来生成新的目录,所以在这里修改子程序目录命名,以适合多程序开发。
anchor init
生成的目录布局是推荐的标准布局。如果要自定义目录布局,需要遵守anchor的规则:1.Anchor.toml必须位于项目根目录,这是 Anchor 的核心配置文件,用于定义项目名称、程序路径、部署地址等。
2.每个 Solana 程序必须放在 programs/ 子目录中。
3.tests/ 目录存放测试代码,不要修改。
接下来,我们将programs/solana-guide
改为programs/guide_1
,我们按照 guide_{1...}这样的子程序目录来讲解每一部分的内容。
修改目录名之后,需要把程序的入口函数名也同步修改,保持一致。打开src/lib.rs
修改如下:
#[program]
pub mod guide_1 {
// ...
}
如果
目录名
和程序入口函数名称
不一致,虽然可以正常编译、正常测试程序,但是会有一些莫名奇妙的错误信息打印,如:Error: No such file or directory (os error 2)...保持目录名和程序入口函数名称一致是一个好习惯。
改完名称后,我们还需要做一些配置的修改:
1.根目录 Cargo.toml 中的 members 配置
members = [
# 因为是通配符,所以不用修改。如果你的配置是具体的子程序目录名,请修改。
"programs/*"
]
2.programs/guide_1/Cargo.toml中的name字段(有两处)
[package]
name = "guide_1"
[lib]
name = "guide_1"
3.Anchor.toml中的程序名称配置
[programs.localnet]
# 修改前
solana_guide = "6n9iWA5k17ajMtWk3U6jsHcBaH4Wrh1gUXurtVq1GPGs"
# 修改后(将solana_guide改为guide_1)
guide_1 = "6n9iWA5k17ajMtWk3U6jsHcBaH4Wrh1gUXurtVq1GPGs"
4.测试文件中的程序名称
将文件名tests/solana_guide.ts
改为tests/guide_1.ts
,这是非必须的,推荐修改保持一致。
打开tests/guide_1.ts
修改下面的内容:
// ...
import { Guide1 } from "../target/types/guide_1";
describe("guide_1", () => {
// ...
}
5.清理并重新构建
anchor clean # 清理项目
anchor build # 重新构建
anchor test --skip-local-validator # 测试
如果你遇到了错误:
Error Number: 4100. Error Message: The declared program id does not match the actual program id.
请在项目根目录下执行
anchor keys sync
同步程序ID就好了。
最后,对本文的内容做一个总结:
1.必须保留的目录和文件(Anchor和solana开发的核心)
1.Anchor.toml 项目配置文件,定义了程序路径、Program ID、网络配置等。
2.programs/<program_name>/ 主程序代码目录,必须保留,包括(src/lib.rs:程序的主要逻辑入口; Cargo.toml:Rust 程序的配置文件。)
3.tests/ 保留至少一个文件以便学习如何测试 Solana 程序。
4.package.json 保留node环境,以便于运行测试脚本。
2.可以删除的目录和文件(随着学习的深入,可以进一步添加)
1.app 当需要前端页面交互时,增加这个目录即可。
2.migrations/ 默认生成的 migrations/deploy.ts 是一个模板,这里用于自定义部署流程的脚本,但对初学者来说非必需。
3.programs/<program_name>/Xargo.toml 暂时不需要了解Xargo,直接删除。
3.我们也修改了子程序目录为guide_1
现在你的目录结构看起来应该是这样(除去隐藏和忽略的目录):
到这里,本文就讲完了。如果你想提前看到我的更新,可以关注我的公众号:认知那些事
。
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!