ERC-8042 Diamond Storage:用一句可读标识符给合约算出一个存储位置 图 1
ERC-8042 Diamond Storage:用一句可读标识符给合约算出一个存储位置 · 图 1

ERC-8042 Diamond Storage:用一句可读标识符给合约算出一个存储位置

升级合约时最怕的不是逻辑写错,而是新旧代码把数据写进同一块存储、互相踩踏。钻石存储的解法是给每个模块的结构体挑一个几乎不可能撞车的存储槽,起点就是一个由哈希产生的巨数。ERC-8042 提出一种极简定位公式:对一句人类可读的标识符(例如 myproject.erc721.registry)直接计算 keccak256(id),把结果当存储基准位置。按照以太坊 ercs 仓库的记录,这份提案名为 Diamond Storage,作者正是 ERC-7201 的作者 Nick Mudge,状态为 Final,创建于 2025 年 10 月 11 日。

两种公式摆在一起看

ERC-7201 的定位公式形如 keccak256(abi.encode(uint256(keccak256(bytes(namespace id))) - 1)) & ~bytes32(uint256(0xff)):先哈希命名空间、减一、再哈希一次、最后把末字节清零。每一段都有用途——减一再哈希保证输入不会与 Solidity 内置类型(映射、动态数组)的定位算法重合;清零末字节则让结构体首槽前的空隙能安全存放版本号。ERC-8042 的公式只有一步 keccak256(id),任何人都能对着字符串当场复算出位置,不需要理解每一段为什么存在。

ERC-8042 Diamond Storage:用一句可读标识符给合约算出一个存储位置 图 2
ERC-8042 Diamond Storage:用一句可读标识符给合约算出一个存储位置 · 图 2

简单公式的代价要靠输入规则补

一步哈希把防碰撞的责任从公式转嫁到标识符本身。提案为此给出输入限制:标识符必须使用纯 ASCII 字符,避开 Unicode 变体带来的两个字符串视觉相同、字节不同的隐性碰撞;同一项目内的标识符要带项目前缀,像文件路径那样分层(myproject.module.name),使不同项目即使起了同名也不会重叠。审计工具因此可以扫描全部源码里的 @custom:storage-location erc8042: 注解,检查前缀规范与字符集,把碰撞风险变成一次静态检查就能回答的问题。

NatSpec 注解是这套标准的用户界面

ERC-8042 规定注解写法为 @custom:storage-location erc8042:<NAMESPACE_ID>,其中 erc8042 是公式标识,冒号后是命名空间。这条约定的意义在于机器可读:ERC-7201 生态定义了公式标识的识别方式,工具看到公式标识就知道用哪条公式复算位置。两个标准可以共存——同一个代码库里,有的结构用 ERC-7201 定位、有的用 ERC-8042 定位,只要公式标识写对,存储分析工具都能还原每个结构体的真实槽位。对读代码的人来说,注解比代码里的哈希常量更难伪造,因为常量可以随手改成任意值,而注解与公式的对应关系会被工具复算揭穿。

什么人需要关心这个标准

动手复算一次定位

两个标准都不难验证,工具链也很短。取项目源码里任意一个带注解的存储结构,拿到命名空间字符串,用任意 keccak256 工具计算哈希——对 ERC-8042 就是直接对字符串取哈希,对 ERC-7201 则按公式多走几步——再对照 Solidity 编译产物 storageLayout 里该结构体字段的实际槽位是否等于该值(或其起始偏移)。对不上的项目要么注解与代码脱节,要么压根没用注册公式,两种情况都提示存储布局管理松弛。另一个免费信号是看同一合约里各模块的结构体定位是否共享前缀风格:东拼西凑的哈希常量与整齐的命名空间体系,往往对应着两种不同的工程纪律。审计报告的存储布局一节是否逐项列出定位公式,也是判断审计深度的线索——只写结论不写槽位的布局审计,等于没审。

直接受益的是可升级合约的用户:验证一个钻石代理或 UUPS 合约升级后数据会不会错位,本质上就是核对每个模块的结构体定位是否用了注册过的公式、注释与实现是否一致。如果你只持有不可升级合约铸造的资产,这个标准离你较远,但它解释了一个常见现象——为什么审计报告专门有一节讲存储布局,以及为什么有些合约升级事故会表现为代币余额凭空错乱。按 ercs 仓库口径该提案为 Final;Final 是规范状态,不代表某个具体项目已经采用,看项目源码里的注解才是判据。本文为机制说明,不构成任何投资建议。