这篇文章深入探讨了以太坊的扩展性问题,重点介绍了PeerDAS (EIP-7594)方案,它是以太坊实现数据可用性抽样(DAS)的第一个实践版本,旨在解决rollup在数据可用性方面的瓶颈。文章详细解释了PeerDAS的技术机制,包括数据结构、KZG承诺、网络交互和抽样策略,并分析了它对L2扩展性、网络效率和去中心化的影响。
The Surge(巨浪):专注于大规模提高可扩展性,主要通过 Layer 2 rollups 和数据分片/可用性技术,目标是每秒 100,000+ 笔交易 (TPS)。

The Surge, 2023 年路线图版本 (作者: Vitalik Buterin)
随着以太坊朝着其以 rollup 为中心的扩展路线图 发展 (由 Vitalik Buterin 提出),旨在解决 “ 可扩展性三难困境 ” — 平衡 可扩展性、安全性 和 去中心化。Pectra 和 PeerDAS 代表着实现 The Surge(巨浪) 目标的下一个合乎逻辑且至关重要的步骤。EIP-4844 为 L2 数据 (blobs) 创建了空间,但其容量受到所有节点都需要下载所有内容的限制。
PeerDAS (EIP-7594) 通过引入 DAS 释放了该空间的可扩展性,打破了将总数据吞吐量与单个节点容量联系起来的约束。通过允许节点通过抽样验证可用性,PeerDAS 使网络能够安全地增加每个区块的 blob 数量,直接履行了 Surge 为 L2 rollups 提供廉价且充足的数据可用性的承诺。
虽然 DAS 的核心思想 (深入文章) 提供了理论,但 以太坊的第一个实用版本 称为 PeerDAS,在 EIP-7594 中定义,并随 Fulu 升级一起发布。](https://ethereum.org/en/roadmap/danksharding/)(这将涉及更高级的 2D erasure coding)。
PeerDAS 引入了处理数据,网络和抽样的特定技术:
[NUMBER\_OF\_COLUMNS](https://github.com/ethereum/consensus-specs/blob/8f8ab03acf1656c54f3a81ef18878f853a1cc4c6/specs/_features/eip7594/das-core.md#data-size) 控制的每个 blob 64 个原始单元格扩展到 128 个编码单元格)。M 个 blobs,并且每个 blob 扩展到 N 个单元格(N = [NUMBER\_OF\_COLUMNS](https://github.com/ethereum/consensus-specs/blob/8f8ab03acf1656c54f3a81ef18878f853a1cc4c6/specs/_features/eip7594/das-core.md#data-size)),则矩阵的维度为 M x N。
consensus-specs/specs/fulu/das-core.md at dev · ethereum/consensus-specs
def compute_matrix(blobs: Sequence[Blob]) -> Sequence[MatrixEntry]:
    """
    返回完整的,扁平化的矩阵条目序列。
    此帮助程序演示了 blobs 和单元格/证明矩阵之间的关系。
    用于存储单元格/证明的数据结构取决于实现。
    """
    matrix = []
    for blob_index, blob in enumerate(blobs):
        cells, proofs = compute_cells_and_kzg_proofs(blob)
        for cell_index, (cell, proof) in enumerate(zip(cells, proofs)):
            matrix.append(MatrixEntry(
                cell=cell,
                kzg_proof=proof,
                row_index=blob_index,
                column_index=cell_index,
            ))
    return matrix
N 个 单元格(可以通过 KZG 证明验证的最小单元,通常每个单元格约 2KB)。列 (索引 j) 由区块中每个 M 个扩展 blobs 中的 j-th 单元格组成。列数通常与每个扩展 blob 的单元格数匹配(例如,128 列)。consensus-specs/specs/fulu/polynomial-commitments-sampling.md at dev · ethereum/consensus-specs
def compute_cells(blob: Blob) -> Vector[Cell, CELLS_PER_EXT_BLOB]:
    """
    给定一个 blob,扩展它并返回扩展 blob 的所有单元格。
    公共方法。
    """
    assert len(blob) == BYTES_PER_BLOB
    polynomial = blob_to_polynomial(blob)
    polynomial_coeff = polynomial_eval_to_coeff(polynomial)
    cells = []
    for i in range(CELLS_PER_EXT_BLOB):
        coset = coset_for_cell(CellIndex(i))
        ys = CosetEvals([evaluate_polynomialcoeff(polynomial_coeff, z) for z in coset])
        cells.append(coset_evals_to_cell(CosetEvals(ys)))
    return cells
PeerDAS 利用 KZG 承诺进行验证。每个 blob(行)都有自己的 KZG 承诺,这已经是 EIP-4844 结构的一部分。验证列中的单元格涉及根据其所属的特定 blob(行)的承诺检查其 KZG 证明。
consensus-specs/specs/fulu/polynomial-commitments-sampling.md at dev · ethereum/consensus-specs
def verify_cell_kzg_proof_batch(commitments_bytes: Sequence[Bytes48],
                                cell_indices: Sequence[CellIndex],
                                cells: Sequence[Cell],
                                proofs_bytes: Sequence[Bytes48]) -> bool:
    """
    验证一组单元格是否属于其对应的承诺。
    给定四个列表,表示 (``承诺``, ``单元格索引``, ``单元格``, ``证明``) 的元组,
    该函数验证 ``证明``,该证明表明 ``单元格`` 是与 ``承诺`` 关联的多项式的评估,
    在由 ``单元格索引`` 指定的域上进行评估。
    此函数实现了此处介绍的通用验证公式:
    https://ethresear.ch/t/a-universal-verification-equation-for-data-availability-sampling/13240
    公共方法。
    """
    assert len(commitments_bytes) == len(cells) == len(proofs_bytes) == len(cell_indices)
    for commitment_bytes in commitments_bytes:
        assert len(commitment_bytes) == BYTES_PER_COMMITMENT
    for cell_index in cell_indices:
        assert cell_index < CELLS_PER_EXT_BLOB
    for cell in cells:
        assert len(cell) == BYTES_PER_CELL
    for proof_bytes in proofs_bytes:
        assert len(proof_bytes) == BYTES_PER_PROOF
    # 创建我们正在处理的去重承诺列表
    deduplicated_commitments = [bytes_to_kzg_commitment(commitment_bytes)\
                                for commitment_bytes in set(commitments_bytes)]
    # 创建索引列表,将初始承诺(可能包含重复项)映射到去重承诺
    commitment_indices = [CommitmentIndex(deduplicated_commitments.index(commitment_bytes))\
                          for commitment_bytes in commitments_bytes]
    cosets_evals = [cell_to_coset_evals(cell) for cell in cells]
    proofs = [bytes_to_kzg_proof(proof_bytes) for proof_bytes in proofs_bytes]
    # 进行实际验证
    return verify_cell_kzg_proof_batch_impl(
        deduplicated_commitments,
        commitment_indices,
        cell_indices,
        cosets_evals,
        proofs)
consensus-specs/specs/fulu/das-core.md at dev · ethereum/consensus-specs
def get_custody_groups(node_id: NodeID, custody_group_count: uint64) -> Sequence[CustodyIndex]:
    assert custody_group_count <= NUMBER_OF_CUSTODY_GROUPS
    current_id = uint256(node_id)
    custody_groups: List[CustodyIndex] = []
    while len(custody_groups) < custody_group_count:
        custody_group = CustodyIndex(
            bytes_to_uint64(hash(uint_to_bytes(current_id))[0:8])
            % NUMBER_OF_CUSTODY_GROUPS
        )
        if custody_group not in custody_groups:
            custody_groups.append(custody_group)
        if current_id == UINT256_MAX:
            # 防止溢出
            current_id = uint256(0)
        else:
            current_id += 1
    assert len(custody_groups) == len(set(custody_groups))
    return sorted(custody_groups)
[CUSTODY\_REQUIREMENT](https://github.com/ethereum/consensus-specs/blob/8f8ab03acf1656c54f3a81ef18878f853a1cc4c6/specs/_features/eip7594/das-core.md#custody-setting) 参数定义了每个节点必须下载、验证和临时存储的 不同列数。示例:如果 [CUSTODY\_REQUIREMENT](https://github.com/ethereum/consensus-specs/blob/8f8ab03acf1656c54f3a81ef18878f853a1cc4c6/specs/_features/eip7594/das-core.md#custody-setting) = 8,则节点负责 128 列中的 8 列。由于保管分配是确定性的(使用节点的唯一 ID 和区块的元数据),因此需要列 j 的节点可以有效地找到负责列 j 的潜在对等点。
j 进行抽样的节点可以识别出其节点 ID 将它们映射到保管子网 j 的潜在对等点。网络模拟表明,节点可能只需要与相对少量的不同对等点(例如,< 50,取决于参数)保持连接,以确保覆盖所有必需的子网。每个节点必须 成功地在每个Slot抽样一定数量的不同列。此数字由 SAMPLES_PER_SLOT 参数定义。
示例:如果 SAMPLES_PER_SLOT = 40,则节点在给定Slot中抽样 40 个不同的列。
子网抽样(初始):节点订阅为其分配的列的 gossip 主题(效率较低)。
对等点抽样(目标):节点使用直接 RPC 从负责这些列的对等点处请求特定列(效率更高)。
验证:节点根据相应 blob 的 KZG 承诺检查每个抽样的单元格。
consensus-specs/specs/fulu/p2p-interface.md at dev · ethereum/consensus-specs
def verify_data_column_sidecar_kzg_proofs(sidecar: DataColumnSidecar) -> bool:
    """
    验证 KZG 证明是否正确。
    """
    # 列索引也表示单元格索引
    cell_indices = [CellIndex(sidecar.index)] * len(sidecar.column)
    # 批量验证单元格是否与相应的承诺和证明匹配
    return verify_cell_kzg_proof_batch(
        commitments_bytes=sidecar.kzg_commitments,
        cell_indices=cell_indices,
        cells=sidecar.column,
        proofs_bytes=sidecar.kzg_proofs,
    )
数据重建: 由于 1D RS 编码(通常每个 blob 扩展2 倍),节点需要获取至少 50% _列_对应的数据,才能重建 整个 原始数据矩阵(所有原始 blobs)。如果节点需要完全重建但抽样比例小于 50%,则可以使用对等点发现机制从负责的对等点处请求缺少的列。
预计通过 Fulu 升级在 EIP-7594 中集成 PeerDAS 将带来几个关键好处:
对节点运营商的影响:
https://github.com/ethereum/EIPs/blob/master/EIPS/eip-7594.md
https://github.com/ethereum/consensus-specs/blob/dev/specs/fulu/das-core.md
Fraud and Data Availability Proofs: Maximising Light Client Security and Scaling Blockchains with Dishonest Majorities — arXiv, https://arxiv.org/abs/1809.09044
EIP-7594: PeerDAS — Peer Data Availability Sampling — Ethereum Magicians, https://ethereum-magicians.org/t/eip-7594-peerdas-peer-data-availability-sampling/18215
http://vitalik.eth.limo/general/2024/10/17/futures2.html
https://hackmd.io/@manunalepa/r1H8CtZlR#The-novel-PeerDAS-approach-Fulu
- 原文链接: medium.com/@Krieger69/un...
 - 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
 
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!