在本教程中, 你将编写一个存在于其自身 crate (包装箱)里的 Substrate 模块,并将其包含在基于 substrate-node-template
的节点中。
当你学习完教程:创建你的第一条 Substrate 链 [1] 之后,你应该已经在计算机上编译了 Substrate Node Template[2] 的 v2.0.0-alpha.8
版本,如果没有的话 , 请先学习完教程。
“
如果你是有经验的开发人员,倾向于选择跳过该教程,建议你可以根据自述文件中的说明安装节点模板。
我们不会将 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 的同级。
让我们从 Cargo.toml
文件开始探索 Substrate Pallet template。
在 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'
“
如果你已按照本教程的步骤进行操作 ,并将模板模块克隆到节点模板的
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 模块都是依赖于一些较低级别的 FRAME 库,例如 frame-system
和 frame-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 存储库 [7] 并发布模块代码 [8] 。
Crates.io 允许未经许可的发布。可以按照他们发布指南学习如何在 Crate.io 上发布 [9]。
现在 Pallet 已经发布在 GitHub 或 crates.io,或者两个地方都发了,我们可以更新 runtime 以使用发布的代码,而不是硬编码的文件系统路径。
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 = '
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。
[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 社区
https://github.com/paritytech/substrate
https://github.com/paritytech/polkadot
https://bootcamp.web3.foundation/
更多内容:
在 Substrate 中为你的 runtime 添加合约模块
扫码关注公众号,回复 “1” 加入波卡群
关注 PolkaWorld
发现 Web 3.0 时代新机遇
点个 “在看” 再走吧!
声明:本内容为作者独立观点,不代表 CoinVoice 立场,且不构成投资建议,请谨慎对待,如需报道或加入交流群,请联系微信:VOICE-V。
简介:波卡(Polkadot)第一中文社区,带你寻找 Web 3.0 时代新机遇!
评论0条