Token metadata and URI help describe what a token is and where to find its details. This makes tokens easy to understand and use.
Token metadata and URI in Blockchain / Solidity
tokenURI = "https://example.com/api/token/123" metadata = { "name": "Token Name", "description": "What this token represents", "image": "https://example.com/images/token123.png", "attributes": [ {"trait_type": "Color", "value": "Red"}, {"trait_type": "Size", "value": "Large"} ] }
The tokenURI is a link to a JSON file with token details.
Metadata is usually a JSON object describing the token's properties.
tokenURI = "https://mytokens.com/metadata/1.json"{
"name": "Cool NFT",
"description": "A unique digital art piece.",
"image": "https://images.com/coolnft.png"
}{
"name": "Rare Token",
"attributes": [
{"trait_type": "Rarity", "value": "Legendary"},
{"trait_type": "Power", "value": 9000}
]
}This program creates a token object with an ID and base URI. It then prints the full URI where the token's metadata JSON can be found.
class Token: def __init__(self, token_id, base_uri): self.token_id = token_id self.base_uri = base_uri def token_uri(self): return f"{self.base_uri}/{self.token_id}.json" # Create a token with ID 42 and base URI my_token = Token(42, "https://tokens.example.com/metadata") # Print the full URI to the token metadata print(my_token.token_uri())
Token metadata is often stored off-chain (outside the blockchain) to save space.
URIs usually point to web servers or decentralized storage like IPFS.
Always ensure metadata links are stable and accessible to avoid broken tokens.
Token metadata describes what a token is and its details.
Token URI is a link to the metadata JSON file.
Metadata helps apps and users understand and display tokens properly.
Practice
Solution
Step 1: Understand token metadata role
Token metadata provides descriptive information about the token, such as its name, description, and image link.Step 2: Differentiate from other blockchain functions
Metadata is not about private keys, mining, or executing contracts but about describing the token for users and apps.Final Answer:
To describe the token and link to its details -> Option BQuick Check:
Token metadata = description and details link [OK]
- Confusing metadata with private keys
- Thinking metadata controls token creation
- Mixing metadata with smart contract code
Solution
Step 1: Identify the data type for URI
A URI is a web address, so it should be stored as a string in the contract.Step 2: Check the options for correct syntax
string public tokenURI = "https://example.com/token/1.json"; uses a string with a valid URL format, while others use wrong types like int, bool, or address.Final Answer:
string public tokenURI = "https://example.com/token/1.json"; -> Option CQuick Check:
URI is a string URL [OK]
- Using int or bool for URI
- Confusing address type with URI
- Missing quotes around the URI string
tokenURI(1) return if _tokenURIs[1] is set to "https://example.com/metadata/1.json"?
mapping(uint256 => string) private _tokenURIs;
function tokenURI(uint256 tokenId) public view returns (string memory) {
return _tokenURIs[tokenId];
}Solution
Step 1: Understand the mapping and function
The mapping stores strings for each tokenId. The function returns the string stored for the given tokenId.Step 2: Check the value for tokenId 1
Since _tokenURIs[1] is set to "https://example.com/metadata/1.json", calling tokenURI(1) returns that string.Final Answer:
"https://example.com/metadata/1.json" -> Option DQuick Check:
Mapping lookup returns stored URI string [OK]
- Thinking tokenURI is private and inaccessible
- Confusing tokenId with URI string
- Assuming function returns tokenId instead of URI
mapping(uint256 => string) private _tokenURIs;
function setTokenURI(uint256 tokenId, string memory uri) public {
_tokenURIs[tokenId] = uri;
}Solution
Step 1: Review function purpose and security
The function sets a URI for a tokenId but has no restriction on who can call it.Step 2: Identify missing access control
Without access control (like onlyOwner), anyone can change token URIs, which is a security risk.Final Answer:
The function lacks access control and allows anyone to set URIs -> Option AQuick Check:
Missing access control = security risk [OK]
- Thinking mapping type is wrong for strings
- Expecting setter functions to return values
- Ignoring security risks of public setters
mapping(uint256 => string) private _tokenURIs;
string private _defaultURI = "https://example.com/default.json";
function tokenURI(uint256 tokenId) public view returns (string memory) {
// Fill in the blank
}Solution
Step 1: Check how to test if string is empty in Solidity
Solidity strings can't be compared to null or use || operator; use bytes length to check emptiness.Step 2: Verify correct conditional expression
return bytes(_tokenURIs[tokenId]).length > 0 ? _tokenURIs[tokenId] : _defaultURI; uses bytes(_tokenURIs[tokenId]).length > 0 to check if URI exists, else returns default URI.Final Answer:
return bytes(_tokenURIs[tokenId]).length > 0 ? _tokenURIs[tokenId] : _defaultURI; -> Option AQuick Check:
Check string length with bytes() for empty [OK]
- Using null or empty string comparison directly
- Using || operator for strings
- Returning wrong URI when none set
Ready to prove it?
Pass the test and this pattern moves unknown
