Alert Source Discuss
🚧 Stagnant Standards Track: Core

EIP-7650: 可编程访问列表

添加一个预编译合约,以编程方式添加访问列表

Authors Qi Zhou (@qizhou), Zhiqiang Xu (@zhiqiangxu)
Created 2024-03-10
Discussion Link https://ethereum-magicians.org/t/eip-7650-programmable-access-lists/19159
Requires EIP-2929, EIP-2930

摘要

我们引入了一个名为 prefetch 的新预编译合约,它接受一个 accessList

accessList 指定了一个地址和本地存储键的列表;这些地址和本地存储键被添加到 accessed_addressesaccessed_storage_keys 全局集合中 (在 EIP-2929 中引入)。与 EIP-2930 类似,通过此预编译预取数据会产生 gas 费用,但与在此列表之外进行的访问相比,费用有所降低。

动机

此 EIP 的主要目标是通过允许合约以编程方式添加访问列表来增强 EIP-2930。在合约中实现此预编译的优势在于,可以持续降低数据访问操作的 gas 成本,从而利用大多数节点都具有的并发计算和 IO。

规范

本文档中的关键字“必须”,“不得”,“必需”,“应”,“不应”,“建议”,“可以”和“可选”应按照 RFC 2119 中的描述进行解释。

参数

常量
FORK_BLOCK_NUMBER TBD
PREFETCH_PRECOMPILE_ADDRESS TBD
CONCURRENCY TBD

FORK_BLOCK_NUMBER 开始,一个新的预编译部署在 PREFETCH_PRECOMPILE_ADDRESS。预编译输入的编码如下:

[local storage key 长度 n 的 32 字节][n * 32 字节的本地存储键][地址长度 m 的 32 字节][m * 32 字节的地址]

在调用的开始,我们将收取 2100 * (N + CONCURRENCY - 1) // CONCURRENCY + 2600 * (M + CONCURRENCY - 1) // CONCURRENCY,其中 // 是整数除法运算符,N 是不在 accessed_storage_keys 全局集合中的本地存储键的数量,M 是不在 accessed_addresses 全局集合中的地址的数量。客户端应并发读取键和地址,并将键和地址放入 accessed_addressesaccessed_storage_keys 全局集合中。存储键和地址的以下读取成本符合 EIP-2929 中定义的 WARM_STORAGE_READ_COST

示例

以 UniswapV2 swap() 函数为例:

    // this low-level function should be called from a contract which performs important safety checks
    // 应该从执行重要安全检查的合约中调用此底层函数
    function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external lock {
        prefetch {
             token0.slot,
             token1.slot,
             reserve0.slot,
             price0CumulativeLast.slot,
             price1CumulativeLast.slot,
        } // add the storage keys `accessed_storage_keys`
        // 添加存储键 `accessed_storage_keys`
        prefetch {
             token0,
             token1,
        } // add the contracts of token0 and token1 to `accessed_addresses`
        // 将 token0 和 token1 的合约添加到 `accessed_addresses`
        ...
    }

原理

对访问列表中的访问收取较少的费用

与 EIP-2930 类似,我们鼓励合约开发者尽可能多地使用 prefetch 预编译,尤其是在假设节点具有某种不错的并发能力(例如,一些核心和 IO 带宽)的情况下。

允许重复项

与 EIP-2930 类似,我们允许列表中存在重复项,以最大限度地提高简单性。

没有外部合约的存储键

与 EIP-2930 不同,prefetch 预编译仅接受本地存储键和地址。预取外部合约的存储键的数据假定合约知道外部合约的存储布局,这可能不是一个好的做法。为了更好地利用节点的并发性,预编译可能会接受外部合约的一系列静态调用以及 calldata。这项工作可能会在未来的 EIP 中完成。

向后兼容性

如果尚未实现 EIP,则调用预编译的合约应不会导致任何操作。

安全注意事项

未发现任何安全注意事项。

版权

通过 CC0 放弃版权和相关权利。

Citation

Please cite this document as:

Qi Zhou (@qizhou), Zhiqiang Xu (@zhiqiangxu), "EIP-7650: 可编程访问列表 [DRAFT]," Ethereum Improvement Proposals, no. 7650, March 2024. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-7650.