查看原文
其他

Substrate 入门 - 项目结构 (四)

Aten2 PolkaWorld 2020-01-27

本文经作者金晓授权,转载自 https://zhuanlan.zhihu.com/p/98684002。

在开始讲解Substrate的内容之前,还需要补充一个当前Substrate的项目结构。之所以这里强调“当前”是因为Substrate从之前的结构到现在已经发生了巨大的变化,如果不重新再介绍一下,后续的文章介绍起来就会有一些麻烦。

笔者在一年前已经写过一个Substrate的项目结构《Substrate 设计总览 (二)》的介绍,但是截止目前项目的结构几乎已经全部变了。因此重新进行介绍。(在看本文前最好先了解了Substrate的设计总览:《Substrate 设计总览》

本文所基于的Substrate提交为:a98625501be68cc3084e666497c16b111741dded,即2019年12月21日的提交。

本文首发于知乎专栏金狗喵喵喵的区块链研习,版权属于@金晓如需转载,需取得同意并标明出处,并涵盖版权信息!

core->primitives + client

以前的core目录包含了所有的链的功能模块的部分,也就是所谓的Substrate的框架主体内容。在现在的版本中,拆成了primitives + client两个部分。

其中:

  • primitives:元语,赋予了新的含义,用于定义一条链中很多基础设置的模块。实际上这个归类也是比较笼统的,但是主要还是用来定义用的,举例来说:
    • primitives/core中定义了密码学类型如ed25519sr25519等,定了hash,定义了H160H256H512等长度类型,
    • primitives/runtime定义了“Runtime”中需要用到的基础类型,如区块头 Header,区块Block,交易体extrinisic,区块头附带的信息“digest”,“Runtime”编写过程中用到的一些基础工具,如错误处理DispatchError,兼容多种类型签名的MultiSignature,Runtime中的随机数,交易合法验证,offchain的一些类型定义等等
    • primitives/consensusSubstrate提出的新共识的核心aura,"babe",以及“pow”的一些类型定义,注意这里只是一些定义以及对于Runtime的api接口,实现在client/consensus对应的模块下。
    • primitives/apiruntime的api的工具宏定义
    • primitives/trie 对 MPT 的包装,MPT见上文介绍,实现在trie-db这个库中
    • primitives/std 和 primitives/io 原来的sr-std 和sr-io,用于提供Runtime中的对于wasm编写的支持以及runtime访问trie的接口。
    • 等等内容
而对于另一个模块client而言:
  • client是对于很多模块的功能实现以及集成功能模块组件
    • client/api就是对于runtime api 调用包装的实现
    • client/consensus是对共识模块的实现。
    • client/network是对网络p2p的实现,底层使用Libp2p
    • client/state-db是对每个块提交到MPT的过程的管理
    • client/service是对许多功能模块的集成,例如网络模块,交易池,rpc等等,service相当于启动了这些模块并持有这些模块的引用
    • client/cli是对命令行的解析并根据相应的参数配置service
    • 等等... 由于本系列主要是为了介绍使用substrate,而不是讲解substrate怎么实现,所有就不必说的很细致了。
所以在今后的文章中介绍primitives/client 即代表着这些是Substrate框架内的代码,若要修改,需要进行fork
ps:(这是不严谨的说法,实际上也可以引用primitives,自己实现client,只所以这么说是因为client可以看做Substrate定义的基础结构的一种实现,当然可以独立进行另一种client的实现。但由于当前的client里面是一种实现,因此里面的模块都是互相关联的,很难只修改其中某个组件,如果需要沿用Substrate的实现但是需要修改其中的某些实现,那么只能fork修改了。)

srml -> frame

参见笔者之前的《Substrate 设计总览》与《Substrate 设计总览 (二)》,应该知道了Runtime的概念,与Substrate中实现Runtime的模块srml(Substrate Runtime Module Library)。在新版中,srml命名为了frame
对于frame而言,模块之间没有很大的迁移,基本沿袭了原来的命名与结构,只不过新增了很多的runtime module 模块。
如理解了这两篇文章的内容,那么应该可以理解frame中除了“system”之外,都是可以由开发者自由实现的,实际上使用Substrate链编写的应用链的核心部分就是开发自己的Runtime Module。编写自己的Runtime Module不会写的时候,就需要去模仿frame模块中这些模块的编写技巧。其中提供了很多最佳实现这类的东西。

node + node-template + subkey + 其他 -> bin

对于上文的 primitiveclient或者再加上frame中的system共同构成了Substrate的框架,而对于新版本中的bin则是对Substrate框架的使用案例(一种实现),因此bin中的内容就是Substrate的框架外的部分。
在新版本中把原来的node,node-template等全部移动到了bin中,代表这些模块是可以进行“可执行文件”的入口。因此调试也好,研究数据流流转也好,都是从这个入口开始。
所以在今后的文章中,介绍bin中的代码,即代表着这是使用者可以自由进行定制的部分,可参考bin中的一些组件进行修改。而bin中的案例即是如何把runtime和service组合在一起的案例。
对于本系列而言,只用参考node的实现就够了,因为它的实现是最全面的。

更多该系列内容:


Substrate 入门 - 具备状态的链(三)

Substrate 入门 - 运行与调试 (二)

Substrate 入门 - 环境配置与编译(一)

Substrate 设计总览(三)

Substrate 设计总览(二)

Substrate 设计总览 (一)


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

关注 PolkaWorld

发现 Web 3.0 时代新机遇


点个 “在看” 再走吧!


    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存