ERC-5375: NFT 作者信息和授权许可
EIP-721 的一个扩展,用于 NFT 的作者身份和作者授权许可。
Authors | Samuele Marro (@samuelemarro), Luca Donno (@lucadonnoh) |
---|---|
Created | 2022-07-30 |
Requires | EIP-55, EIP-155, EIP-712, EIP-721, EIP-1155 |
Table of Contents
摘要
本 EIP 标准化了一种 JSON 格式,用于存储关于 NFT 作者的链下信息。具体来说,它增加了一个新字段,该字段提供了一个作者姓名、地址和 作者授权许可 证明的列表:证明作者已同意被署名为作者。请注意,作者授权许可的证明不是作者身份的证明:一个地址可以授权许可,而无需创作 NFT。
动机
目前没有标准来识别 NFT 的作者,并且现有技术存在问题:
- 使用 mint
tx.origin
或msg.sender
- 假定 mint 者和作者是同一个人
- 不支持多个作者
- 使用给定 ID 的第一个 Transfer 事件
- 合约/mint 者可以声称其他人是作者,但未经其同意
- 不支持多个作者
- 使用自定义方法/自定义 JSON 字段
- 需要 NFT 平台提供每个合约的支持
- 合约/mint 者可以声称其他人是作者,但未经其同意
第一种做法是最常见的。但是,在几种情况下,mint 者和作者可能不是同一个人,例如:
- 由合约 mint 的 NFT
- 延迟 mint
- 由中介机构 mint 的 NFT(当作者不精通技术和/或 mint 过程复杂时,这尤其有用)
因此,本文档定义了一个标准,该标准允许 mint 者提供作者身份信息,同时防止在未经作者同意的情况下声明作者身份。
规范
本文档中的关键词“必须”、“禁止”、“必需”、“应”、“不应”、“应该”、“不应该”、“推荐”、“可以”和“可选”应按照 RFC 2119 中的描述进行解释。
本标准中使用的所有地址必须遵循 EIP-55 中描述的大小写规则。
定义
- 作者:NFT 的创建者
- Minter:负责实际 mint 交易的实体;minter 和作者可以是同一个人
- 验证者:想要验证 NFT 作者身份的实体(例如,用户或 NFT 市场)
- 作者授权许可证明 (ACP):一种签名消息,证明签名者同意被认为是 NFT 的作者
作者身份支持
该标准引入了一个新的 JSON 字段,名为 authorInfo
。它为作者身份声明提供了一个必需的接口,并为作者授权许可证明提供了一个可选的接口。
authorInfo
是 NFT 元数据的顶级字段。具体来说:
- 如果合约支持 EIP-721 的元数据扩展,则
tokenURI(uint256 _tokenId)
指向的 JSON 文档必须包含顶级字段authorInfo
- 如果合约支持 EIP-1155 的元数据扩展,则
uri(uint256 _id)
指向的 JSON 文档必须包含顶级字段authorInfo
authorInfo
的 JSON 模式(命名为 ERC5375AuthorInfoSchema
)定义如下:
{
"type": "object",
"properties": {
"consentInfo": {
"type": "object",
"description": "用于授权许可验证的辅助字段",
"properties": {
"chainId": {
"type": "integer",
"description": "EIP-155 链 ID"
},
"id": {
"type": "string",
"description": "NFT ID"
},
"contractAddress": {
"type": "string",
"description": "智能合约的 0x 前缀地址"
}
}
},
"authors": {
"type": "array",
"items": "ERC5375AuthorSchema"
}
},
"required": [ "authors" ]
}
请注意,authors
可以是一个空数组。
ERC5375AuthorSchema
定义如下:
{
"type": "object",
"properties": {
"address": {
"type": "string",
"description": "作者的 0x 前缀地址"
},
"consent": {
"type": "ERC5375AuthorConsentSchema",
"description": "作者授权许可信息"
}
},
"required": [ "address" ]
}
此外,如果存在 consent
字段,则 authorInfo
的 consentInfo
字段必须存在。
ERC5375AuthorConsentSchema
定义如下:
{
"type": "object",
"properties": {
"consentData": {
"type": "object",
"properties": {
"version": {
"type": "string",
"description": "NFT 作者身份授权许可模式版本"
},
"issuer": {
"type": "string",
"description": "作者的 0x 前缀地址"
},
"metadataFields": {
"type": "object"
}
},
"required": ["version", "issuer", "metadataFields"]
},
"publicKey": {
"type": "string",
"description": "作者的 EVM 公钥"
},
"signature": {
"type": "string",
"description": "授权许可消息的 EIP-712 签名"
}
},
"required": ["consentData", "publicKey", "signature"]
}
其中 metadataFields
是一个对象,包含作者将要认证的 JSON 顶级字段(不包括 authorInfo
)。请注意,metadataFields
的键可以是字段集合的(可能是空的)子集。
consentData
可以支持其他 EIP 定义的其他字段。consentData
必须包含验证作者身份授权许可证明有效性所需的所有信息(这些信息尚未存在于其他字段中)。
作者授权许可
通过签署与 EIP-712 兼容的消息来获得授权许可。具体来说,结构定义如下:
struct Author {
address subject;
uint256 tokenId;
string metadata;
}
其中,subject
是 NFT 合约的地址,tokenId
是 NFT 的 ID,metadata
是 metadataFields
中列出的字段的 JSON 编码。metadata
:
- 必须包含与
metadataFields
中列出的字段完全相同的字段,顺序也相同 - 必须转义所有非 ASCII 字符。如果转义的字符包含十六进制字母,则它们必须为大写
- 不得包含任何不属于字段名称或值的空格
例如,如果顶级 JSON 字段是:
{
"name": "安提阿的圣手榴弹",
"description": "朝你最喜欢的兔子的方向扔,瞧",
"damage": 500,
"authors": [...],
...
}
并且 metadataFields
的内容是 ["name", "description"]
,则 metadata
的内容是:
{
"name": "安提阿的圣手榴弹",
"description": "朝你最喜欢的兔子的方向扔,瞧\u00E0"
}
与 consentData
类似,此结构可以支持其他 EIP 定义的其他字段。
域分隔符结构是
struct EIP712Domain {
string name;
string version;
uint256 chainId;
}
其中 name
和 version
是 consentData
中描述的相同字段。
此结构可以支持其他 EIP 定义的其他字段。
作者授权许可验证
验证是基于每个作者使用 EIP-712 执行的。具体来说,给定 JSON 文档 D1,如果以下所有语句都为真,则授权许可证明有效:
- D1 具有与
ERC5375AuthorInfoSchema
匹配的顶级authorInfo
字段 consent
存在并与ERC5375AuthorConsentSchema
匹配;- 如果调用
tokenURI
(对于 EIP-721)或uri
(对于 EIP-1155)返回 JSON 文档 D2 的 URI,则metadataFields
中列出的所有顶级字段必须存在并且具有相同的值; signature
中的 EIP-712 签名(使用 JSON 文档中指定的字段计算)有效;
验证者不得假定来自地址 X 的具有有效授权许可证明的 NFT 意味着 X 是实际作者。另一方面,验证者可以假定,如果 NFT 没有为地址 X 提供有效的授权许可证明,则 X 不是实际作者。
原理
为什么只提供作者授权许可证明?
添加对完全作者身份证明(即 Alice 是作者,而其他人不是作者)的支持需要一个协议来证明某人是 NFT 的唯一作者。 换句话说,我们需要回答这个问题:“给定一个 NFT Y 和一个声称是作者的用户 X,X 是 Y 的原始作者吗?”
为了论证起见,假设存在一种协议,给定一个 NFT Y,可以确定 Y 的原始作者。即使存在这种方法,攻击者也可以稍微修改 Y,从而获得一个新的 NFT Y’,并理所当然地声称自己是 Y’ 的作者,尽管事实上它不是原创作品。现实世界的例子包括更改图像的某些像素或用同义词替换文本的某些单词。 要防止这种行为,需要对两个 NFT 何时在语义上等效进行一般的形式化定义。即使定义这样的概念是可能的,它仍然超出了本 EIP 的范围。
请注意,当使用 mint 者的地址作为作者的代理时,也存在此问题。
为什么是链下?
原因有三个:
- 添加链下支持不需要修改现有的智能合约;
- 链下存储通常比链上存储便宜得多,从而降低了实现门槛;
- 虽然完全链上作者身份证明可能有一些用例(例如,市场为作者提供特殊功能),但链上作者授权许可的应用有限,因为它主要供用户用来确定 NFT 的主观价值。
为什么要重复 ID、chainId 和 contractAddress?
在很多情况下,这些数据可以从上下文信息中得出。但是,要求将其包含在 JSON 文档中可确保仅使用 JSON 文档即可验证作者授权许可。
为什么不实施撤销系统?
作者身份通常是最终的:要么是某人创建了 NFT,要么他们没有。此外,撤销系统会对智能合约施加额外的实施要求,并增加验证的复杂性。智能合约可以实施撤销系统,例如其他 EIP 中定义的系统。
为什么要在签名消息中转义非 ASCII 字符?
EIP-712 的设计考虑了链上验证的可能性;虽然链上验证不是本 EIP 的优先事项,但由于在智能合约中处理非 ASCII 字符串的复杂性很高,因此会转义非 ASCII 字符。
对作者的可用性改进
由于作者只需要签署 EIP-712 信息,因此该协议允许 mint 者处理 mint 的技术方面,同时仍然保留作者钱包的保密性。具体来说,作者只需要:
- 获取 EVM 钱包;
- 学习如何读取和签署 EIP-712 消息(通常可以使用 Dapp 简化)
而无需:
- 获取链的原生代币(例如,通过交易或桥接);
- 签署交易;
- 了解交易的定价机制;
- 验证交易是否已包含在区块中
这降低了作者的技术门槛,从而提高了 NFT 的可用性,而无需作者将他们的密钥交给精通技术的中介机构。
基于地址的授权许可的局限性
本标准定义了一个协议来验证某个 地址 是否提供授权许可。但是,它不能保证该地址与预期的作者(例如 name
字段中提供的作者)相对应。证明地址与地址背后的实体之间的链接超出了本文档的范围。
向后兼容性
未发现任何向后兼容性问题。
安全注意事项
攻击
利用此 EIP 的一种潜在攻击涉及诱骗作者签署违反他们意愿的作者身份授权许可消息。因此,作者必须验证所有签名字段是否与要求的字段匹配。
一种更微妙的方法是不向 metadataFields
添加重要字段。这样做,即使 mint 者更改关键信息,作者签名也可能有效。
弃用的功能
ERC5375AuthorInfoSchema
最初还包括一个字段,用于指定作者的可读名称(没有任何类型的验证)。由于作者欺骗的风险很高,因此该字段被取消,即:
- Alice 使用 Bob 的名字和 Alice 的地址 mint 一个 NFT
- Charlie 不检查地址,而是依赖于提供的名称
- Charlie 购买 Alice 的 NFT,同时认为它是由 Bob 创建的
因此,智能合约开发人员不应向 JSON 文档添加对无法验证的信息的支持。我们认为,提供复杂作者身份信息(例如作者姓名)的最安全方法是证明该信息与_作者的地址_相关联,而不是与 NFT 本身相关联。
重放攻击抵抗
链 ID、合约地址和代币 ID 唯一地标识一个 NFT;因此,无需实施额外的重放攻击对策(例如,nonce 系统)。
版权
版权和相关权利通过 CC0 放弃。
Citation
Please cite this document as:
Samuele Marro (@samuelemarro), Luca Donno (@lucadonnoh), "ERC-5375: NFT 作者信息和授权许可," Ethereum Improvement Proposals, no. 5375, July 2022. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-5375.