-
Notifications
You must be signed in to change notification settings - Fork 550
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
1 changed file
with
132 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,132 @@ | ||
--- | ||
eip: xxxx | ||
title: Contract-level metadata via `contractURI()` | ||
description: A standard for specifying contract-level metadata | ||
author: Ryan Ghods (@ryanio) | ||
discussions-to: https://ethereum-magicians.org/t/erc-contract-level-metadata-via-contracturi/17157 | ||
status: Draft | ||
type: Standards Track | ||
category: ERC | ||
created: 2023-12-06 | ||
requires: | ||
--- | ||
|
||
## Abstract | ||
|
||
This specification standardizes `contractURI()` to return contract-level metadata. This is useful for dapps and offchain indexers to show rich information about a contract, such as its name, description and image, without specifying it manually or individually for each dapp. | ||
|
||
## Motivation | ||
|
||
Dapps have included supported for `contractURI()` for years without an ERC to reference. This standard also introduces the event `ContractURIUpdated()` to signal when to update the metadata. | ||
|
||
## Specification | ||
|
||
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 and RFC 8174. | ||
|
||
The contract MUST implement the below interface: | ||
|
||
```solidity | ||
interface IERCXXXX { | ||
function contractURI() external view returns (string memory); | ||
event ContractURIUpdated(); | ||
} | ||
``` | ||
|
||
The string returned from `contractURI()` MAY be an offchain resource or onchain JSON data string (`data:application/json;utf8,{}`). | ||
|
||
The `ContractURIUpdated()` event SHOULD be emitted on updates to the contract metadata for offchain indexers to query the contract. | ||
|
||
If the underlying contract additionally provides a `name()` method, the metadata returned by `contractURI()`'s `name` property is RECOMMENDED to take precedence. This enables contract creators to update their contract name with an event that notifies of the update. | ||
|
||
### Schema for contractURI | ||
|
||
The schema for the JSON returned from `contractURI()` MUST conform to: | ||
|
||
```json | ||
{ | ||
"$schema": "https://json-schema.org/draft/2020-12/schema", | ||
"type": "object", | ||
"properties": { | ||
"name": { | ||
"type": "string", | ||
"description": "The name of the contract." | ||
}, | ||
"description": { | ||
"type": "string", | ||
"description": "The description of the contract." | ||
}, | ||
"image": { | ||
"type": "string", | ||
"format": "uri", | ||
"description": "The URL of the image representing the contract." | ||
}, | ||
"external_link": { | ||
"type": "string", | ||
"format": "uri", | ||
"description": "The external link of the contract." | ||
}, | ||
"collaborators": { | ||
"type": "array", | ||
"items": { | ||
"type": "string", | ||
"description": "An Ethereum address representing an authorized editor of the contract." | ||
}, | ||
"description": "An array of Ethereum addresses representing collaborators (authorized editors) of the contract." | ||
} | ||
}, | ||
"required": ["name"] | ||
} | ||
``` | ||
|
||
Example: | ||
|
||
```json | ||
{ | ||
"name": "Example Contract", | ||
"description": "Your description here", | ||
"image": "ipfs://QmTNgv3jx2HHfBjQX9RnKtxj2xv2xQCtbDXoRi5rJ3a46e", | ||
"external_link": "https://project-website.com", | ||
"collaborators": ["0x388C818CA8B9251b393131C08a736A67ccB19297"] | ||
} | ||
``` | ||
|
||
Future ERCs MAY inherit this one to add more properties to the schema for standardization. | ||
|
||
## Rationale | ||
|
||
The method name `contractURI()` was chosen based on its existing implementation in dapps. The event `ContractURIUpdated()` is specified to help offchain indexers to know when to refetch the metadata. | ||
|
||
## Backwards Compatibility | ||
|
||
As a new ERC, no backwards compatibility issues are present. | ||
|
||
## Reference Implementation | ||
|
||
```solidity | ||
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 | ||
function setContractURI(string memory newURI) external onlyOwner { | ||
_contractURI = newURI; | ||
emit ContractURIUpdated(); | ||
} | ||
} | ||
``` | ||
|
||
## Security Considerations | ||
|
||
Addresses specified as `collaborators` should be expected to receive admin-level functionality for updating contract information on dapps that implement this standard. | ||
|
||
## Copyright | ||
|
||
Copyright and related rights waived via [CC0](../LICENSE.md). |