ERC-7572: 通过 `contractURI()` 实现合约级别元数据
指定和更新合约级别元数据
Authors | Devin Finzer (@dfinzer), Alex Atallah (@alexanderatallah), Ryan Ghods (@ryanio) |
---|---|
Created | 2023-12-06 |
Discussion Link | https://ethereum-magicians.org/t/erc-contract-level-metadata-via-contracturi/17157 |
摘要
本规范标准化 contractURI()
以返回合约级别的元数据。这对于 dapps 和链下索引器来说非常有用,它们可以显示有关合约的丰富信息,例如其名称、描述和图像,而无需手动或单独为每个 dapp 指定。
动机
多年来,Dapps 已经包含了对 contractURI()
的支持,但没有 ERC 可以参考。此标准还引入了事件 ContractURIUpdated()
,以指示何时更新元数据。
规范
本文档中的关键词“MUST”、“MUST NOT”、“REQUIRED”、“SHALL”、“SHALL NOT”、“SHOULD”、“SHOULD NOT”、“RECOMMENDED”、“NOT RECOMMENDED”、“MAY”和“OPTIONAL”应按照 RFC 2119 和 RFC 8174 中的描述进行解释。
合约必须实现以下接口:
interface IERC7572 {
function contractURI() external view returns (string memory);
event ContractURIUpdated();
}
从 contractURI()
返回的字符串可以是链下资源或链上 JSON 数据字符串(data:application/json;utf8,{}
)。
ContractURIUpdated()
事件应该在合约元数据的更新时发出,以便链下索引器查询合约。
如果底层合约提供了任何与 contractURI
模式冲突的方法,例如 name()
或 symbol()
,建议 contractURI()
返回的元数据优先。这使合约创建者能够通过通知更新的事件来更新其合约详细信息。
contractURI 的模式
从 contractURI()
返回的 JSON 模式必须符合:
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "合约的名称。"
},
"symbol": {
"type": "string",
"description": "合约的符号。"
},
"description": {
"type": "string",
"description": "合约的描述。"
},
"image": {
"type": "string",
"format": "uri",
"description": "指向具有 mime type image/* 的资源的 URI,该资源表示合约,通常显示为合约的头像。"
},
"banner_image": {
"type": "string",
"format": "uri",
"description": "指向具有 mime type image/* 的资源的 URI,该资源表示合约,显示为合约的横幅图像。"
},
"featured_image": {
"type": "string",
"format": "uri",
"description": "指向具有 mime type image/* 的资源的 URI,该资源表示合约的特色图像,通常用于高亮部分。"
},
"external_link": {
"type": "string",
"format": "uri",
"description": "合约的外部链接。"
},
"collaborators": {
"type": "array",
"items": {
"type": "string",
"description": "表示合约的授权编辑者的以太坊地址。"
},
"description": "表示合约的协作者(授权编辑者)的以太坊地址数组。"
}
},
"required": ["name"]
}
例子:
{
"name": "Example Contract",
"symbol": "EC",
"description": "Your description here",
"image": "ipfs://QmTNgv3jx2HHfBjQX9RnKtxj2xv2xQCtbDXoRi5rJ3a46e",
"banner_image": "ipfs://QmdChMVnMSq4U7oVKhud7wUSEZGnwuMuTY5rUQx57Ayp6H",
"featured_image": "ipfs://QmS9m6e1E1NfioMM8dy1WMZNN2FRh2WDjeqJFWextqXCT8",
"external_link": "https://project-website.com",
"collaborators": ["0x388C818CA8B9251b393131C08a736A67ccB19297"]
}
未来的 ERC 可以继承这个 ERC,以便为模式添加更多属性以进行标准化。
理由
方法名 contractURI()
的选择是基于其在 dapps 中的现有实现。指定 ContractURIUpdated()
事件是为了帮助链下索引器知道何时重新获取元数据。
向后兼容性
作为一个新的 ERC,不存在向后兼容性问题。
参考实现
contract MyCollectible is ERC721, IERCXXXX {
string _contractURI = "ipfs://QmTNgv3jx2HHfBjQX9RnKtxj2xv2xQDtbVXoRi5rJ3a46e"
// or e.g. "https://external-link-url.com/my-contract-metadata.json";
function contractURI() external view returns (string memory) {
return _contractURI;
// or e.g. for onchain:
// 或者例如,对于链上:
string memory json = '{"name": "Creatures","description":"..."}';
return string.concat("data:application/json;utf8,", json);
}
/// @dev Suggested setter, not explicitly specified as part of this ERC
// @dev 建议的setter,未明确指定为此ERC的一部分
function setContractURI(string memory newURI) external onlyOwner {
_contractURI = newURI;
emit ContractURIUpdated();
}
}
安全考虑
应预期指定为 collaborators
的地址将收到管理员级别的功能,以便在实施此标准的 dapps 上更新合约信息。
版权
版权和相关权利通过 CC0 放弃。
Citation
Please cite this document as:
Devin Finzer (@dfinzer), Alex Atallah (@alexanderatallah), Ryan Ghods (@ryanio), "ERC-7572: 通过 `contractURI()` 实现合约级别元数据 [DRAFT]," Ethereum Improvement Proposals, no. 7572, December 2023. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-7572.