一个工人,干四份活
想象一家小小的餐馆,从头到尾就一个人:他给你引位、给你做菜、把每一只碗都刷了、还把账也记了——全靠他自己,招待每一位客人。店里清闲时,这套法子转得动。可一旦人潮涌进来,这个累得团团转的人,就成了整家餐馆能跑多快的天花板。你没法在不找一个更快的人的前提下多招待客人,而任何一个人能有多快,是有极限的。
一条经典的链,比如早期的 以太坊,就是那个累得团团转的人。每一个 全节点 都被要求,为每一笔 交易同时干四份活:重跑一遍运算(执行)、就那唯一真实的排序达成一致(共识)、确保底层数据真的被发布出来、任何人都能去查(数据可用性),还要把最终敲定的状态锚定下来、争议在这里裁决(结算)。把这四样全捆进一个节点、再让所有人来跑,这就是我们说的单体设计。它简洁优美、自成一体——可也跟那个孤身一人的厨子一样,有一道硬天花板。
把链拆成一层一层
第一个点子,跟当初拯救我们那家餐馆的是同一个:请专人。雇一个专门的厨子、一个专门的洗碗工、一个会计、一个引位员——各自只干自己最拿手的那一件事,而且并行地干。一条 模块化区块链 做的正是这件事。它不再让一条链把四份活全包了,而是把它们拆成各自独立的分层,让每一层都能被单独地优化、扩展,甚至单独替换掉。
通常这么一切,会切出三到四个角色。执行层负责跑交易、算出新的状态——繁重的活儿都住在这一层。结算层是那个受信任的大本营,争议在这里裁决、最终状态在这里锚定。共识层就那唯一真实的事件排序达成一致。而数据可用性层,则担保原始的交易数据确确实实被发布了出来,于是任何人都能把它下载下来、亲自去核对那一遍执行。把这几样拆开,每一样都能为自己那份活儿狠狠地调优一番。
MONOLITHIC MODULAR (one node, all jobs) (specialized layers) +-------------------+ +-------------------+ | EXECUTION | | EXECUTION (L2) | fast, cheap | CONSENSUS | +-------------------+ | SETTLEMENT | -> | SETTLEMENT (L1) | secure anchor | DATA AVAIL. | +-------------------+ | (all in one) | | CONSENSUS + DA | shared base +-------------------+ +-------------------+
Rollup 怎样嵌进这套堆栈
这正是一条 rollup 大显身手的地方,也是为什么模块化这套说法和 第二层 那套说法,其实是同一个故事。一条 rollup,是一个住在某条基础链之上的执行层。它把忙碌的活儿挪到一旁去干——成千上万笔交易,在那里被便宜地排序、运算——然后把它们打成一捆,再把一份紧凑的摘要回贴到安全的基础层上,通常就是以太坊。基础层从不去把那一笔笔交易重跑一遍;它只是握着数据和证明,并把自己的安全性借给那个结果。
于是一条 rollup,就是一套模块化堆栈里的执行层,而基础链则扮演结算加数据可用性。神奇之处全在最后那个词上:通过把自己的原始数据回贴到基础层,一条 rollup 让任何人都能重建并核对它干的活儿,于是它继承了基础层的安全性,而不必另起炉灶自造一套。一条 ZK Rollup 还更进一步,附上一份 零知识证明,证明这一捆是算对了的——一张小小的收据,基础层眨眼之间就能验掉,根本不必把数学重做一遍。正是这一手,让你能同时拥有便宜的执行与强劲的安全,也就是三难里那个被禁止的配对。
分片:拆的是负载,不是分工
分片 从另一个角度去攻同一道天花板。这个点子是从那些庞大数据库如何应付海量数据里借来的:别再要求每个节点都去处理每一笔交易了。换个法子,把网络分成一个个子集——分片——让每一个分片只处理属于它自己的那一片流量。十个分片,各自并行地扛着十分之一的负载,加起来差不多能干一个分片十倍的活儿。模块化拆的是活儿的种类,而分片拆的是把同一份活儿的工作量分摊到各个组里。
麻烦在于,把负载拆开,可能连安全性也一并拆掉了。如果每个分片只有十分之一的验证者在盯着,那么一个本来根本威胁不到整张网络的攻击者,也许就能廉价地把某一个孤零零的分片压垮。让分片之间安全地互相通话,再把 验证者 不停地洗牌轮换、好让没有哪个分片能被悄悄拿下——这事儿原来是真的难——这也正是为什么早期那些分片方案如此雄心勃勃、却又迟迟落不了地。
前沿这边有个出人意料的转折:这两个点子最终合流了。以太坊没有去给执行分片,而是只给数据可用性层分片——把发布数据这件又便宜又充裕的活儿,分摊到整张网络上去,同时把执行留给上面那些 rollup。这就是数据分片,也是整套模块化哲学最干净利落的一个示范:给那个容易扩展的部分分片,给那个难啃的部分配专才,再让各层之间彼此借用安全性。
权衡,与本篇要点
这一切没有一样是白来的。一条单体链,有一个清清楚楚的故事、一个安全与数据共处的地方、也没有可供漏风的接缝。一套 模块化 系统,是靠在接合处添上复杂度来换取规模的:数据必须被可靠地发布、证明必须被核验,而在各层之间挪动价值,就需要一座 跨链桥——这历来是整个领域里被攻击得最凶的那一个点。零件越多,就越多地方能出那种微妙的差错,而这个领域至今仍在火热地摸索,到底怎样把各层粘合到一起才最好。
把这幅核心图景攥牢,剩下的就都顺下来了。单体把每一份活都塞进一个节点——简单,但被它最忙的那个节点封了顶。模块化把每一份活——执行、共识、结算、数据可用性——交给一个专门的分层,于是每一层都能自顾自地扩展。Rollup 就是那个执行层,它在一旁把活儿便宜地干掉,再向基础层借来安全性。分片 把负载分摊到一个个子集上,而现代的设计,给容易又充裕的那部分——数据——分片,同时把难啃的部分留给 rollup。三难 这片前沿下的那一注大赌是:你再也不必三选二了——只要接缝搭得对,一摞朴素的分层叠起来,就能去中心化、安全、而且快,三样一齐拥有。