Substrate Developer Hub

Substrate Developer Hub

  • 教程
  • 知识库
  • 进阶菜谱
  • API 文档
  • Languages icon简体中文
    • English
    • 协助翻译

›整合

开始

  • 总览
  • 安装
  • 在 Windows 系统开始
  • 词汇表

学习 Substrate

  • Extrinsics
  • 交易池
  • 账户摘要
  • 会话密钥
  • 交易权重
  • 链下功能

Runtime

  • Runtime 总览
  • Runtime 的基本类型
  • FRAME
  • Pallets
  • Runtime宏
  • Runtime 元数据
  • Runtime 存储
  • Runtime 来源
  • Runtime 执行流程
  • Runtime事件
  • Runtime 错误
  • 交易费用
  • 链下工作机
  • 调试
  • Runtime 测试
  • 链上随机生成
  • Runtime 升级

智能合约

  • 总览
  • ink! 智能合约
  • ink! 概念
  • ink! 开发
  • EVM 模块
  • ink! 常问问题

整合

  • Polkadot-JS
  • 客户端库
  • 链规范
  • Subkey 工具
  • 内存分析

进阶

  • SCALE 编解码器
  • 共识机制
  • 区块导入过程
  • 执行器
  • 密码学
  • 存储
  • SS58 地址格式

贡献

  • 协助翻译
Translate

链规范

链规范 (Chain Spec) 是一个配置信息的集合,它决定了一个区块链节点连接到的网络,最初将与哪几估节点交流,以及它在创世时必须具备什么样的重要共识状态。

Chain Spec 的结构

The <a href="https://substrate.dev/rustdocs/v3.0.0/sc_service/struct.General ChainSpec.html>ChainSpec 结构体 把在链规范里的信息分为两部份。 节点可以使用 ChainSpec 来生成创世区块。

客户端规范 (Client Spec)

链规范的第一部分是 ClientSpec。 ClientSpec 包含了 Substrate 客户端所使用的信息,是节点内 runtime 以外的一部分。 这信息用于在网络中与其他远端沟通,例如启动节点 (bootnodes),该节点会传送数据的遥测端点 (telemetry endpoints),以及会连接到的供人和机器阅读的网络名称。 里面许多选项其实是可被命令行标志覆盖,而区块链启动后它们的值也可有所更改。

注意:本部分中的所有属性都可在创世后更改,节点只能添加使用相同 protocolId 的同伴节点。

延伸

因为 Substrate 框架极具扩展性,它提供了方法去调整客户端规范来增加数据去调整客户端的不同部份。 其中一个用例是告诉节点在特定高度的特定区块内容,来防止新节点起来时在区块同步上受到远程攻击。

创世状态

链规范的第二部分是重要的共识创世设置。 网络中的所有节点必须先商定这个初始状态,然后才能商定其后的所有区块。 因此,该信息必须在链一开始时就建立,此后在不启动新的区块链的前题下,是无法更改的。 这里没有命令行标志可覆盖链规范里这创世状态的值。

包含在这部份链规范的信息有比如,初始的帐户余额,最初在治理理事会当中的账户,或 sudo 钥匙的持有人。 Substrate 节点也将会编译后的 Wasm runtime 逻辑放到链上,因此链规范必须提供初始时的 runtime。

就是链规范的这第二部份在创建创世区块时会被使用到。

存储链规范信息

包含在链规范的信息可用以下两种方式储存起来。 第一种方法是以 Rust 代码形式,作为 Rust 的结构体,来存储此信息。 事实上,Substrate 节点一般至少包含一个,且往往是多个,的链规范是写死在客户端里。 在客户端直接包含这些信息可确保节点,在不需要运维工程师提供任何额外信息下,就知道如何连接到至少一条链。 在有 "主网" 概念的协议中,这规范一般是写死在客户端的。

