以下是对Polkadot1、Polkadot2及其如何演变为JAM的详细解释。(详情请参见:https://www.navalmanack.com/almanack-of-naval-ravikant/how-to-think-clearly)本文面向技术读者,尤其是那些并不十分熟悉波卡但对区块链系统有一定了解的技术人员,并且可能了解其他生态系统相关技术的读者。
我认为,在阅读JAM灰皮书之前,阅读本文是一个很好的前奏。(详情请参见:https://graypaper.com/)
背景知识
本文假定读者熟悉以下概念:
- 将区块链描述为状态转换函数。
- 理解什么是“状态”。(详情请参见:
- 经济安全和权益证明。(详情请参见:
https://polkadot-blockchain-academy.github.io/pba-book/economics/economics-of-polkadot/page.html#staking-concept、https://www.youtube.com/watch?v=suyram9vaFc)
前言:Polkadot1
首先,回顾一下我认为Polkadot1最具创新性的特征。
- 社会层面:
- 波卡是一个庞大的去中心化自治组织(DAO)。该网络实现了完全基于链上、实现自我执行的治理,包括无需分叉的运行时升级。
- 美国证券交易委员会(SEC)将DOT视为软件而非证券。(详情请参见:
- 网络开发的大部分工作由Polkadot Fellowship完成(详情请参见:
https://polkadot-fellows.github.io/dashboard/),而不是由财政支持的公司(如Parity:https://www.parity.io/)进行。
- 技术层面:
- 波卡实现了共享安全和分片执行。
- 使用基于WASM的元协议(详情请参见:
关于“异构分片”的更多信息,请参见相关章节。
分片执行:核心要点
目前,我们正在讨论一个托管其他Layer2“区块链”网络的Layer1网络,类似于波卡和以太坊。因此,Layer2和平行链(Parachain)这两个词可以互换使用。
区块链可扩展性的核心问题可以表述为:存在一组验证者,他们可以通过权益证明(Proof-of-Stake)的Crypto经济性来确保某些代码的执行是可信的。默认情况下,这些验证者需要重新执行彼此的全部工作。因此,只要我们强制所有验证者始终重新执行一切,整个系统就不可扩展。
请注意,只要上述绝对重新执行原则保持不变,那么在这个模型中增加验证者的数量并不会真正提高系统的吞吐量。
以上展示的是一个单体区块链(与分片区块链相对)。所有网络验证者都会逐一处理输入(即区块)。
在这样的系统中,如果Layer1想要托管更多的Layer2,那么所有验证者现在都必须重新执行所有Layer2的工作。显然,这种方法无法扩展。Optimistic Rollups是规避这个问题的一种方式,因为只有在有人声称发生了欺诈时,才会重新执行(欺诈证明)。基于SNARK的Rollups通过利用验证SNARK证明的成本远低于生成它的这一事实来规避这一问题,因此允许所有验证者验证SNARK证明是合理的。有关此方面的更多信息,请参阅“附录:可扩展性空间图”。
分片的一个简单解决方案是仅仅将验证者集合分割成更小的子集,并让这个较小的子集重新执行Layer2区块。这个方法的问题是什么?我们正在对网络的执行和经济安全性进行分片。这样的Layer2的安全性低于Layer1,并且随着我们将验证者集合分割为更多的分片,其安全性会进一步下降。
与无法始终重新执行成本的Optimistic Rollups不同,波卡在设计时就考虑了执行分片,因此它可以让一部分验证者重新执行Layer2区块,同时向所有网络参与者提供足够的Crypto经济学证据,证明该Layer2区块的真实性与整个验证者集合重新执行它时一样安全。这通过一种新颖的(最近正式发布的)ELVES机制实现的。(详情请参见:https://eprint.iacr.org/2024/961)
简而言之,ELVES可以被看作一种“怀疑式Rollups”机制。通过几轮验证者主动询问其他验证者某个Layer2区块是否有效,我们可以极大概率地确认该Layer2区块的有效性。实际上,在发生任何争议时,很快就会要求整个验证者集合参与。波卡联合创始人Rob Habermeier在一篇文章中详细解释了这一点。(详情请参见:https://polkadot.com/blog/polkadot-v1-0-sharding-and-economic-security#approval-checking-and-finality)
ELVES使得波卡能够同时具备两个以前被认为是互相排斥的属性:“分片执行”和“共享安全”。这是Polkadot1在可扩展性方面的主要技术成果。
现在,继续讨论“核心(Core)”类比。
一个执行分片的区块链非常像一个CPU:与CPU可以有多个并行执行指令的核心一样,波卡可以并行处理Layer2区块。这就是为什么波卡上的Layer2被称为平行链,而由较小的验证者子集重新执行单个Layer2区块的环境被称为“核心(core)”。每个核心可以抽象为“一组协同工作的验证者”。
你可以把单体区块链想象成在任意时间段内只摄取一个区块,而波卡则在每个时间段内摄取一个中继链区块和每个核心的一个平行链区块。
异构性
到目前为止,我们只讨论了可扩展性和波卡提供的分片执行。值得注意的是,波卡的每个分片实际上都是完全不同的应用程序。这是通过使用存储在字节码中的元协议实现的:一种将区块链定义作为字节码存储在区块链自身状态中的协议。在Polkadot 1.0中,WASM被用作首选字节码,而在JAM中,则采用了PVM/RISC-V。
总而言之,这就是为什么波卡被称为异构分片区块链。(详情请参见:https://x.com/kianenigma/status/1790763921600606259)每个Layer2都是完全不同的应用程序。
Polkadot2
Polkadot2的一个重要部分是让核心的使用更加灵活。在原始的波卡模型中,核心的租期可以从6个月到2年不等,这适合于资源丰富的企业,但对小团队来说则不太合适。波卡核心能够以更灵活方式使用的特性被称为“敏捷核心时间”(agile coretime)。(详情请参见:https://polkadot.com/agile-coretime)在这种模式下,波卡核心的租期可以短至一个区块,也可以长达一个月,并为那些希望长期租用的用户提供价格上限保障。
Polkadot 2的其他特性正在我们讨论的过程中逐渐展现,因此在这里不需要过多赘述。
核心内部与链上操作
为了理解JAM,首先需要了解当一个Layer2区块进入波卡核心时会发生什么。
以下内容进行了大量简化。
回顾一下,核心主要由一组验证者组成。因此,当我们说“数据被发送到核心”时,实际上是指这些数据被传递给这组验证者。
0.一个Layer2区块加上该Layer2的一部分状态被发送到核心。这些数据是执行该Layer2区块所需的全部信息。
1.核心内的一部分验证者会重新执行Layer2区块,并继续处理与共识相关的任务。
2.核心验证者将重新执行所需的数据提供给其他验证者(核心外部的验证者)。其他验证者可能根据ELVES规则决定是否重新执行该Layer2区块,并且他们需要这些数据来完成此操作。
注意,到目前为止,所有操作都在波卡的主区块和状态转换函数之外进行。一切都发生在核心内部以及数据可用性层上。
3.最终,Layer2最新状态的一小部分会在波卡主中继链上可见。与之前的所有操作不同,这项操作比实际重新执行Layer2区块便宜得多,它会影响波卡的主状态,在波卡区块中可见,并由所有波卡验证者执行。
从上述内容中,我们可以探讨波卡正在执行的一些操作:
首先,从第1步我们可以得出,波卡中存在一种与传统区块链状态转换函数不同的新型执行方式。通常,当网络中的所有验证者执行某项工作时,主区块链状态会更新。我们称这种情况为链上操作(on-chain operation),这就是第3步中发生的事情。然而,在核心内部发生的情况(第1步)与此不同。我们称这种新型区块链计算为核心内执行(in-core execution)。
接下来,从第2点我们可以推断出,波卡已经提供了一个原生的数据可用性(Data-Availability,以下简称DA)层,并且Layer2自动使用它来确保其执行证据在一段时间内可用。然而,可以发布到该DA层的数据块是固定的,它始终是重新执行Layer2区块所需的证据。此外,平行链的代码从未读取DA层数据。
理解上述内容是理解JAM的基础。总结如下:
- 核心内执行(in-core execution):指核心内部发生的操作。其特点是丰富、可扩展,并通过Crypto经济学和ELVES实现与链上执行同样的安全性。
- 链上执行(on-chain execution):指所有验证者执行的操作。通过经济保障的验证者默认获得安全性,但成本更高且限制更多,因为所有人都在执行所有操作。
- 数据可用性(Data Availability):波卡验证者在一定时间内承诺一些数据的可用性,并向其他验证者提供这些数据的能力。
JAM
通过前一部分的理解,我们可以顺利过渡到对JAM的介绍。
JAM是一个受波卡启发而设计的新协议,并与其完全兼容,旨在取代波卡中继链,并让核心的使用变得完全去中心化且无限制。
JAM构建于Polkadot2之上,试图让波卡的核心更加易于访问,但方式上比agile-coretime更加灵活和无固定限制。
- Polkadot2使得Layer2在核心上的部署更加灵活。
- JAM则旨在让任何应用程序都能部署在波卡核心上,即使这些应用程序并不像区块链或Layer2那样。
这主要通过向开发者暴露前面部分讨论的三种主要原始概念来实现:即链上执行、核心内执行和DA层。
换句话说,在JAM中,开发者可以接触到:
- 完全可编程化核心内和链上的工作。
- 允许任意数据被读写至波卡的DA层。
这是对JAM目标的基础描述。无需多言,这里做了很多简化,且协议可能仍会演变。有了这个基础理解,我们现在可以在接下来的章节中进一步探讨JAM的一些细节。
服务与工作项
在JAM的背景下,过去被称为Layer2/平行链的现在称为“服务(Service)”,过去被称为区块/交易的现在称为“工作项(Work-Item)”或“工作包(Work-Package)”。具体来说,工作项属于某个服务,而工作包则是工作项的集合。这些术语被有意设计得足够通用,以涵盖超越区块链/Layer2的各种用例。
一个服务由三个入口点描述,其中两个分别是fn refine()和fn accumulate()。前者描述服务在核心内执行的内容,后者描述服务在链上执行的内容。
最后,两个入口点的名称也是协议被称为JAM(Join Accumulate Machine)的原因。Join即fn refine(),当所有波卡核心并行处理不同服务的大量工作时,这一阶段被称为Join。数据经过筛选后,进入下一个阶段。Accumulate则指的是所有上述结果被累积到主JAM状态中的过程,也就是链上执行部分。
工作项可以精确指定它们在核心内、链上执行什么代码,并指明它们如何/是否/从哪里读写分布式数据湖(Distributed Data Lake)中的内容。
半一致性
回顾现有关于XCM(波卡选择的平行链通信语言)的资料,其中所有通信都是异步的。(详情请参见:https://github.com/polkadot-fellows/xcm-format?tab=readme-ov-file#11-xcm-communication-model)也就是说,消息发送后,无法等待其回复。
异步性是系统不一致性的表现,是永久分片系统(如波卡1和波卡2以及以太坊现有的Layer2生态系统)的主要缺点。
然而,正如灰皮书第2.4节中描述的,一个始终为其所有租户保持同步的完全一致系统,也只能在不牺牲普遍性、可访问性或弹性的情况下增长到一定程度。(详情请参见:https://graypaper.com/graypaper.pdf)
同步≈一致性||异步≈不一致性
这也是JAM脱颖而出的另一个领域:通过引入多种特性,JAM实现了一种新颖的中间状态,即半一致性系统。在这个系统中,频繁通信的子系统有机会在彼此之间创建一致的环境,而不强制整个系统保持一致。这在灰皮书作者Gavin Wood博士的采访中得到了最好的描述:(详情请参见:https://www.youtube.com/watch?t=1378&v=O3kRAVBTkfs&embeds_referring_euri=https://blog.kianenigma.nl/&source_ve_path=OTY3MTQ)
另一种理解方式是将波卡/JAM视为一个分片系统,其中这些分片的边界是流动的,并且是动态决定的。
波卡一直是分片的,并且完全异质化。
现在,它将被分片、异构,而且这些分片的边界可以灵活决定,正如Gavin Wood在推特中所谓的“半一致性”系统。(详情请参见:https://x.com/gavofyork?ref_src=twsrc^tfw、https://graypaper.com/)
使这一切成为可能的特性包括:
1.访问无状态的、并行的核心内执行,其中不同的服务只能与在同一核心中且在特定区块内的其他服务同步交互,以及链上执行,其中服务可以访问跨所有核心的所有服务的结果。
2.JAM不强制执行任何特定的服务调度。频繁通信的服务可以为其排序器提供经济激励,创建包含这些频繁通信服务的工作包。这使这些服务能够运行在同一个核心内,彼此之间的通信就像是在一个同步环境中进行一样。
3.此外,JAM服务可以访问DA层,并可以将其用作一种临时但极其便宜的数据层。一旦数据被放置在DA中,它最终会传播到所有核心,但在同一个核心内立即可用。因此,JAM服务可以通过在连续区块中将自己调度到同一个核心,享受更高程度的数据访问。
需要注意的是,虽然上述内容在JAM中是可能的,但并未在协议层强制执行。因此,预计某些接口在理论上是异步的,但通过精妙的抽象和激励措施,可以在实践中表现为同步的。接下来的部分将讨论的CorePlay就是这样的一个例子。
CorePlay
本节介绍了CorePlay,这是在JAM环境下的一个实验性想法,可以描述为一种新的智能合约编程模型。截至撰写本文时,CorePlay尚未被详细说明,仍然是一个设想。
要理解CorePlay,我们首先需要介绍JAM选择的虚拟机:PVM。
PVM
PVM是JAM和CorePlay中的一个重要细节。PVM的低层次细节超出了本文的范围,最好查看领域专家在灰皮书中的描述。不过,为了本文的需要,我们只需阐述PVM的几个属性:
- 高效计量
- 暂停和恢复执行的能力
后者对于CorePlay尤为重要。
CorePlay是使用JAM的灵活原语创建一个同步且可扩展的智能合约环境的一个例子,具有非常灵活的编程接口。CorePlay建议将基于Actor的智能合约直接部署在JAM核心上,使它们能够享受同步编程接口,在其中可以像普通的fn main()一样进行编写,并通过let_result=other_coreplay_actor(data).await?进行通信。如果other_coreplay_actor在同一个JAM区块中的核心上,这个调用是同步的;如果在另一个核心上,该Actor会被暂停,并在后续的JAM区块中恢复。这正是因为JAM服务及其灵活的调度,以及PVM的属性,使这种情况成为可能。
CoreChains服务
最后,让我们总结一下提到JAM完全兼容波卡的主要原因。波卡的主要产品是以敏捷核心时间方式运行的平行链(Parachains),而这一产品在JAM中得以延续。
在JAM中最早部署的服务很可能会被称为CoreChains或Parachains。这项服务将允许现有的波卡-2风格的parachains在JAM上运行。
进一步的服务可以在JAM上部署,并且现有的CoreChains服务可以与它们通信,但波卡现有的产品仍将保持强劲,只会为现有的Parachain团队开启新的大门。
附录:数据分片
本文大部分内容从执行分片的角度探讨了可扩展性。我们也可以从数据的角度来审视相同的问题。有趣的是,我们发现这与前面提到的半一致性情况类似:原则上,完全一致的系统更好,但无法扩展;完全不一致的系统可扩展,但不理想,而JAM以其半一致性模型提出了一种新的可能性。
完全一致系统:这是我们在完全同步的智能合约平台上看到的,如Solana或那些勇敢地仅部署在以太坊Layer1上的平台。所有应用数据都存储在链上,并且可以轻松访问到所有其他应用。这是一个程序化的完美属性,但不可扩展。
不一致系统:应用数据保存在Layer1外部,以及不同的、隔离的分片中。极具可扩展性,但在可组合性方面表现不佳。波卡和以太坊的Rollup模型属于这种情况。
JAM除了提供上述两种功能外,还允许开发者将任意数据发布到JAM DA层,这在某种程度上是链上数据和链下数据之间的中间地带。可以编写利用DA层的大部分应用数据的新型应用,同时只将绝对关键的数据持久化到JAM状态中。
附录:可扩展性空间图
这一部分重新解释了我们对区块链可扩展性领域的观点。这在灰皮书中也有说明,这里提供了一个更简洁的版本。
区块链的可扩展性在很大程度上遵循了传统分布式系统中使用的方法:向上扩展(垂直)和向外扩展(水平)。
向上扩展是像Solana这样的平台所做的工作。通过对代码和硬件进行极限优化,以实现最大吞吐量。
向外扩展是以太坊和波卡所采用的策略:减少每个人需要完成的工作量。在传统的分布式系统中,这通过增加更多的复制机器来实现。在区块链中,“计算机”是整个网络的验证者集合。通过在它们之间分配工作(如ELVES所做的),或通过乐观地减少它们的职责(如乐观Rollups所做的),我们减少了整个验证者集合的工作负载,从而实现了系统的向外扩展。
在区块链中,向外扩展类似于“减少需要执行所有操作的机器数量”。
总结如下:
1.向上扩展:高性能硬件+单体区块链的优化。
2.向外扩展:
1.乐观Rollups
2.基于SNARK的Rollups
3.ELVES:波卡的讽刺Rollups(Cynical Rollups)
附录:相同硬件,内核更新
本节基于Rob Habermeier在Sub02023中提供的类比:波卡:Kernel/Userland|Sub02023-YouTube(详情请参见:https://www.youtube.com/watch?v=15aXYvVMxlw),展示了JAM作为对波卡的升级:在相同硬件上的内核更新。
在典型的计算机中,我们可以将整个堆栈划分为三个部分:
1.硬件
2.内核
3.用户空间
在波卡中,硬件,即提供计算和数据可用性的本质,一直是核心(cores),如前面所述。
在波卡中,内核实际上到目前为止包含了两个部分:
1.平行链(Parachains)协议:一种意见化、固定的使用核心的方式。
2.一组低级功能,例如DOT代币及其可转移性、质押、治理等。
这两者都存在于波卡的中继链(Relay Chain)中。
用户空间应用则是parachains的实例、它们的原生代币以及在它们之上构建的其他内容。我们可以如下可视化这一过程:
波卡一直设想将更多的核心功能移至其一类用户——平行链。这正是Minimal Relay RFC旨在实现的目标。(详情请参见:https://github.com/polkadot-fellows/RFCs/blob/main/text/0032-minimal-relay.md)
这意味着波卡中继链仅处理提供平行链协议,从而在一定程度上缩小了内核空间。
一旦实现了这种架构,便更容易可视化JAM迁移的样子。JAM将大幅缩小波卡的内核空间,使其更具通用性。此外,Parachains协议将移至用户空间,因为这是为数不多的能够在相同核心(硬件)和内核(JAM)上编写应用程序的方式之一。
这也再次说明了为什么JAM只是波卡中继链的替代品,而不是平行链的替代品。
换句话说,我们可以将JAM迁移视为内核升级。底层硬件保持不变,旧的内核的大部分内容被移至用户空间,以简化系统。
想参与到本文的讨论,欢迎到论坛中发表自己的意见:https://blog.kianenigma.nl/posts/tech/demystifying-jam/
(责任编辑:小陈)