本文详细探讨了 Danksharding 作为以太坊未来扩展方案的一部分,特别是数据可用性采样(DAS)的工作原理及其潜在改进。文章介绍了 Protodanksharding 和 Danksharding 的基本概念,如何通过 erasure coding 和多项式承诺确保数据的可用性和可恢复性,并提出了一种通过修改协议以降低重构所需数据比例的方案。
Danksharding 是一种扩展链上数据的方法,旨在为以太坊的未来版本提供规模化解决方案。该升级的目标是确保在数据首次发布时档案方能够访问链上的数据。它通过一种称为数据可用性采样(Data Availability Sampling,简称为 DAS)的技术来实现这一点。
在这篇文章中,我们调查了 danksharding 中数据可用性的工作原理,并提出了一些对底层技术的修改。特别地,我们探索了一种小的修改,可能会改善数据恢复:当前的提议要求 75% 的份额才能恢复一个区块,而该修改可以将这个界限降低到 25%。
Danksharding 将紧随 protodanksharding(EIP-4844)实施。Protodanksharding 将允许客户端通过引入一种新的交易类型“blob-carrying transaction”向区块链写入更多数据。最初,这种新的交易类型将携带多达四个数据blob的列表,其中每个blob最大为 128 KB(每个 32 字节的字段元素总共为 4096),每个区块增加最多 512 KB 的额外数据(目标平均为 256 KB),相比于当前以太坊的区块大小,后者大约为 100 KB 平均。
这些数据 blob 将会以不同的方式处理: (i) 它们将仅在有限的时间内存储,例如 30-60 天,(ii) 尽管这些数据是交易数据的一部分,但对智能合约将不可直接访问。相反,智能合约只能访问这些 blob 数据的一个简短承诺,称为 DATAHASH。对验证者的额外负担似乎是可以接受的:验证者目前存储的区块链状态小于 100 GB。在 protodanksharding 后,他们将不得不额外存储 50-100 GB。
Danksharding 将跟随其后。它将通过增加每个区块的最大 blob 数量,使数据可用性提高 60 倍。区块大小将从每个区块 0.5 MB 增加到 30 MB。但由于无法要求验证者存储 60 倍的数据,这些数据将分散于他们之间,使得每个验证者只存储小部分数据。然而,他们可以通过数据可用性采样(DAS)协议就他们是否共同存储所有数据达成一致。
blob 数据的定价将采用类似于 EIP-1559 的机制,并将目标设定为每字节约 1 data-gas。当前最便宜的替代方案 calldata 的定价为每字节 16 gas。但由于将存在两个不同的费用市场,因此这些成本不可直接比较。增发客户端将从这些升级中受益,因为目前超过 90% 的客户端费用都用于 支付以太坊的数据费用。
其他项目,如 Celestia 和 EigenLayer,也正在采用 DAS 技术来增加可用数据空间。这些设计比完全分片以太坊网络要简单得多。
我们描述该方案假设有一个提议者-建筑者分离(PBS)设计:
挑战在于确保在后续时间能重建区块 B。为此,构建者在一个大的验证者网络中复制区块。我们可以要求每个验证者存储整个区块,但那被认为成本过高。相反,区块构建者:
每个验证者检查它所收到的片段 Pi 是否与签名承诺列表 C 一致。区块构建者提供证明以帮助验证者进行这些检查。
在此设置下,数据可用性采样方案有两个协议:
(我们在下面讨论的方法可能会减少重建所需的元素数量。)
要求是,如果采样验证者输出 success,那么重建代理将输出区块 B,前提是它接收了超过四分之三的元素作为输入。只要提供足够的元素,重建就应该成功,即使提供的元素是通过对抗性选择的。
回顾一下,参与 danksharding 的相关方包括:
我们接下来解释该方案的两个构建模块:纠删编码和多项式承诺。
纠删编码可以追溯到20世纪60年代,其动机是需要通过丢包信道传输信息。它在 danksharding 中用于防止验证者丢失数据片段。这项技术将数据从 N 个元素扩展到 M 个元素 ( M > N),使得可以从扩展数据的 任何 N 个完整的 M 元素重建原始数据。想象一下取 N 个元素(原始数据)、将它们编码成 M = 2 N 个元素,并将一个编码后的元素分配给每一个 2 N 的验证者。如果大多数验证者是诚实的,他们总可以联合重建原始数据。这项技术对任意一半的验证者的崩溃故障提供保护。借助接下来的多项式承诺,可以扩展这一保护,抵御一半验证者的拜占庭行为。
下面更详细地解释扩展是如何工作的。要将数据从 N 字段元素 d 1, d 2, . . . , dN ∈ 𝔽 p 扩展为 M 个编码元素 e 1, e 2, . . . , eM ∈ 𝔽 p,我们插值一个满足 p(i) = di ( i = 1, . . . , N) 的独特度数为 N– 1 的多项式 p(x)。然后在 M 个点上评估该多项式:ei = ( i, p( i)),对于 i = 1,. . . , M。使用拉格朗日插值法,可以从 M 个编码元素中的任意 N 个重建原始多项式 p( x)。这种扩展方法被称为 Reed-Solomon 编码 或 低度多项式扩展。
多项式承诺是 DAS 方案的一个基本构建块。它允许该方案进行两项操作:
更严谨地说,给定 x,y ∈ 𝔽 p,承诺者可以创建一个短证明 π,证明承诺的多项式 p 满足 p( x) = y 且其度数不超过 D。证明 π 将针对承诺字符串 C 和数值 x, y 进行验证。这个 π 被称为 评估证明。
安全性保障承诺对多项式是绑定的,并且对手无法创建虚假证明。
这里可以用多种实用的多项式承诺方案。Danksharding 使用 KZG 承诺方案,该方案需要一个 可信设置仪式 生成公共参数(称为一个 SRS),但具有常量大小的承诺和常量大小的评估证明。KZG 承诺具有许多属性,使其特别适合于 danksharding:
现在我们可以解释客户如何对其数据 blob 进行承诺。首先,客户将数据 blob 解释为由 m 字段元素 d 1, . . . , dm ∈ 𝔽p 组成的向量,其中 m ≤ 4096。接下来,它插值一个有限度的单变量多项式 p ∈ 𝔽p[ X],其度数最多为 m– 1,使得 p( i) = di ( i = 1, . . . , m)。 (从技术上来说,danksharding 使用 1, ω, ω2, . . . , ωm-1 ∈ 𝔽p 作为评估点,其中 ω ∈ 𝔽 p 是 m 次单位根,并采用 反位顺序;这一做法是为了提高效率,但出于简化考虑我们在此不予考虑。)最后,客户构造对多项式 p 的 KZG 多项式承诺。它签署承诺并将承诺-签名对发送给构建者。该过程需要公共参数(一个 SRS),其中包含 4096 个元素。
接下来,我们解释区块构建者如何编码一个区块并将其分割为片段以发送给验证者。固定一个 256 位素数 p。区块构建者执行以下操作:
输入: 在 danksharding 中,一个区块 B 可以包含最多 256 个数据 blob(比 protodanksharding 多 64 倍),其中每个数据 blob 是在 𝔽p 中的 4096 个元素的向量。因此,我们可以将区块表示为一个 256 × 4096 的元素矩阵。在该矩阵的每一行对应于客户的数据 blob。回想一下,每个客户将其 B 的一行及该行的 KZG 多项式承诺一并发送给构建者。构建者收集 256 个签名的多项式承诺 C 0, . . . , C 255,每行一个承诺。
步骤 1: 构建者插值一个双变量多项式 d( X, Y),使得 d( i, j) = B[ i, j](对于 i = 0, . . . , 255 和 j = 0, . . . , 4095)。这个双变量多项式在 X 的最大度数为 255,在 Y 的最大度数为 4095。
步骤 2: 构建者使用上述纠删编码方法在每个方向上将区块扩展两倍。即通过设置 E[ i, j] ← d( i, j) 形成一个 512 × 8192 的字段元素矩阵 E,其中 i = 0, . . . , 511 和 j = 0, . . . , 8191。下图说明了这一过程。
步骤 3: 构建者验证每个签名的 C i 是否是单变量多项式 d i( Y) := d( i, Y) 的 KZG 承诺,适用于所有 i = 0, . . . , 255。请注意,多项式 d i( Y) 是 B 的第 i 行的插值,因此必须与客户 i 提交的多项式相同。构建者会拒绝所有 C i 形态不正确的数据 blob。
现在构建者将 C = ( C 0, . . . , C 255) 作为对区块 B 或更准确地说,对双变量多项式 d( X, Y) 的承诺。
让我们展示 C = ( C 0, . . . , C 255) 确实是对多项式 d( X, Y) 的多项式承诺。对于某给定的 x, y, z ∈ 𝔽p,我们构建一个评估证明,该证明让验证者相信 d( x, y) = z,并报告承诺 C。因为 d( X, Y) 中的 X 的最大度数为 255,因此有常数 λ0, . . . , λ255 ∈ 𝔽p,这些常数仅依赖于 x,使得
d( x, Y) = λ0 · d(0, Y) + . . . + λ255 · d(255, Y)。
然后,基于 KZG 承诺的同态属性,得出:
Cx := λ0 · C 0 + . . . + λ255 · C 255
是单变量多项式 d x( Y) := d( x, Y) 的 KZG 承诺。因此,验证者可以自行从 C 中构建 Cx。设 π 为多项式 d x( Y) 的 KZG 评估证明,证明 d x( y) = z 是针对承诺 Cx 得到的。这个 π 就是针对在点 ( x, y) 上的 d( X, Y) 的所需评估证明。
这一论证表明 C 是多项式 d( X, Y) 的承诺。值得注意的是,虽然每个客户独立地签署 B 的一行,但所有客户签名的集合充当对多项式承诺 d( X, Y) 的签名。
步骤 4: 在这个 DAS 方案中,通信的最小单位是一个 样本,即一个 16 元素的行向量。元素矩阵 E 的 512 × 8192 被看作 512 × 512 的方阵样本。设 V 为验证者的数量。那么,块构建者将矩阵 E 划分成 V 个重叠片段 P 1, . . . , PV,其中 Pi 恰好包含 E 行和列中随机选择的两个行和两列的样本。因此, Pi 包含 2 × 512 × 16 + 2 × 8192 = 9216 个字段元素,位于 𝔽 p 中。这远小于完整区块 B,后者约有一百万个字段元素。以太坊中的验证者最少是 128 个(当前大约为 ~500,000),因此存在足够的验证者,以确保整个区块有充分覆盖。
步骤 5: 区块构建者将三元组 ( Pi, C, π i) 发送给验证者编号 i,其中 π i 是 Pi 中所有元素的评估证明列表:每个 Pi 的两个行和两个列中的每个单元格 d( x, y) 的一个证明。 π i 中的证明使验证者能够验证 Pi 中每个字段元素与承诺 C 的一致性。
在 danksharding 中,验证者的数量可以大大超过区块中的列或行的数量。因此,某些列和行可能由多个验证者存储。如此一来,danksharding 使用了复本和 Reed-Solomon 纠删编码来确保数据可以被重建。
当重建代理需要重建整个区块时,它拥有 C,并请求验证者集合发送其片段。作为回应,诚实的验证者 i 发送 ( Pi, π i)。重建代理检查 π i 中的开证明,如果有效,则接受 Pi 中的值。因此,拜占庭验证者无法发送虚假的数据。然而,拜占庭验证者可能拒绝发送数据并不回应重建代理。
当某些数据缺失时,danksharding 需要至少 75% 的矩阵 E 来重建区块。由于验证者仅存储完整的行和列,最坏的情况是如下场景,其中区块的 75% – ε 元素存在,但无法重建缺失的元素。
看为何数据在此情况下无法被重建,观察会发现存在一个非零双变量多项式 δ( X, Y),在整个“存在”区域上评估为零,并且对 X 和 Y 有必要的度数界限。因此,在重建期间无法确定缺失的空白区域是来自正确的多项式 d( X, Y) 还是多项式 d( X, Y) + δ( X, Y);这两个多项式在现有数据上是一致的。因此,当缺失数据遵循这种模式(不考虑行和列的排列)时,其缺失数据无法被重建。注意,如果验证者丢失其部分数据,进而变为“拜占庭”,它会丢失所有数据,包括所有行和所有列。
因此,最坏情况下区块有不足 75% 不能提供。经过当存在 75% 或更多区块时,重建可以通过简单贪婪算法确保成功。
重建算法:重建通过逐步寻找一行(或一列)中至少 50% 的可用元素,并通过单变量插值来重建该行(或列)的缺失元素。要理解为何该程序最终能够重建整个区块,该设想前提是没有找到可重建的行或列,即该行或列的所有元素都小于 50%,或全部都有(100% 的可用元素)。让我们选择任何不完整的行,它有超过 50% 的不可用元素,通过那些元素的列也必须有超过 50% 的不可用元素,这立即意味着区块的不止 25% 的不可用,这是对最初假设的反驳。
要使一个区块不可重构,攻击者需要进攻至少 15/16 的验证者集合。在这种情况下,攻击者将选择一个象限进行删除,并攻击在该象限中至少有一行或一列的验证者。
假设诚实的验证者 i 崩溃并丢失其数据。重新上线后,它希望重建其两个行和两列 Pi 以及开证明 π i。Danksharding 使得验证者无需重建整个区块即可完成重建。验证者可以从另一个存储完全相同数据点的验证者那里下载其数据,或通过从其他验证者中获取其行(或列)的 50% 元素,并通过单变量插值重建该行的其余部分。这一过程不需要进行完整的重建。
例如,假设一个验证者存储了至少 50% 的第 42 列,但少于 100%,现在它需要重建缺失的元素。也就是说,该验证者持有对所有 i ∈ S 的 ( E( i,42), πi) ∈ (𝔽, 𝔾),其中 S 为一个集合,256 ≤ | S | < 512。为重建缺失的对,验证者执行以下操作:
步骤 3 利用了 KZG 多项式承诺的 同态证明 特性。据我们所知,KZG 是唯一具备这一特性的多项式承诺方案。
为了确定扩展的区块 E 是否可用于重建原始区块 B,采样客户端会查询 E 的随机样本。作为对每次查询的回应,它会获得一个样本(16 元素的行向量)和一个评估证明以检查该样本与承诺 C 的一致性。如果所有查询都成功回应,客户端即可接受数据为可用。如果客户端总共进行 Q 次查询,则它错误地接受不可用数据的概率为 (3/4)Q,此概率会随着查询次数 Q 的增加而迅速下降。3/4 的比率对应于上一节中的 75% 重建阈值。
在以太坊网络中,采样将由三种类型的参与方完成: (i) 无法全额存储 blob 数据的全节点, (ii) 轻客户端,以及 (iii) 验证者本身。验证者必须在对区块及其前身投票之前验证该数据可用。每个时期都有一个固定的验证者集合,这些验证者将随机分为 32 个委员会。每个委员会分配一个 12 秒的时间片(每个时期有 32 个时间片)。每个时间片预计确认一个区块。每个验证者接收各个区块的片段(2 行和 2 列的样本),即使对于那些验证者不在见证委员会中时的区块。此外,每个验证者还对当前区块及所有以前的区块进行采样,以确保在根据分叉选择规则选择要见证的区块之前,所有区块都是有效的并且可用。
该协议保证数据在 32 个时间片的周期可用,即可用 6 分钟。其他方法如可检索性证明或 激励机制 有助于确保数据可以更长时间内可用,例如,在数据过期之前, blob 应该可用 30-60 天。
在本节中,我们将解释如何在仅有 25% 数据可用时进行重建成功(相比于前面所述当前 danksharding 的 75%)。
当可用点的比例低于 75% 时,贪婪的列向和行向单变量插值可能会失败。相反,我们建议直接通过双变量多项式插值进行重建。在这种情况下,即使只有 25% 的 E 点可用,也可以实现完整的重建。然而,这要求对片段分配给验证者的方式进行小的修改。不再给每个验证者分配两个完整的行和两完整的列样本,而是建议每个验证者存储:
每个验证者的总体存储需求没有变化,但现在即使低于 75% 样本可用时,仍可实现重建。此外,多个验证者存储相同的数据点集,因此,如果任何一个验证者需要重建其片段,它可以从存储相同片段的任何其他验证者那里请求。如果没有此类可用的验证者,则可以进行局部或完整重建以获取其片段。
该混合提议允许在拜占庭验证者很少的情况下轻松重建样本在 75% 以上的情况。在不幸的情况下,当拜占庭验证者过多时,可以利用全双变量插值在 25% 样本的情况下重建数据,这得益于样本在矩阵 E 中的随机分散。
双变量插值可以通过求解多项式的系数的线性方程组简单地实现。这个简单的方法需要构建一个 220 × 220 字段元素(32TB)的插值矩阵。这非常大,但还不是不可行。不过,可以使用更好的方法。(例如,参见 P.J.Olver-2016 的综述。)虽然双变量插值的成本不容小觑,但它仅在恢复点的比例低于 75% 时才需要,并可视为一种安全措施。要实现这一安全措施,danksharding 需要进行轻微修改,以上述分配片段的方式为验证者分配片段。
前面构造的主要缺点是 KZG 多项式承诺方案所需的可信设置。否则,该方案会非常快速。然而,可信设置通常需要付出大量的工作和协调。 (我们关于 链上 KZG 设置的工作 可以帮助简化未来项目的仪式)。一些其他多项式承诺方案不需要可信设置(例如, Bulletproofs),尽管它们没有在验证者重建所需的高效性之情况下所需的同态证明(正如 Vitalik 提到的)。
然而,可以修改构造以避免需要同态证明,并仍然保持轻量级验证者。高层次的构思是让区块构建者计算承诺到区块矩阵 E 的列。通过这种方式,验证者不需要重建列证明;它们将简单地完全重建其列,并从头开始重新计算相对于列承诺的证明。通过共识,验证者将确保他们在相同的列承诺上达成一致。
更精确地说,步骤 1-4 与上文中解释的 danksharding 相同。然而,步骤 5 是不同的。
步骤 5: 区块构建者计算对 B 列的多项式承诺:用 T = ( T 0, T 1, . . . , T 4095) 表示,每个 Tj 是对 d( X, j) 的承诺(具体来说,它可以是对 d( X, j) 系数向量的 Pedersen 向量承诺)。然后,它创建证明 C 和 T 承诺对相同的矩阵,如下所示。区块的构建者选择一个(伪)随机点 ( x̂, ŷ),利用承诺的同态性插值并计算列承诺 T ŷ 对单变量多项式 d( X, ŷ),以及对单变量多项式 d( x̂, Y) 创建行承诺 C x̂,并创建两个证明: πx̂ —— 多项式评估证明 d( x̂, ŷ) 相对于 C x̂, 以及 πŷ —— 多项式评估证明 d( x̂, ŷ) 相对于 T ŷ。点 ( x̂, ŷ) 对所有验证者都是通用的,可以从随机信标输出或通过 Fiat-Shamir 变换伪随机生成。然后,区块的构建者向验证者编号 i 发送 ( P i, C, T, πx̂, πŷ, d( x̂, ŷ)),其中 Pi 是 E 的两行和两列。构建者在此构造中不计算证明。
验证者验证证明 πx̂,πŷ 以防止恶意区块构建者生成不正确的列承诺 T。然后,验证者再次承诺来自 P i 的两行和两列,并验证与 C 和 T 中的对应元素是否匹配。如果 P i 中的行 x 在原始矩阵 B 的范围内,例如 x ∈ {0..255},验证者仅需验证承诺是否与 C 中的对应元素 C x 匹配;然而,如果行在扩展部分: x ∈ 256..511,验证者首先需要通过对 C 中的承诺插值来获得 C x:
Cx := λ0 · C 0 + . . . + λ255 · C 255
请注意,正因为 IPA 承诺(但不是其证明)是同态的,所以可以进行插值。验证者以类似的方式验证 Pi 的列相对于 T 是否符合需求的方式。
在这个构造中,区块的构建者无需为验证者计算证明。验证者可以自行计算所有证明。但这仍然是一个有趣的研究问题,找出如何高效地一次计算大量证明的算法(类似于 KZG 的实现,或使用 Vitalik 对 IPA 的想法)。
我们认为这种方法的主要瓶颈在于对采样客户端的效率损失,因为基于 IPA 的证明大小是对数级别的(相对于 KZG 为常量级别)。此外,采样客户端可能需要下载列承诺,连同行承诺,从而增加通信的开销。然而,我们认为这是进一步探索的一个有前景的方向。
Vitalik 最近探讨的另一种可行的方法是 避免可信设置,即使用 Merkle 承诺而不是多项式承诺。Merkle 承诺并不是多项式承诺方案,因此在与纠删编码配合工作时更具挑战。区块的构建者将对数据进行纠删编码,并将对扩展数据承诺 Merkle 树的根。主要的挑战是如何在不下载完整数据的情况下,识别不正确扩展的数据。欺诈证明可以用于绕过这个问题,但是这依赖于存在一个客户端,其会下载完整数据,检查其是否被正确地进行纠删编码和承诺,并在不这样做时发出警告,提供欺诈证明。
或者,可以使用 FRI 证明来检查 Merkle 树的叶子是否接近 Reed-Solomon 码字(即检查 Merkle 承诺下的基础数据是否被正确地进行了纠删编码)。采样客户端将检查 FRI 证明,并通过请求其 Merkle 证明来采样足够比例的叶子,以确保数据可用并且可以被重建。
\\*\
数据可用性采样,以及作为其具体实例之一的 danksharding,将降低数据存储的成本,从而导致更具可扩展性和更便宜的区块链。DAS 的编码方面是一个潜在的丰富研究领域,有许多可能的方向可供探索。我们建议了一条可能的途径:改进重建协议以减少所需样本(25% 代替 75%)。另一个值得兴奋的方向是探索不需要可信设置的替代承诺方案。
\\*\
Protodanksharding
以太坊及 danksharding 的 DAS- 在 Devcon 上的 Danksharding 研讨会: Youtube (2022年10月14日)
关于 DAS 的研究
KZG 承诺
\\*\
感谢 Ansgar Dietrichs 提供的许多深刻的评论,这些评论为本文提供了参考。
\\*\
Valeria Nikolaenko 是 a16z crypto 的研究合伙人。她的研究重点是密码学和区块链安全。她还研究了许多主题,包括 PoS 共识协议中的长程攻击、签名方案、后量子安全和多方计算。她在斯坦福大学获得密码学博士学位,导师是 Dan Boneh 教授,并作为核心研究团队的一部分参与了 Diem 区块链的研究。
Dan Boneh 领导斯坦福大学应用密码学组,并联合管理计算机安全实验室。Dan 的研究集中在密码学在计算机安全中的应用,包括具有新型属性的密码系统、网络安全、移动设备安全和密码分析。他发表了超过一百篇论文,并荣获 2014 年 ACM 奖、2013 年戈德尔奖和 2011 年石井企业教育创新奖。
\\*\
此外,本材料仅用于提供信息,任何投资决策不应依赖于此。过去的表现并不能说明未来的结果。投资于池投资工具和/或数字资产包含许多未在此充分讨论的风险,包括但不限于重大波动性、流动性、技术和监管风险。内容仅代表所指日期的观点。材料中表达的任何预测、估计、预测、目标、前景和/或意见均可能在不通知的情况下发生变化,并可能与其他人表达的意见不同或相悖。有关其他重要信息,请参阅 https://a16z.com/disclosures。
- 原文链接: a16zcrypto.com/posts/art...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!