Ethereum 2.0 基本架构理解
Ethereum (以下简称 eth)2.0 从 2018 年提出改进到现在已经 4 年了。现有的 eth 1.0 是基于 pow 共识的链。pow 共识主要存在以下问题:
浪费能源。
性能低,每秒只能处理十几笔交易。
数据完全集中存储在一个节点。
算力集中问题,芯片巨头理论上有 51% 算力攻击能力。
eth 2.0 最核心的改动是把 pow 换为 pos,和分片链。eth 2.0 最主要的目标有:
- 数据的读写分片,解决 block 数据读写在一个节点的问题。
- 通过 pos 算法提高 TPS
- 防止过度中心化
- 平民化,任何民用的机器(树霉派都行)只要质押 32 个 ETH 都能成为 validator 节点
以下是 eth2.0 基本架构
上图解释: beacon chain 是个单独的链,它协调所有的 sharding chain。注意上面图里面的 shard 1~shard 100。它表示一个 beacon chain 的 block 负责管理 1~100 的 shard block。
eth1.0 到 2.0 以 phase 的形式进行迭代。具体的时间节点从 2018 年开始。(很明显,已经 delay 很久了)
Phase 0: 构建 beacon chain 网络。
Phase 1: 构建分片网络,让数据读写分片。
Phase 2: EVM 可支持分片网络。
以下是各项升级涉及到的一些技术细节,你可以到这里深入了解里面的具体技术。
beacon chain 网络
beacon chain 网络是整个 eth2.0 非常关键的一环,它负责 validator 的注册和质押,以及随机的分配 validator 到一个 committee 进行 pos 投票。为了保证区块的随机性和防止做假预测, eth 2.0 引入了 RANDAO(随机数生成器)random+DAO。它的简要原理如下:
设想一堆人坐在一个房间,每个人任意给一个数字,最后给出数字的那个人把其他人给出的数字加总,然后以此做为随机数 seed。为了防止最后一个人给出他自己可以预测的数字进行做假,他需要做一轮 VDF(Verifiable Delay Functions) 运算得出一个最终的随机数。
beacon chain 也是一个 block chain 系统,它需要 validator 通过 pos 共识算法给每一个 block 进行投票。每 12 秒会有一个时间同步 slot, 每个 slot 里面会产生一个 block。32 个 slot 组成一个 epoch。这里 slot 和 epoch 的作用先按下不表,下文再做介绍。先说下投票的过程。
在每轮 epoch 里,validator 将会被随机分配到一个 committee 进行投票。每个 slot 会随机选一个 proposer 做为 block producer(出块者)。 其他的 validator 会投票(POS)验证成这个块是否合法。如果超过三分之二同意就通过,高于三分之一的反对票则无法达成共识。(拜占庭共识)。一个 validator 有可能同时兼具 proposer 和 validator 角色,但这种情况比较罕见。
为防止共谋发生,每轮 epoch 中 validator 只会被随机的分配到一个 committee 里面。每个 committee 不会让他们连续投相邻两个区块的票。eth2.0 在数学上保证超过三分之一 validator 共谋的概率是万亿分之一。
从以上我们可以看出 slot 的作用是给 validator 之间的分布式环境做同步用的,还有就是每个 slot 的分割投票减少 validator 的共谋,每轮 epoch 后 validator 和 committee 会重新进行洗牌投票。
现在的 beacon chain 只运行了 pos 的投票验证,还未见到任何和 sharding block 有关的数据详情见 beaconscan。也未见到如何把 beacon chain 和 sharding chain 联合起来的方案(欢迎留言补充)。不过社区已经有不少关于 sharding chain 的讨论,我们可以初探一下。
sharding chain
eth2.0 把 shred(分片) 分为 64 个。每个 shred 只负责它自己内部的数据读写,涉及到跨链的读写操作需要 beacon chain 进行协调。这里sharding chain 有个关键的问题需要解决,就是执行交易和合约时需要全局的数据,如何与其他节点高效的进行交互?社区讨论的有两种方案,同步和异步:
-
同步
同步的改两个 shred 的 block。两边必须进行状态同步通信。 -
异步
假设有一笔跨 shred 的交易需要从 shred A 里的 账户a 里减 10 块钱,然后到 shred B 里面的 账户 b 里加 10 块钱。 shred A 先创建好一个 receipt(扣掉 a 的钱,目标账户地址,目标 shred,金额)。 shred B 拿到这个 receipt 后会先执行验证,验证成功后往账户 b 里面加 10 块钱。这个 receipt 必须要可验证,还要防止 double spending,需要给这个 receipt 赋一个唯一的自增长 ID 存在 shred A 中。shred B 只要去追踪源 shred A 里面的这个 ID 就能知道这笔钱有没有被花掉。
这里需要注意的是有一个中间状态,就是 sharding A 把钱扣掉了,然后创建 receipt。sharding B 再把创建好的 receipt 状态同步到它自己的 shred 里。