Solana/程序开发入门/搭建初始目录结构

这篇文章, 我们来搭建一个干净的纯 rust 的 solana 程序项目目录结构, 作为我们的链上数据存储器项目的初始目录结构.

新建空白项目

我们先创建一个普通的 rust 库项目:

$ cargo new --lib pxsol-ss
$ cd pxsol-ss

这个项目会包含我们的主程序逻辑, 也就是将要部署到链上的合约. 项目名称 pxsol-sspxsol-simple-storage 的缩写.

配置编译目标

编辑 Cargo.toml, 添加如下设置:

[lib]
crate-type = ["cdylib", "lib"]

这个是告诉 cargo 我们要生成哪几种类型的 crate.

其中 cdylib 表示编译为一个 c 兼容的动态库. Solana 要求合约以 cdylib 形式编译为 .so 文件, 才能部署到链上. 这个 .so 文件会通过 cargo build-sbf 生成.

另外 lib 表示我们还希望编译成普通的 rust 库, 即 .rlib. 这有助于在本地测试时, 把合约逻辑当作普通 rust 模块来调用, 也方便写单元测试或集成测试.

总结的说: 您需要 cdylib 来部署, lib 来开发和测试.

添加依赖

我们需要引入 solana 的核心 sdk:

[dependencies]
solana-program = "2"

项目目录结构参考

最终的目录结构看起来可能像这样:

pxsol-ss/
├── Cargo.toml
└── src/
    └── lib.rs

其中 Cargo.toml 中的内容为

[package]
name = "pxsol-ss"
version = "0.1.0"
edition = "2021"

[lib]
crate-type = ["cdylib", "lib"]

[dependencies]
solana-program = "2"

创建 lib.rs 骨架

src/lib.rs 中, 先写一个最简单的入口:

solana_program::entrypoint!(process_instruction);

pub fn process_instruction(
    program_id: &solana_program::pubkey::Pubkey,
    accounts: &[solana_program::account_info::AccountInfo],
    data: &[u8],
) -> solana_program::entrypoint::ProgramResult {
    solana_program::msg!("Hello Solana!");
    Ok(())
}

这个程序目前什么也不做, 只会在调用时打印一句话. 但它已经可以被编译成 solana 支持的 bpf 程序了.

尝试编译

运行下面命令, 进行交叉编译:

$ cargo build-sbf -- -Znext-lockfile-bump

如果一切正常, 你会在 target/deploy/ 目录下看到 pxsol_ss.so 文件, 这就是可以部署到 solana 的程序文件.

注意参数 -Znext-lockfile-bump 是一个临时参数, 因为旧的 solana_program 依赖于旧的 rustc, 如果您本地的 rust 版本大于它所期望的, 存在一些兼容性问题, 因此需要传入该参数. 当您阅读本书时, 随着版本的更新, 此兼容问题很可能已经修复, 因此您也许可以尝试看看不加入该临时参数. 关于该问题的详细解释, 可以参考该 github 页面.

小结

到这里, 我们已经完成了一个最基本的, 使用原生 rust 编写的 solana 程序框架搭建. 这是实现我们用户自托管链上数据存储器的第一步.

下一步我们将实现账户派生和数据存储的逻辑, 开始真正和 solana 的账户模型打交道.