作者:PaperMoon Zhou Jun |Polkadot dev advocate
构建区块链项目如同搭建一座复杂的积木城堡,而 Substrate 框架中的 Pallet 模块正是这些积木的核心部分。每个 Pallet 都具备特定功能,类似于积木中的门、窗、墙壁等元素,可以通过合理组合来构建理想的区块链网络。然而,面对种类繁多的 Pallet 模块,许多开发者可能会感到迷茫,不确定如何选择和应用这些模块来实现特定功能。为此,详细的开发指南应运而生,它将引导开发者在庞大的代码库中找到合适的 Pallet,并教授如何灵活地将它们集成到项目中,助力开发者轻松搭建专属的区块链 “城堡”。
下面一起深入了解周俊老师带来的第三篇「 Substrate 技术解读」,帮助开发者更好地理解 Pallet 概念,并通过实用示例掌握开发技巧,加速区块链项目的落地。
Substrate 技术详解——Pallet 开发指南
在每期的 Substrate 课程中,学员们常常提到 Polkadot SDK 中代码繁杂、Pallet 众多,难以逐一阅读和理解。那么,开发者在创建 Substrate Pallet 时,应该如何找到具体的示例和技巧呢?幸运的是,Polkadot SDK 的代码库中提供了一个名为 “Examples” 的目录,这里汇集了大量有用的示例和技巧,能够帮助开发者更高效地掌握 Pallet 的使用方法。
1.default-config
default-config 示例展示了如何使用 pallet::DefaultConfig 和 pallet::config_preludes::TestDefaultConfig 来简化 Pallet 的配置。每个 Pallet 通常需要定义多个类型,如果都自己定义需要很多的时间,从其他地方拷贝有时候会有冲突,编译不能通过。而使用默认配置可以将这些类型绑定到预设的默认值,只要一个宏就能完成很多类型的绑定。
示例:
在定义 Pallet 的时候
在定义测试时候的使用
应用场景:
在编写 Pallet 和单元测试时,使用默认的类型宏来绑定到默认的类型上,可以节省大量时间。当然,如果默认的值不符合要求的时候,重新定义就好,自定义的类型会去覆盖默认的类型。
2.dev-mod
dev-mod 宏允许开发者在开发过程中跳过一些严格的检查,例如对 Vec 长度的限制。这使得开发者能够快速验证想法,而不必在初期阶段就考虑所有的边界条件。
在开发阶段,快速迭代和验证想法是至关重要的。使用 dev-mod 宏可以让开发者在初期阶段专注于功能实现,而不必担心代码的完整性和安全性。
示例:
Rust
在 dev-mod 下,可以定义没有 call index,没有 weights 的交易。
没有长度检查的 Vec
使用默认的 Hash 方法来定义 Map 类型
应用场景
在原型设计阶段,开发者可以使用 dev-mod 快速构建和测试新功能,待功能验证后再去掉该宏,确保代码的生产安全性。
3.kitchensink
kitchensink Pallet 是一个全面的示例,展示了 Pallet 开发中的多种类型定义和使用,包括常量、存储类型、Genesis 数据、事件、错误定义、Hook 函数、测试和基准等。
这个 Pallet 提供了一个几乎涵盖所有 Pallet 开发基本元素的参考。开发者可以在此找到如何定义和使用不同类型的详细示例。
示例
Rust
Balances 或者 Currency 的使用
增加在 Metadata 中的常量的定义
Pallet storage版本的定义
Map 的 Key 可以是 Tuple
定义不需要支付交易费用的场景
Inherent 的定义
应用场景:
对于新手开发者,kitchensink 提供了一个对应 Pallet 全面的参考,里面几乎涵盖了所有 Pallet 里面的元素。很多的实现是空的,但是给出来输入输出的类型定义。这个为开发者提供了很大的帮助。
4.multi-block-migrations
multi-block-migrations Pallet 展示了如何在多个区块中完成数据迁移,特别是在需要迁移的数据量很大的情况下。强行在一个区块中完成所有操作可能会导致超时和出块失败。使用 SteppedMigration 可以将迁移操作分成多个步骤,逐步完成。
示例
rust
应用场景
在大型项目中,数据迁移是常见的需求,使用 multi-block-migrations 可以确保迁移过程的稳定性和安全性。在实现的时候要注意 WeightMeter 在 migration 过程中的使用,当它不足的时候就会停下来。
5.offchain worker
offchain worker 是实现链下交互的重要功能,允许 Pallet 与外部系统进行交互,例如 Oracle 服务。通过 Offchain Worker,开发者可以在链下执行任务,获取外部数据,并将结果提交到链上。这对于需要实时数据的应用场景尤其重要。
示例
Rust
Offchain worker hook 的定义
在构建去中心 在向链上提交交易的时候,需要用到签名,key 的类型。需要定义一个 crypto 的 mod,最主要的实现在 app_crypto 这个宏里面,它接受签名算法和 KEY_TYPE 二个参数。签名算法可以是 sr25519、ed25519 或者是 ecdsa,KEY_TYPE 可以从一个二进制的字符串导出。
Offchain worker 向链上提交签名的交易,这里需要用到 frame_system::offchain::Singer
也可以提交没有签名的交易,使用 frame_system::offchain::SubmitTransaction
应用场景
在构建去中心化金融(DeFi)应用时,Offchain Worker 可以用来获取市场价格数据并进行实时交易。对应复杂的计算,也可以使用它在链下完成,然后通过签名的,或者不签名的交易来提交结果。并且计算的时间可以是多个区块。在使用的时候,需要注意的一点是,每个结果都是从单个节点来的,不同节点的提交会有所不同,因此往往需要简单的共识机制。比如在这个例子中,就使用了平均价格来作为最终的参考。
6.pallet_section
在没有这个宏之前,可以看到对于比较复杂的 Pallet,需要把大量的代码都放在 lib.rs 文件中。这些代码内容只有包含在 mod pallet 才能够正确的展开和编译。pallet_section 允许开发者将事件、错误、交易等定义在单独的文件中,然后在 mod pallet,使用 import_section 将这些代码引入到 pallet 里面来。这二个宏配合使用,其实就是起到了简单的把代码拷贝过去的作用。
这个技巧对于代码量较大的 Pallet 非常有用,每个功能放到不同的文件,可以增加代码的可读性,编码的时候容易找到对应的位置。
通过将事件和错误分离到不同的文件中,可以提高代码的可读性和可维护性,使得开发者更容易管理和理解代码结构。
示例
rust
// events.rs
// errors.rs
应用场景
代码非常复杂,代码量大的 Pallet.
7.tasks
tasks Pallet 用于管理一系列任务,这些任务可以根据链上数据的状态来触发,并可以与 Offchain Worker 结合使用。
示例
Rust
通过 task_list 来遍历所有的 task,task 触发的条件定义在 task_condition 的方法中。
应用场景
在需要根据链上状态自动执行某些操作的场景中,任务管理可以大大简化开发过程。需要注意的是目前这些宏还在实验的阶段,如果中使用中碰到任何 bug 都 Parity 开发团队提交 PR。
以上扩展内容详细解答了 Pallet 开发过程中常见的难点问题。在 Substrate 开发中,参考这些示例和技巧可以显著提升开发效率,无论是使用默认配置进行快速验证,还是处理复杂任务和数据迁移。通过「Substrate 技术解读」,开发者可以深入了解 Pallet 及 Coretime 机制的应用,为构建和维护 Pallet 提供了宝贵的指导。希望这些扩展内容能帮助大家更深入地理解和应用 Substrate 开发的核心元素。
对 Substrate 最新技术动态感兴趣的小伙伴欢迎回顾「Substrate 技术解读」系列文章的前两篇👇
✦ 由周俊老师撰写的第一篇文章:
「Pallet 最新上线!Substrate 开发进阶课程第八期火热报名中!」
✦ 由孙凯超老师撰写的第二篇文章:
「解密 Coretime:Polkadot 区块链资源分配的新革命」
第八期 Substrate 课程《开发进阶与项目实战》火热进行中!
掌握 Substrate 不仅赋予快速构建和部署区块链应用的能力,还将开发者带入区块链技术的前沿,增强在行业中的话语权。为此,OneBlock+ 与 Polkadot 联合推出第八期《Substrate 开发进阶与项目实战》课程,特别邀请了区块链领域的资深专家王大锤、周俊和孙凯超联合授课。课程将深入探讨 Substrate 的核心技术,传授前沿开发技巧,并通过实践培养出色的能力。无论是寻求在区块链领域突破,还是渴望在这一新兴行业中脱颖而出,这门课程都将成为迈向成功的重要一步。
🪅 如果准备好加入第八期进阶课程学习,点击链接即可加入:
https://wj.qq.com/s2/14825200/0zv4/