如果你关注过 polkadot 的发展,你可能会多次看到 “substrate”。它是 polkadot 项目的重要组成部分,但有关该领域的信息很少。它不在白皮书或黄皮书中,或者至少不在 “substrate” 的名称下,并且其规范仍然很不稳定。概括来看,它是一个使用最新的区块链技术研究,来创建加密货币和其他去中心化系统的框架。但这个定义不是很有帮助,至少对我不是很有帮助。区块链法律法规
我认为了解 parity substrate 最重要的部分是它根本不是 polkadot 的一部分。尽管 polkadot 是使用 substrate 构建的,并且使用 substrate 构建的项目可以在 polkadot 上本地运行,但是你现在可以使用 substrate 构建新的区块链。你无需等待 polkadot 完成,甚至无需发布概念证明即可开始使用此框架在区块链上工作。
那么什么是 substrate ?你可以把它看作 express 或其他 web 应用程序框架,但用于构建分布式或去中心化系统,例如加密货币或消息总线。正如大多数 web 应用程序不需要重新实现自己的 http 版本一样,我们认为每个团队创建一个新的区块链,都必须从头开始实施所有网络和共识代码,这是浪费了精力。更不用说密码学家、安全研究人员、网络工程师、devops 人员(以协调更新)等,当你的业务逻辑真正是你的产品时,就需要雇用这些人员并为其付费。如果你想使用 substrate 建立一个新项目,你要做的就是在代码中实现少量的钩子,然后免费获得:
· 共识、确定性和区块投票逻辑。即使你不是在构建加密货币,甚至不是需要区块链的项目,这也是可取的 —— 这意味着你可以免费获得拜占庭容错能力,因此即使其中的某些节点被损坏、禁用或是恶意的,你的系统仍将继续正常运行;
· 网络,如对等发现(peer discovery)、复制(replication)等;
· 一个高效的、确定的、沙盒化的 webassembly runtime,可用于运行智能合约,甚至运行其他基于 substrate 的项目。你不必一定要使用 webassembly,你当然可以编写自己的虚拟机解释器,但是我们坚信使用 webassembly 运行时的好处,因此你可以充分利用我们在 webassembly 和全球社区中的工作其他开发人员为此创建工具的情况;
· 能够在浏览器中无缝运行可与任何桌面或云节点通信的节点;
· 跨平台的数据库文件存储抽象,甚至可以在浏览器中使用;
· 无缝的客户端更新 —— 任何可能影响共识的更新,都可以通过将代码编译到 webassembly,并将其作为网络上的另一条消息进行部署来处理。不仅如此,你还可以存储 n 个版本你要编译成本机代码的共识代码,并且 substrate 将处理确保执行的本机代码与当前部署的 webassembly 代码对齐的复杂工作。你可以获得本机代码的速度,而由于始终有 webassembly 垫后,你可以按照自己的进度部署本机代码版本,而且你知道自己永远不会意外地遇到硬分叉或其他共识问题,你是安全的。
· 能够在项目发布后立即开始在 polkadot 上运行你的项目。尽管可以将使用 substrate 构建的项目编译为每个项目使用单独的客户端(就像现有的区块链一样),但是由于 polkadot 实现了 substrate api,你可以利用 polkadot 提供的共享安全性和互操作性。polkadot 本身是使用 substrate 构建的,这让我们可以快速获取框架中任何漏洞的反馈,并允许我们运行 polkadot 测试网,甚至可以将 polkadot 本身的第二个实例作为平行链运行。如果你不了解 polkadot,或还不够了解它的好处的话,可以在 polkadot 博客上查看此帖子:mediumcompolkadot-networkhow-polkadot-tackles-the-biggest-problems-facing-blockchain-innovators-1affc1309b0f。
那么哪些东西不是你免费获得的呢?本质上,只有你的状态机,其中包括交易(transactions)之类的东西。为了使 substrate 尽可能通用,它没有交易。相反,它具有我们所谓的 “extrinsics”,它们只是二进制的 blob,可用于存储所需的任何数据。对于大多数链来说,这些外部要素将包括交易,但是你当然不需要那样做!你可以从网络中完全删除货币的概念,并使用 substrate 创建具有一组可信任权限的去中心化 erlang 风格参与者模型并发系统,以验证网络的正确行为。假设你确实想要货币和交易,那么实现交易格式可能很简单 —— 只是一种交换格式和一个库,可以从你选择的语言访问该数据。它比微服务之类的其他分布式体系结构甚至更容易 —— 由于代码及其所操作的数据存储在同一位置,因此你无需为交易[1]强制执行向后兼容保证,而只需为存储而执行。对于具有私人交易的链,实现可能会更复杂。所有内容的名称尚未最终确定,因此你会在不同的地方看到使用不同的语言,但这是你为了实现完整的区块链需要实现的东西的简单说明:
· 一个基于前一个区块的区块头,创建新的待处理区块的函数。区块头包括:
· 块高;
· 对区块状态的 “加密承诺”,这对于轻客户端验证区块正确是很重要的。加密承诺与哈希(hash)的作用相同,你在使承诺失效前无法更改状态。
· 对主体中所有 extrinsics 的加密承诺,可防止 extrinsics 被更改;
· 父区块的哈希值;
· 一些额外的任意数据。此数据的一个用例是用于客户端更新 —— 由于轻客户端仅同步区块头,因此,如果要更新区块头,则无法将更新实现为 extrinsics,否则轻客户端不会接收到它们。
· 将 extrinsic(例如一笔交易)添加到待处理区块的函数。这还应该更新链的状态(例如帐户余额);
· 接受一个待处理区块,并从中生成一个完成的区块的函数。然后可以将完成的区块传播到整个网络。
· 执行现有区块的功能。这由全节点运行,以便在接收区块之前确认收到的区块是有效的。例如,在一条价值链中,你可以确认没人试图转走超过其余额的金额。
这种设计的一个缺点是,你必须手动确保创建区块时完成的状态转换,与执行现有区块时完成的状态转换保持同步。如果不这样做,可能会引起共识问题!将来这一点可能会改变,但是目前这在实践中应该不是什么大问题,因为你可能会将外部函数的执行委派给一个通用函数。
此外,你需要提供一个验证人集(validator set)。尽管目前我们无意在 substrate 中支持工作量证明链,但这既涵盖了权威证明又包括权益证明委托的权益证明链。验证人集是公共密钥的列表,其相应的私钥应被认为对签署给定区块有效。该集合可以更改,但是每个区块均由在创建区块时选择的集合验证。你不必处理处理验证人的票甚至单个区块的 “凭证” 难题,这些问题由 substrate 自动处理。验证人集可以根据需要设置,但这里需要权衡。验证人越少,他们串通起来就越容易,但验证人越多,那么任何给定的区块都需要更多验证才能将其视为 “最终确定(finalised)”(即不可恢复)[2]。
我们无法让 substrate 为你自动处理权益证明,因为权益证明依赖于你的项目,包括带有价值的 token,而并非所有项目都可以做到这一点。测试网可能故意让 token 没有,而使用 substrate 实现消息总线的项目可能根本没有 toekn。但是,很容易在 substrate 之上编写一个库来强制使用 token 并自动为你提供交易和权益证明共识[3]。关于 substrate 的一件事是,在它之上构建更高级别的库相对容易。虽然使用 substrate 构建新的区块链时你可以免费获得很多东西,但它仍然是相对最少的一组原语,并且并非真正可以直接使用。相反,应该把它看作基石,其他常见功能可以纳入帮助程序库。尽管细节还没确认,但 polkadot 并不是唯一在 substrate 上构建的链。随着平台的成熟,可以构建更多的库,来让创建一条新的链,变得像编写现代 web 应用程序一样容易。
我知道科技文章中, “即将到来” 这几个字的可信度跟政客的承诺有一拼,但我还是想以这个结尾。尽管已经可以在 substrate 上进行构建,但是我们目前缺少学习材料。目前,在没有加入 polkadot 团队的情况下,你根本无法学习如何做我刚才告诉你的任何事情。不过,我们正在努力解决这一问题,因此,如果你对此感到兴奋,那么请密切注意即将推出的 substrate 教程和文档。(译者注:本文发表于 2018 年 7 月,而在当前的 2020 年 3 月,已经有不少的 substrate 教程和文档,还有孵化新 substrate 项目的训练营,具体请看文末的参考链接。)
更多资源:
视频:gavin wood 在 event horizon 2018 上介绍 substrate:
youtubeiumzyl5ktwc
视频:rob habermeier 在 truebit 的柏林聚会上介绍 substrate:
youtubeq1zlho7lkuk
parity substrate 的 github repository:
githubcomparitytechsubstrate
注释
当然,实际上,你可能最终希望强制实施向后兼容性,以便外部工具可以轻松地与你的链进行交互,但在开发过程中,你可以根据需要快速而轻松地进行兼容。即使你确实需要向后兼容,也不必很难,你可以使用 protobuf 免费获得有效的向后兼容存储。
作为这种效应的简化案例,例如比特币或以太坊之类的纯粹的工作量证明链根本就不会具有最终性,因为可能的验证人集合是无限的。
例如,一个简单的权益证明链可能会在每个区块中设置一次验证人集,方法是:选择 100 个拥有最大抵押的帐户,并在你获得他们不当行为证明时删除其抵押。