Chapter 6 · Tokens · lesson 7
Token URIs and on-chain art
12 min
Builds on Storage, memory, calldata
Chapter 6 · Tokens · lesson 7
12 min
Builds on Storage, memory, calldata
Your NFT contract stores an owner per id. It stores no image, no name and no description.
Where does the picture come from?
The standard adds one function:
function tokenURI(uint256 id) external view returns (string memory);
It returns a URL. A wallet fetches that URL, expects JSON, and reads image
from it — which is another URL, which it fetches too.
So the usual chain is: contract → JSON somewhere → image somewhere else.
Two off-chain hops. If either fails, the NFT displays as a broken image while the ownership record on-chain remains perfectly intact.
You own the row in the mapping. Whether you can see anything is a separate question with a separate answer.
A plain URL (https://api.example.com/token/7). Cheap, flexible,
completely centralised. The team can change what your NFT depicts, or stop
paying for the server.
IPFS (ipfs://Qm…). Content-addressed, so the hash proves the file has not
changed. But IPFS only keeps files that someone actively pins. Stop paying
the pinning service and the content becomes unreachable — the hash remains valid
and points at nothing.
Fully on-chain. The image is generated by the contract. Nothing to host, nothing to pin, nothing to go offline.
You generated an image from the token id, inside the contract, with no server involved. That is how Loot, Autoglyphs and Nouns work.
Real on-chain collections base64-encode the SVG into a data: URI so wallets
render it directly, and the encoding is the only part missing from what you
wrote.
Predict
Check