ERC-6066:用一枚 NFT 签字,isValidSignature 验的是哪件事 图 1
ERC-6066:用一枚 NFT 签字,isValidSignature 验的是哪件事 · 图 1

ERC-6066:用一枚 NFT 签字,isValidSignature 验的是哪件事

签名验证的世界有条清晰分工:外部账户用 ecrecover 验私钥签名,智能合约按 ERC-1271 自报“这签名我认不认”。ERC-6066 想补上第三个问题:如果签名主体不是地址、也不是合约,而是一枚具体的 NFT 呢?这份在 ethereum/ERCs 仓库里状态为 Final 的提案(2022 年 11 月创建)给出的答案出人意料地小——一个函数。

一个函数与一个魔术值

接口 IERC6066 只要求实现 isValidSignature(uint256 tokenId, bytes32 hash, bytes calldata data):给定签名 NFT 的 tokenId、消息哈希和可选辅助数据,验证通过必须返回字节数 0x12edb34f,失败返回 0xffffffff;函数要求不可修改状态、必须允许外部调用,且可以调用任意方法来完成验证。ERC-721 或 ERC-1155 合约都可以实现它,让持有者用自己的藏品“签名”;调用方若要支持合约类签名,对 NFT 持有人必须改走这个函数。第三个参数是为未来留的门,符合 ERC-5750 的多余数据思路。

ERC-6066:用一枚 NFT 签字,isValidSignature 验的是哪件事 图 2
ERC-6066:用一枚 NFT 签字,isValidSignature 验的是哪件事 · 图 2

“布尔式签名”到底安全在哪

参考实现揭示了它的本性:合约里存一张 _signatures[tokenId][hash] 的布尔映射,持有人调用 sign 把某个哈希标记为真,验证时查表返回魔术值。这和 Gnosis Safe 的合约签名逻辑同源——验的不是密码学曲线,而是“合约状态里是否记录过这枚代币对该哈希的同意”。标准明确放弃了对签名生成方式的统一:怎么产生这个“同意”,由各合约自定。这也带来核对义务:调用方确认的是该 NFT 合约内部登记过意愿,前提是你信任这个合约的实现没有被管理员随意改写登记状态。

什么场景值得用

和 ERC-1271、EIP-1271 家谱的关系

把 ERC-6066 放回签名家族的谱系里更好理解。第一层是外部账户:钱包用私钥签 personal_sign,合约用 ecrecover 对照地址,前提是签名者恒为一个地址。第二层是 ERC-1271:智能合约账户对哈希“表态”,验证方调用合约的 isValidSignature(bytes32,bytes),魔术值 0x1626ba7e 代表合约认可,表态主体是一个合约。第三层才是 6066:表态可以精确到合约内部的某一枚代币,签名槽位从“合约级”下沉到“tokenId 级”,魔术值换成 0x12edb34f 以免与 1271 混淆。这样做的现实收益是问责粒度:多成员共用的 NFT 金库合约里,一枚治理凭证的同意与另一枚的同意可以分开追溯;DAO 金库常由 Safe 这类合约管理,6066 让“某凭证持有者已确认”成为可查询事实而不是网页截图。代价也要摊开:布尔登记意味着链上只有“同意过某哈希”这一个事实,消息原文、同意时间、谁触发的登记都依赖实现层补事件,调用方务必要求展示端还原完整上下文再落签。

一枚 NFT 签名前的核对清单

若你手里有支持 6066 的藏品并准备签署某段哈希:第一步,把哈希还原成原始消息,用支持 EIP-712 的解析器读出字段,拒绝只给你一串十六进制的请求。第二步,确认调用对象地址就是该 NFT 的合约地址,钓鱼合约会伪装同样的接口名。第三步,查这次登记是否有过期机制——布尔登记若永不过期,你等于永久背书了这段文本,未来转手代币时新持有人会继承这份“签名历史”。第四步,留一份链上交易哈希作凭证。四步走完再点确认,这份标准的便利才真正落在你这边而不是对手那边。

社群里最常被举的例子是“以持币人资格签署”:链上问卷、需要某系列成员署名的提案、用稀有藏品充当的会签凭证。对读者而言的核实路径有三步:用 ERC-165 探测合约是否声明支持 ERC-6066;调用 isValidSignature 复现验证而不是看展示页的绿勾;查清登记签名的那条链上路径是否需要额外权限。要划清边界:它证明“该合约记录这枚代币同意过这段哈希”,不能证明持有人的私钥此刻参与了签名,也不能证明消息内容在展示层没有被断章取义。签之前永远先还原 hash 对应的原文。本文只讨论机制,不构成投资建议或安全承诺。