如何开发substrate
使用substrate frame 构建区块链
我们在区块链框架中定义自己的运行时的逻辑,例如区块链中有一个共识组件,我们可以更换其他共识组件,也可以自定义共识组件。substrate 中通过 pallet 来实现功能组件,我们可以使用 substrate 提供的 pallet 也可以自己开发 pallet。
一些基础库基本上都是不会修改的, 只需要在这个基础上添加特定业务的逻辑完成开发。所以我们直接使用 node-template 在上面开发特定的业务逻辑的 pallet就可以了。
node-template 目录结构
通过 github 下载 node-template
.
├── Cargo.lock
├── Cargo.toml
├── docker-compose.yml
├── docs
│ └── rust-setup.md
├── LICENSE
├── node // 区块链底层实现,p2p,rpc 基础功能的实现
│ ├── build.rs
│ ├── Cargo.toml
│ └── src
│ ├── chain_spec.rs
│ ├── cli.rs
│ ├── command.rs
│ ├── lib.rs
│ ├── main.rs
│ ├── rpc.rs
│ └── service.rs
├── pallets // 业务相关模块
│ └── template
│ ├── Cargo.toml
│ ├── README.md
│ └── src
├── README.md
├── runtime // 组合使用 pallets 的地方
│ ├── build.rs
│ ├── Cargo.toml
│ └── src
│ └── lib.rs
├── rustfmt.toml
├── scripts
│ ├── docker_run.sh
│ └── init.sh
└── shell.nix
开发过程中主要操作的就是 pallets 和 reuntime ,node很少会操作。
pallet 结构
打开 src/lib.rs 对照下面的框架了解一下 pallet 的模块代码。
// 1. Imports and Dependenciespub 依赖
use pallet::*;
#[frame_support::pallet]
pub mod pallet {
use frame_support::pallet_prelude::*;
use frame_system::pallet_prelude::*;
// 2. Declaration of the Pallet type 类型声明,类似 java 的类属性
// This is a placeholder to implement traits and methods.
#[pallet::pallet]
#[pallet::generate_store(pub(super) trait Store)]
pub struct Pallet<T>(_);
// 3. Runtime Configuration Trait config trait
// All types and constants go here.
// Use #[pallet::constant] and #[pallet::extra_constants]
// to pass in values to metadata.
#[pallet::config]
pub trait Config: frame_system::Config { ... }
// 4. Runtime Storage 定义链上储存
// Use to declare storage items.
#[pallet::storage]
#[pallet::getter(fn something)]
pub MyStorage<T: Config> = StorageValue<_, u32>;
// 5. Runtime Events 定义通知事件
// Can stringify event types to metadata.
#[pallet::event]
#[pallet::generate_deposit(pub(super) fn deposit_event)]
pub enum Event<T: Config> { ... }
// 6. Hooks 钩子函数
// Define some logic that should be executed
// regularly in some context, for e.g. on_initialize.
#[pallet::hooks]
impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> { ... }
// 7. Extrinsics runtime 可调用的方法
// Functions that are callable from outside the runtime.
#[pallet::call]
impl<T:Config> Pallet<T> { ... }
}
1,2是固定写法
3 config trait 可以理解为构造方法 runtime 可以传递参数进来,
4-7 就是链上相关的方法,属性,生命周期钩子,事件。
总结
知道了 node-template 目录结构和 pallet 的框架之后,我们将在这个基础上创建一个拥有存证功能的公链。