教程|编写一个 Substrate 模块

自己创建一个 Pallet

在本教程中, 你将编写一个存在于其自身 crate (包装箱)里的 Substrate 模块,并将其包含在基于 substrate-node-template 的节点中。

安装 Node Template

当你学习完教程:创建你的第一条 Substrate 链 [1] 之后,你应该已经在计算机上编译了 Substrate Node Template[2] 的 v2.0.0-alpha.8 版本,如果没有的话 , 请先学习完教程。

如果你是有经验的开发人员,倾向于选择跳过该教程,建议你可以根据自述文件中的说明安装节点模板。

克隆 Pallet 模板

我们不会将 Pallet (模块)直接写为节点模板的一部分,而是写成一个单独的 Rust crate。这种形式让我们可以和节点分开发布 Pallet,也可以让其他人轻松的将该 Pallet 导入自己的 Substrate Runtime。

在你的节点模板的 pallets 目录中克隆 Substrate pallet template:

cd pallets       git clone -b v2.0.0-alpha.8 https://github.com/substrate-developer-hub/substrate-pallet-template test-pallet

在本教程中,我们将 pallet template (模块模板) 放在 node template (节点模板) 的目录结构中。这种形式不是必须的,你可以将 pallet template 放置在任意位置。另一种流行的做法是将其作为 node template 的同级。

Substrate Pallet 模板

让我们从 Cargo.toml 文件开始探索 Substrate Pallet template。

重命名 crate

Cargo.toml 文件中 , 你可以更新 crate 的名称和作者身份。在本教程中,我们集中讲如何创建和使用 pallet (模块),而不是编写 pallet (模块)逻辑。我们称之为 test-pallet

Cargo.toml 的开头是这样展示的 :

pallets/test-pallet/Cargo.toml

[package]        authors = ['Substrate DevHub ']       description = 'Substrate FRAME pallet template'       edition = '2018'       homepage = 'https://substrate.io'       license = 'Unlicense'       name = 'test-pallet'       repository = 'https://github.com/paritytech/substrate/'       version = '2.0.0-alpha.8'

编译 Template Pallet

如果你已按照本教程的步骤进行操作 ,并将模板模块克隆到节点模板的 pallets 目录中,则需要将模板模块添加到 Cargo.toml 文件的 workspace.members 数组中。在节点模板目录的根目录中;你将需要包括路径和包的名称,所以需要将此元素添加到 members 数组中 : 'pallets/test-pallet',

你应该能够使用以下命令成功编译 Substrate pallet template :

cd test-pallet       cargo build --release

模块的 std 功能

在这个 pallets/test-pallet/Cargo.toml 文件中,你会注意到关于 "std 功能 " 的几行内容,在 Rust 中, 当你启用 “std 功能” 时,就可以让你的项目访问 Rust 标准库 [3]。这在构建本机二进制时非常好用。

但是, Substrate 也将 runtime 代码构建到 WebAssembly (Wasm)。在这种情况下, 我们使用 cargo 功能禁用 Rust 标准库。因此,我们用于 Pallet (模块)及整个 runtime 时的所有依赖项都必须能够使用 no_std[4] 功能。Cargo.toml 文件会告诉模块的依赖项,仅在该模块还使用 std 功能时才使用其 std 功能, 如下所示:

pallets/test-pallet/Cargo.toml

[features]        default = ['std']       std = [           'codec/std',           'frame-support/std',           'frame-system/std',       ]

Substrate 的依赖性需保持一致

所有的 Substrate 模块都是依赖于一些较低级别的 FRAME 库,例如 frame-systemframe-support。这些库是从 crates.io 中提取的。当人们构建自己的基于 FRAME 的 runtime 时 , 他们还将依赖于这些低级库 . 并且你需要确保 pallet 和 runtime 之间保持一致性依赖关系。

pallets/test-pallet/Cargo.toml

# --snip--         [dependencies.frame-support]       git = 'https://github.com/paritytech/substrate.git'       default-features = false       tag = 'v2.0.0-alpha.8'

从上面的代码片段中,我们看到该 pallet template 取决于低级库的版本 2.0.0-alpha.8 。因此它可以在同样依赖于 2.0.0-alpha.8 的 runtime 中使用。

模块的开发依赖

Cargo.toml 文件的最后一部分指定了开发依赖项。这些依赖项是在模块的测试中需要用到的,而不是实际模块本身需要。

pallets/test-pallet/Cargo.toml

# --snip--         [dev-dependencies.sp-core]       git = 'https://github.com/paritytech/substrate.git'       default-features = false       tag = 'v2.0.0-alpha.8'

你可以通过以下命令来确认 Substrate pallet template 中的测试通过了 :

cargo test

当更新模块来包含你自定义的逻辑时 , 你可能需要向 Cargo.toml 文件添加自己的依赖项。

将模块添加到节点

当我们的模块以及编译并通过了测试,可以开始准备将其添加到我们的节点中。

如果你对包含和使用其他 crate 还不熟悉 , 请参阅 the Cargo book[5] 以了解更多信息。

我们首先在节点的 runtime Cargo.toml 中将新创建的 crate 添加为依赖项,然后告诉模块仅在 runtime 本身构建时,才构建其 std 功能,如下所示:

runtime/Cargo.toml

# --snip--         [dependencies.test-pallet]       default-features = false       path = '../pallets/test-pallet'        # toward the bottom       [features]       default = ['std']       std = [           'test-pallet/std',           # --snip--       ]

