Contract metadata
INFO
Contract metadata should not be confused with token metadata.
Introduction
The contract metadata provides details about the contract itself and the offchain-views like the 'back cover' of a book describing its content and author.
The contract's metadata is stored as a separate JSON file on IPFS (InterPlanetary File System) or any HTTPS accessible url and linked into the metadata
big map.
The metadata file
The contract metadata is structured as a JSON file, which is essentially a dictionary of key-value pairs. This JSON file follows the standard described in the TZIP-16 and contains information about the contract.
The metadata file is used by a range of tools (wallets, explorers, dapps) to display useful information to users (contract's name, version, description, etc).
You are encouraged to read the TZIP linked above to know all the information expected in this file.
metadata.json
{
"name": "MyContract",
"version": "1.0.0",
"description": "This implements FA2 (TZIP-012) using SmartPy.",
"interfaces": ["TZIP-012", "TZIP-016"],
"authors": ["SmartPy <https://smartpy.io>"],
"homepage": "https://smartpy.io/ide?template=fa2_lib.py",
"source": {
"tools": ["SmartPy"],
"location": "https://gitlab.com/SmartPy/smartpy/-/raw/master/python/templates/fa2_lib.py"
},
"permissions": {
"receiver": "owner-no-hook",
"sender": "owner-no-hook",
"operator": "owner-or-operator-transfer"
}
}
Upload
To make your metadata file accessible, it needs to be uploaded to a server. While it can be hosted on any https server, it's often uploaded on IPFS due to its decentralized nature. This decentralization ensures that the file content cannot be altered without changing its hash and thus the URL, providing a form of content integrity. Moreover, anyone can host an IPFS node to re-upload the content if necessary, ensuring resilience against single points of failure.
TIP
If you upload your metadata file on IPFS, remember to 'pin' it. Pinning is the process of marking a particular file or data block to prevent it from being garbage collected and removed from your IPFS storage. You should also keep a backup version of your file elsewhere, as you may need to re-upload it again later.
Setting the big map
Once your metadata file is uploaded and accessible, a link to it is stored in a bigmap called metadata
. This bigmap works as a reference point for metadata values and files.
The key used to reference an external file is the empty string: ""
.
If the file is using IPFS, the URI should be in the form "ipfs://<hash>"
. This format allows for content-addressable access, making the data resilient to changes and network failures. Conversely, an HTTPS URL points to a location on a server where the content can be modified, and the server might not always be accessible.
The examples below show how to set contract metadata using both IPFS and HTTPS. Notice how the URL forms differ depending on the used method.
Example:
import smartpy as sp
from templates import fa2_lib as fa2
def bytes_of_string(s):
return sp.bytes("0x" + s.encode('utf-8').hex())
@sp.add_test()
def test():
sc = sp.test_scenario("NFT", [fa2.t, fa2.main])
metadata = sp.big_map({
"" : bytes_of_string(
"ipfs://QmPChd2hVbrJ6bfo3WBcTW4iZnpHm8TEzWkLHmLpXhF68A")
})
c1 = fa2.main.Nft(metadata, {}, [])
sc += c1
import smartpy as sp
from templates import fa2_lib as fa2
def bytes_of_string(s):
return sp.bytes("0x" + s.encode('utf-8').hex())
@sp.add_test()
def test():
sc = sp.test_scenario("NFT", [fa2.t, fa2.main])
metadata = sp.big_map({
"" : bytes_of_string(
"https://example.com")
})
c1 = fa2.main.Nft(metadata, {}, [])
sc += c1