Track 5 · Tokens · lesson 7

Token URIs and on-chain art

12 min


Your NFT contract stores an owner per id. It stores no image, no name and no description.

Where does the picture come from?

tokenURI

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.

The three options, honestly

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.

ArtNFT.solComplete
Loading editor…
Generate the artwork in the contract, from the token id.
Run the code to see what happens.
Nudge
You are gluing three pieces together: a prefix, the id as text, and a suffix.
Show me the approach
`string.concat(a, b, c)` joins strings. `toString(id)` is already written for you.
Show me the code
Return `string.concat("<svg><text>#", toString(id), "</text></svg>")`.
Explain the solution
This is the entire idea behind fully on-chain art: the image is computed from the id at read time, so there is no server, no IPFS pin, and nothing to go offline. Real generative collections do the same thing with far more concat calls.

What you just did

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

An NFT's tokenURI points at a team's own web server. What can the team do?

Choose one answer

Check

Why does on-chain art cost so much more to mint?

Choose one answer

Worth remembering

  • `tokenURI` returns a URL; wallets fetch JSON from it and then fetch the image it names.
  • A plain HTTPS URI means the team can change or remove the artwork at any time.
  • IPFS is content-addressed but only persists while someone pins it.
  • Fully on-chain art is generated by the contract, so nothing can go offline.
  • On-chain costs more because storage is expensive — hence the minimal aesthetic.