加入 PolkaWorld 社区,共建 Web 3.0!
今年年初,Polkadot 创始人 Gavin Wood 博士在迪拜的 TOKEN2049 大会上发布了 JAM 灰皮书这一令人振奋的技术里程碑。它不仅仅是对现有 Polkadot 网络的改进,更是整个 Web3 的重要技术突破。但要真正理解其意义,我们需要先了解它的发展历程。
以下内容是对 Polkadot 1.0、Polkadot 2.0 以及最终演进到 JAM 的详细解析。在阅读 JAM 灰皮书之前,这篇文章将为你打下良好的基础。
背景知识
本文涉及并假设你了解以下概念:
区块链作为状态转换函数的理解
对 “状态” 概念的理解
以上概念均在此处有详细解释:https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/reference_docs/blockchain_state_machines/index.html
经济安全性和权益证明(Proof of Stake)
在 Polkadot Blockchain Academy 讲座(https://polkadot-blockchain-academy.github.io/pba-book/economics/economics-of-polkadot/page.html#staking-concept)及其录音(https://www.youtube.com/watch?v=suyram9vaFc)中有详细说明。
前言:Polkadot 1.0
首先,让我们回顾一下我认为的 Polkadot 1.0 最具创新性的几大特征。
社区层面
Polkadot 是一个庞大的 DAO,拥有完全链上自治、自执行的治理机制和无需分叉的运行时升级能力。
根据 Web3 基金会的定义,DOT 被视为软件,而非证券。
网络的主要开发工作由 Polkadot Fellowship 负责,而非由像 Parity 这样的公司主导。
技术层面
共享安全性和分片执行模型。
使用基于 WASM 的元协议:将区块链的代码以字节码形式存储在状态中。这样,大多数升级可以做到无需分叉,从而极大提升了 Polkadot 的能力,使其不仅能够进行分片,还能做到异构分片。
接下来,我们将深入探讨什么是分片执行,以及它的实际意义。
分片执行:核心是关键
Polkadot 通常被描述为 L0(Layer 0)层,用于托管其他具有主权性质的链(即 L1)。但在本文中,我们将这一定义稍作调整,将 Polkadot 描述为一个托管其他 L2 区块链的 L1 网络,这与以太坊的角色相似。因此,“L2”和“平行链”在这里可以互换使用。
区块链扩展性的核心问题可以理解为:存在一组验证者,他们通过权益证明(Proof-of-Stake)加密经济学来保障某段代码的可信执行。在默认情况下,这些验证者被要求完全重新执行彼此的所有工作。因此,只要我们强制所有验证者执行这么多的计算操作,系统整体就无法实现可扩展性。
在这种模式下,即使增加验证者数量,只要绝对重新执行的原则依然存在,系统的吞吐量就无法有效提升。
这描述的是一个单体(而非分片)的区块链。在这样的系统中,所有网络验证者必须逐个处理所有输入(即区块)。因此,如果 L1 层想要托管多个 L2,那么所有验证者还必须重新执行所有 L2 的计算任务。
显然,这种方式是无法扩展的。乐观式 Rollup 是一种解决方案,因为它只有在有人声称存在欺诈时,才会触发重新执行(即欺诈证明)。这样就避免了对每个操作都进行重复计算。
一种简单的分片方案是将验证者集划分成更小的子集,让这些子集来处理 L2 区块的验证。然而,这种方法的缺点在于,分片会削弱整个网络的经济安全性。L2 的安全性会比 L1 更弱,并且随着验证者集被进一步划分成更多的分片,L2 的安全性会逐步下降。
乐观 Rollup 的设计本身并不适合一直进行所有交易的重复验证(重执行),因为这样会非常耗费资源。但 Polkadot 的设计从一开始就考虑了如何更好地进行“分片执行”,它允许一小部分验证者来重复验证 L2 区块(而不是所有验证者都去做相同的工作)。同时,Polkadot 能用一种特殊的加密经济学手段来向所有参与者证明,这些小部分验证者的验证结果和整个网络都参与验证时同样可信。
这是通过叫做 “ELVES”的机制实现的!https://eprint.iacr.org/2024/961
简单来说,ELVES 是一种“怀疑式 Rollup”机制。它通过几轮验证者主动询问其他验证者某个 L2 区块是否有效,从而达到极高概率的验证效果。如果出现争议,那么所有验证者都会被召集参与验证。Polkadot 联合创始人 Rob Habermeier 在一篇文章中对此做了详细说明。https://polkadot.network/blog/polkadot-v1-0-sharding-and-economic-security#approval-checking-and-finality
正是因为 ELVES 机制,Polkadot 能够同时具备两种原本被认为无法共存的特性:“分片执行”与“共享安全性”。即,Polkadot 在分片执行和共享安全性之间找到了一个很好的平衡点。这也是 Polkadot 1.0 在扩展性上的核心技术成果。
让我们用“核心”的类比来理解分片执行的区块链。分片执行的区块链就像一个 CPU:就像 CPU 可以有多个核心并行执行指令一样,Polkadot 可以同时处理多个 L2 区块。这就是为什么在 Polkadot 上的 L2 被称为“平行链”(Parachain),而由部分验证者重新执行单个 L2 区块的环境被称为“核心”(Core)。每个核心可以抽象为“一个由验证者组成、协同工作的小组”。
你可以把单体区块链想象成在每个时间段内只能处理一个区块,而 Polkadot 在每个时间段内可以处理一个中继链区块,同时在每个核心上处理一个平行链区块。
异构架构
目前为止,我们讨论的内容主要围绕可扩展性和 Polkadot 提供的分片执行机制。理解 Polkadot 的关键在于:它的每个分片都是完全不同的应用。这是通过一种“元协议”来实现的:该协议将区块链的定义以字节码形式存储在区块链的状态中。在 Polkadot 1.0 中,WASM 被用作默认的字节码格式;而在 JAM 中,则采用了 PVM/RISC-V 格式。
因此,Polkadot 是一个异构的分片区块链,因为它的每一个 L2 都是完全不同的应用程序。
Polkadot 2.0
Polkadot 2.0 的一个重要目标是让核心(Cores)对生态中正在构建项目的团队更加实用。在原本的 Polkadot 模型中,一个核心的租期通常在六个月到两年之间。这对资金充裕的企业来说很合适,但对小团队来说就不太友好了。
为了让核心使用更加灵活,Polkadot 推出了一个新功能,叫做“敏捷核心时间(Agile Coretime)”。在这种模式下,核心的租期可以短到只租用一个区块,也可以长达一个月。对于想要长期租用的用户,还会提供价格上限的保障。这样一来,团队可以根据自己的需求灵活地使用核心资源。
核心内部 vs. 链上操作
要理解 JAM 的运作机制,我们首先需要了解当一个 L2 区块进入 Polkadot 核心时,内部会发生什么。你可能还记得,一个核心主要由一组验证者组成。因此,当我们说数据被“发送到核心”时,实际上是通过消息传播(gossip)方式将数据传递给这组验证者:
一个 L2 区块和该 L2 的部分状态被发送到核心。这些数据就是执行 L2 区块所需的全部信息。
部分验证者(即组成该核心的小组)会重新执行该 L2 区块,并继续完成其他与共识相关的任务。
核心验证者会将重新执行所需的数据提供给核心外的其他验证者。根据 ELVES 规则,其他验证者可能会决定是否对该 L2 区块进行重执行,而他们需要这些数据来完成验证工作。
请注意,到目前为止的所有操作都是在 Polkadot 主链区块和状态转换函数之外进行的。这些操作都发生在核心内部和数据可用性层上。
最终,L2 的最新状态的一个小型承诺(commitment)会被提交到 Polkadot 主链的状态中。这个操作比实际重新执行 L2 区块便宜得多(与之前的所有操作不同),它会影响 Polkadot 主链的状态,并被记录在 Polkadot 区块中,同时被所有 Polkadot 验证者执行并验证。
Polkadot 现在可以执行哪些操作?
从第 1 点我们可以了解到,Polkadot 中存在一种不同于传统区块链状态转换的全新执行类型。在传统区块链中,当网络中所有验证者执行一个任务时,主链状态会更新,我们将这种操作称为“链上操作”。这就是第 3 步中发生的情况。然而,在核心内部发生的操作(第 1 步)则有所不同。我们将这种全新的区块链计算方式称为“核心内执行(in-core execution)”。
接下来,从第 2 点我们可以推测出,Polkadot 已经提供了一个原生的数据可用性(Data Availability,DA)层,并且 L2 会自动使用它来在一定时间内保留其执行证据。然而,这个 DA 层中可以发布的数据“块”(blob)是固定的,并且始终是重新执行 L2 区块所需的证据。此外,平行链的代码并不会从 DA 层中读取。
理解以上内容是理解 JAM 机制的基础。总结如下:
核心内执行(in-core execution):发生在核心内部的操作。具有充足的可扩展性,并且通过加密经济学和 ELVES 机制保证安全性,其安全性与链上执行相当。
链上执行(on-chain execution):发生在所有验证者之间的操作。默认由具有经济安全保障的验证者来确保安全性。由于所有验证者都参与执行,因此更昂贵且更受限。
数据可用性(Data Availability):Polkadot 验证者能够承诺在一定时间内保留一些数据并向其他验证者提供这些数据的能力。
JAM
JAM 是一个全新的协议,深受 Polkadot 的启发,并与其完全兼容,旨在替代 Polkadot 中继链,并对核心的使用方式进行彻底的解放和去中心化。
JAM 构建于 Polkadot 2.0 之上,它的目标是让 Polkadot 的核心(Cores)更加易于使用,但相比于“敏捷核心时间(Agile Coretime)”的方式,JAM 的设计更加灵活、去中心化和无偏见。
Polkadot 2.0 已经让 L2 在核心上的部署更加灵活。JAM 的重点则在于能够在 Polkadot 核心上部署任何应用程序,即便这些应用程序并不像传统区块链或 L2 那样运作。
这主要是通过向开发者开放前面讨论的三大基础原语来实现的,分别是:链上执行(on-chain)、核心内执行(in-core)以及数据可用性(DA)层。
借助 JAM,开发者可以完全编程化地控制任何核心内或链上的执行逻辑,同时还可以从 Polkadot 的 DA 层中读取或写入任意数据。
这就是 JAM 所追求的核心目标的基础描述。需要说明的是,本文对一些概念进行了简化,并且该协议未来可能还会继续演变。
在理解了这些基础之后,我们可以进一步深入讨论 JAM 的更多细节。
服务与工作项
在 JAM 中,原本被称为 L2 或平行链的概念,现在被称为“服务(service)”,而原本的区块或交易,现在被称为“工作项(work-item)”或“工作包(work-package)”。具体来说,一个工作项隶属于某个服务,而工作包是多个工作项的集合。这两个术语被刻意设计得足够通用,以便能够涵盖区块链/L2 之外的更多用例场景。
一个服务通过三个入口点(entry points)进行描述,其中两个分别是 fn refine() 和 fn accumulate。fn refine() 描述服务在“核心内”执行的操作,而 fn accumulate 则描述服务在“链上”执行的操作。第三个入口点是 on_message,当接收到来自其他服务的消息时,会调用这个入口点进行处理。
这两个主要入口点的命名就是 JAM 协议名称的来源:Join Accumulate Machine。Join 对应 fn refine(),指的是当所有 Polkadot 核心并行处理不同服务的大量工作时,数据被提炼为一个较小的子集,并传递到下一个阶段。而 Accumulate 对应的是 fn accumulate,即所有前述工作的结果被累积到 JAM 的主状态中,这就是链上执行的部分。
工作项可以精确指定它们在“核心内”、“链上”执行的代码,以及是否、如何、读取或写入分布式数据湖中的数据。
半一致性
回顾一下与 XCM(Polkadot 的平行链通信语言)相关的现有资料,你会发现所有这些通信都是异步的。也就是说,消息发出后,无法等待其回复。这种异步通信反映了系统的一种不一致性(incoherent),这是像 Polkadot 1.0、Polkadot 2.0 以及以太坊中现有的 L2 架构等永久性分片系统的主要缺点。
然而,正如在 JAM 灰皮书第 2.4 节中所描述的,一个始终为所有租户提供同步通信的完全一致(coherent)系统,其规模也只能在一定程度上扩展,否则就会影响其通用性、可访问性或系统弹性。
同步 ≈ 一致(Coherent)
异步 ≈ 不一致(Incoherent)
这是 JAM 的一个独特之处:通过引入多种特性,JAM 实现了一种新的中间状态 —— 半一致性系统(semi-coherent system)。在这个系统中,经常互相通信的子系统有机会在彼此之间创建一个一致的环境,而无需强制整个系统都保持一致性。JAM 灰皮书的作者 Gavin Wood 博士在多次采访中深入探讨了这一点。
另一个形象的类比是,将 JAM 时代的 Polkadot 看作一个分片系统,但这些分片的边界是动态的,可以随时调整。
这种特性得以实现的关键在于以下几点:
无状态、并行的核心内执行:不同服务之间只能在同一区块中、位于同一个核心的服务之间实现同步交互。而“链上执行”则允许某个服务访问所有核心中所有服务的执行结果。
服务调度的自由度:频繁交互的服务可以通过经济激励促使调度者(sequencers)将这些服务的工作项(WorkItems)打包到同一个工作包(WorkPackage)中,从而使它们位于同一个核心内。这样,它们可以像在同步环境中一样互相通信。
数据可用性(DA)层的访问权限:作为一种临时但极其廉价的数据层,一旦数据被放入 DA 层,它最终会传播到所有核心,但在同一个核心内可以立刻访问。因此,JAM 服务可以通过将自己调度到连续区块中的同一个核心内,从而享受到更高的即时数据访问能力。
需要注意的是,尽管上述特性在 JAM 中是可能的,但它们并不是由协议层强制执行的。因此,某些接口在理论上是异步的,但通过精巧的抽象和激励机制,可以在实际中表现为同步。例如,下一个章节中将讨论的 CorePlay 就是一个这样的例子。
CorePlay
在 JAM 的背景下,CorePlay 是一个实验性的想法,可以被描述为一种编写智能合约的新模型。目前,CorePlay 仍然只是一个概念,还没有具体的细节。
无论如何,要理解 CorePlay,我们首先需要介绍 JAM 所选择的虚拟机——Polkadot 虚拟机(Polkadot Virtual Machine),也被称为 PolkaVM 或简称 PVM。
PolkaVM
JAM 和 CorePlay 的一个重要细节就是 PolkaVM。关于 PolkaVM 的底层细节超出了本文的讨论范围,最好的描述可以参考相关领域专家撰写的灰皮书。然而,本文只需关注 PolkaVM 的两个特点:
高效的资源计量(Efficient metering)
能够暂停和恢复执行的能力
CorePlay 是利用 JAM 灵活原语来创建同步且可扩展的智能合约环境的一个例子,同时提供了一个非常灵活的编程接口。CorePlay 提倡将基于 actor 模型(角色模型)的智能合约直接部署在 JAM 核心中,使它们能够使用同步的编程接口。开发者可以像编写普通函数 fn main() 一样进行编码,在合约中使用 let _result = other_coreplay_actor(data).await? 来进行通信。
如果 other_coreplay_actor 在同一个 JAM 区块中的同一个核心内执行,那么该调用是同步的;而如果它位于另一个核心中,那么这个 actor 将被暂停,并在后续的 JAM 区块中恢复执行。这种机制的实现得益于 JAM 服务及其灵活的调度能力,以及 PolkaVM 的上述特性。
核心链服务
最后,让我们总结一下为什么我们强调 JAM 与 Polkadot 是完全兼容的。Polkadot 的主要产品是以“敏捷核心时间(Agile Coretime)”模式运行的平行链,而这个产品在 JAM 中依然保留。
JAM 中第一个可能部署的服务很可能会被称为“核心链”或“平行链”之类的名称。这个服务将允许现有的 Polkadot 2.0 风格的平行链能够在 JAM 上继续执行。
未来可以在 JAM 上部署更多的服务,并且现有的核心链服务可以与它们进行通信。但 Polkadot 的现有产品(平行链)依然会保持稳固,同时这也为现有的平行链团队开启了更多新的可能性。
PolkaWorld Telegram 群:
https://t.me/+z7BUktDraU1mNWE1
PolkaWorld Youtube 频道:
https://www.youtube.com/c/PolkaWorld
PolkaWorld Twitter:
@polkaworld_org
更多内容
Polkadot 2.0 即将实现全面上线!为下一波 Web3 采用和创新奠定基础!
关注 PolkaWorld
发现 Web 3.0 时代新机遇
点个 “在看” 再走吧!