另一种常见存储链规范的方式是透过 JSON 格式。 链规范结构有个方法可将其数据序列化为 JSON,和从 JSON 反序列化为链规范对象。 当启动测试网或私有链时,常见的做法是分发节点的执行档连同 JSON 编码的链规范。

使用 Chain Specs

运维人员和 runtime 开发者在执行很多共同任务时都会使用上链规范。

启动一条链

每次运维人员启动节点时,他们需要提供该节点的链规范。 最起码,节点在使用写死到节点二源档的默认链规范。

一个常见的任务是启动一个测试网或私人网络,跟现在已有网络协议类似,但却不连接到主网上的。 要实现这一点,运维人员可通过命令行标志如 --chain local 来选择另一个与 "local" 相关联的另一个替代性链规范。 第三个选项是运维人员提供链规范的 JSON 文件,然后用命令行标志 --chain=some CustomSpec.son 来使用它。节点会尝试反序列化并使用 JSON 里提供的链规范。

Runtime 开发

几乎每一个 Substrate runtime 都有着在创世时需配置的存储项目。 当开发 FRAME 时,任何使用 config() 来声明的存储项都需要在创世时进行配置。 这是链规范,尤其是创世状态那部份,的职责来配置存储项里的值。

自定义链规范

当在创建个一次性网络作开发,测试,或展示之用,可能使用自定义链规范会更合适。 运维人员可为协议导出默认链规范到 JSON 格式然后修改。 Substrate 节点配备了 build-spec 子命令来导出链规范。

substrate build-spec > myCustomSpec.json

链规范导出后,运维人员可自由修改其任何字段。 一些正常操作是修改网络性名,启动节点,和存储项的创世状态如帐户余额。 编辑完成后,运维人员可通过提供这 JSON 文件来启动他们的自定义链。

substrate --chain=myCustomSpec.json

原始链规范

Substrate 节点支持 runtime 升级,这意味着区块链当前的 runtime 可能与它初始时是不一样的。 迄今为止所讨论的链规范,都包含着 runtime 所能理解的信息。 例如,看以下 Substrate 节点中截取的默认链规范 JSON。

"sudo": {
  "key": "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY"
}

在这个链规范可用来定义创世存储项前,一个供人阅读的钥匙要先被转换成 存储树 里的实际存储键。 这转换很直接,但它需要节点 runtime 能理解这链规范。

如果一个已升级的节点 runtime 试图从创世开始来同步一条链,那它会不能理解这链规范里的信息。 因此链规范有着第二种编码方式,称为 "原始" 链规范。

当以 JSON 格式发布链规范时,它们应以这种原始格式来发布,来确保所有节点,就算升级过后仍然能够同步链数据。 Substrate 节点支持 --raw 标志来生成这样一种链规范。

substrate build-spec --chain=myCustomSpec.json --raw > customSpecRaw.json

经过转换后,上面的代码段会像以下:

"0x50a63a871aced22e88ee6466fe5aa5d9": "0xd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d",

后续步骤

进一步学习

  • Rustdocs for the ChainSpec 结构体 的 API 文档
  • Rustdocs for the ProtocolId 结构体 的 API 文档

例子

  • 跟着 启动一个私人网络 教程来获取亲手使用链规范的经验。
  • 以 Rust 代码储存的 Node Template 链规范。
← 客户端库Subkey 工具 →
  • Chain Spec 的结构
    • 客户端规范 (Client Spec)
    • 创世状态
  • 存储链规范信息
  • 使用 Chain Specs
    • 启动一条链
    • Runtime 开发
    • 自定义链规范
  • 原始链规范
  • 后续步骤
    • 进一步学习
    • 例子
Substrate Developer Hub
开发者中心
教程知识库进阶菜谱API 文档
社区
社区主页通讯Substrate 技术聊天室Substrate 研讨会Stack Overflow推特聚会活动
更多
Substrate Builders 计划BlogSubstrate GitHub开发者中心 GitHub隐私政策使用条款Cookie 设置
Copyright © 2021 Parity Technologies