你必须设置为 default_features = false 这样你的 runtime 才能成功编译为 Wasm。

接下来,我们通过将 test_pallet 添加到 construct_runtime! 宏中,来更新 runtime/hide/lib.rs ,以实际使用我们新的 runtime pallet。

runtime/hide/lib.rs

// add the following code block       impl test_pallet::Trait for Runtime {         type Event = Event;       }        // --snip--       construct_runtime!(         pub enum Runtime where           Block = Block,           NodeBlock = opaque::Block,           UncheckedExtrinsic = UncheckedExtrinsic         {           // --snip--           // add the following line           TestPallet: test_pallet::{Module, Call, Storage, Event},         }       );

运行节点

至此,你已经将模块打包在自己的模块包中,并包含在节点的 runtime 中。

确保你返回了节点模板的根目录,然后使用以下命令编译并运行节点:

cargo build --release

清除所有现有的开发链 (在提示时输入 y ):

./target/release/node-template purge-chain --dev

启动节点:

./target/release/node-template --dev

最后,启动 Polkadot-JS Apps connecting to your local node[6] 确保模块按预期工作。

注意 :你还可以通过以下方式在 Polkadot-JS Apps 中手动设置节点 URL: 导航到设置标签, 并将要连接的远程节点 / 端点设置为本地节点

发布模块

一旦你的模块不再处于测试阶段,你应该考虑将其发布到 GitHub 或者 crates.io。

在 GitHub 上发布

要在 GitHub 上发布 , 你需要创建 GitHub 存储库 [7] 并发布模块代码 [8] 。

在 Crates.io 上发布

Crates.io 允许未经许可的发布。可以按照他们发布指南学习如何在 Crate.io 上发布 [9]。

更新 Runtime 依赖项

现在 Pallet 已经发布在 GitHub 或 crates.io,或者两个地方都发了,我们可以更新 runtime 以使用发布的代码,而不是硬编码的文件系统路径。

GitHub 的依赖项

runtime/Cargo.toml

[dependencies.your-pallet-name]        default_features = false       git = 'https://github.com/your-username/your-pallet'       branch = 'master'        # You may choose a specific commit or tag instead of branch       # rev = ''       # tag = '

Crates.io 的依赖项

runtime/Cargo.toml

[dependencies.your-pallet-name]        default_features = false       version = 'some-compatible-version'

完善构建

再次编译,并且注意 Cargo 现在从 GitHub 或 crates.io 抓取你的 Pallet 而不是使用本地文件。

下一步

恭喜 ! 你已经成功编写并发布了一个 Substrate 模块在自己的 Rust 包中。其他的区块链开发者只需要在 Cargo.toml 文件中简单的使用 4 行代码并更新其 runtime 的 lib.rs 文件,就可以在他们的 runtime 中轻松使用你的 pallet。

了解更多

  • 我们还有 很多教程 [10] 关于 Substrate 开发的概念和技术。
  • 更多信息关于 runtime 开发技巧和模式,请参阅 Substrate Recipes[11].

参考资料

  • The Cargo book[12]
  • 更多关于 Rust and WebAssembly[13] 的信息

参考链接

[1]

创建你的第一条 Substrate 链 :https://www.substrate.io/tutorials/pallet-in-own-crate/tutorials/create-your-first-substrate-chain/v2.0.0-alpha.8

[2]

Substrate Node Template:https://github.com/substrate-developer-hub/substrate-node-template

[3]

Rust 标准库 :https://doc.rust-lang.org/std/

[4]

no_std:https://rust-embedded.github.io/book/intro/no-std.html

[5]

the Cargo book:https://doc.rust-lang.org/cargo/guide/creating-a-new-project.html

[6]

Polkadot-JS Apps connecting to your local node:https://polkadot.js.org/apps/#/explorer?rpc=ws://127.0.0.1:9944

[7]

创建 GitHub 存储库 :https://help.github.com/en/articles/create-a-repo

[8]

发布模块代码 :https://help.github.com/en/articles/pushing-to-a-remote

[9]

如何在 Crate.io 上发布 :https://doc.rust-lang.org/cargo/reference/publishing.html

[10]

很多教程 :https://www.substrate.io/tutorials

[11]

Substrate Recipes:https://substrate.dev/recipes/

[12]

The Cargo book:https://doc.rust-lang.org/stable/cargo/

[13]

Rust and WebAssembly:https://rustwasm.github.io/

原文:https://www.substrate.io/tutorials/pallet-in-own-crate/v2.0.0-alpha.8

翻译:PolkaWorld 社区

  • 欢迎学习 Substrate:

https://substrate.dev/

  • 关注 Substrate 进展 :

https://github.com/paritytech/substrate

  • 关注 Polkadot 进展 :

https://github.com/paritytech/polkadot

  • 申请 Bootcamp:

https://bootcamp.web3.foundation/

教程|编写一个 Substrate 模块

更多内容:

Substrate:过去,现在和未来

在 Substrate 中为你的 runtime 添加合约模块

教程|创建你的第一条 Substrate 区块链

扫码关注公众号,回复 “1” 加入波卡群

教程|编写一个 Substrate 模块

关注 PolkaWorld

发现 Web 3.0 时代新机遇

点个 “在看” 再走吧!

来源链接:mp.weixin.qq.com