DEV Community

Niranjan Lamichhane
Niranjan Lamichhane

Posted on

Solana NFT : Referenced , not embedded .

Before this week, I thought an NFT is something that is a unique piece and cannot be tampered with. I assumed that an NFT is contained inside the blockchain itself, permanently sealed like a digital time capsule.

But What I Found Is That...

Only a tiny pointer (the URI) lives on-chain. The actual JPEG could be sitting on a free hosting service that might disappear tomorrow. The blockchain just says "go look here" — not "here's the thing."

This post is what I learned building NFTs on Solana from scratch — and why most of what I thought I knew was wrong.

The Mental Model: What an NFT Actually Is on Solana

Before practicing this, I thought an NFT is something that is a unique piece and cannot be tampered with. I assumed that an NFT is contained inside the blockchain itself, permanently sealed like a digital time capsule.

But that's not how Solana works.

On Solana, an NFT is just a regular SPL token with three specific properties:

Property Value Why
Decimals 0 Cannot be split into smaller units
Supply 1 Only one exists
Extensions Metadata + (optional) Group/Member Adds name, image, and collection logic

That's it. No separate "NFT program." No magic.


What I Built: The Full Arc

Day 1: A Single NFT with Metadata

Using Token-2022, I created a mint with the Metadata extension:

spl-token --program-id TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb \
  create-token --decimals 0 --enable-metadata
Enter fullscreen mode Exit fullscreen mode

Then I stamped the metadata:

spl-token initialize-metadata MY_MINT "Sketch #1" "SK1" https://gist.github.com/...
Enter fullscreen mode Exit fullscreen mode

Day 2: A Collection with Group + Member Extensions

I created a collection container and linked members to it:

# Create collection with group extension
spl-token create-token --enable-metadata --enable-group

# Set max size
spl-token initialize-group COLLECTION_MINT 3

# Create member with member extension
spl-token create-token --enable-metadata --enable-member

# Link member → collection (THIS ORDER MATTERS)
spl-token initialize-member MEMBER_MINT COLLECTION_MINT

# Lock it
spl-token authorize MEMBER_MINT mint --disable
Enter fullscreen mode Exit fullscreen mode

Day 3: Auditing Everything On-Chain

spl-token display COLLECTION_MINT  # Shows Size: 2 / Max Size: 3
spl-token display MEMBER_MINT       # Shows Group: COLLECTION_ADDRESS
Enter fullscreen mode Exit fullscreen mode

Day 4: Mutating Live Metadata

spl-token update-metadata MY_NFT name "Probably Worthless"
spl-token update-metadata MY_NFT rarity "legendary"
Enter fullscreen mode Exit fullscreen mode

The Surprising Part: What Was Different from What I Expected

Surprise 1: The Image Isn't On-Chain

I found that only a tiny pointer (the URI) lives on-chain. The actual JPEG could be sitting on a free hosting service that might disappear tomorrow. The blockchain just says "go look here" — not "here's the thing."

What I thought:    [Blockchain] ─ contains ─> [JPEG Image]

What it actually:  [Blockchain] ─ contains ─> [URI: "https://random-server.com/nft.jpg"]
                                                      ↓
                                              [Actual JPEG on someone's server]
Enter fullscreen mode Exit fullscreen mode

Surprise 2: NFTs Can Be Changed

I assumed "unique" meant nobody can ever change it. But the update authority (whoever minted the NFT) can change the name, symbol, URI, and add/remove metadata fields at any time.

Immutability is a choice (burning the update authority), not a technical requirement.

Surprise 3: "Unique" Means the Mint Address, Not the Image

Two different NFTs can point to the exact same image URL and still be completely distinct tokens. The blockchain doesn't check or care if images are duplicated. Uniqueness comes from the 32-byte mint address.


Where an NFT Actually Lives

An NFT is scattered across multiple layers:

Layer What's Stored There
On-chain Mint account (32 bytes of identity + extensions)
Off-chain JSON metadata (maybe on Gist, AWS, or Pinata)
Off-chain Image file (JPEG on a CDN)
Wallet cache Local copy of all the above

No single place contains the "whole" NFT. It's a distributed reference system.


My Mental Model: Before vs. After

Before Practice After Practice
❌ NFT = Image file inside blockchain ✅ NFT = Token mint (on-chain) + Pointer to JSON (on-chain) + JSON file (off-chain) + Image (off-chain)
❌ Completely immutable forever ✅ Mutable if update authority exists; immutable only if authority is burned
❌ Automatically unique content ✅ Unique by mint address only — content can be duplicated
❌ One single thing in one place ✅ Distributed across multiple layers — no single "location"

The Conclusion

Solana NFTs are referenced, not embedded.

An NFT is actually just a deed — a small on-chain pointer to off-chain content, mutable if the creator keeps their keys, and only as permanent as the server hosting the image.

The blockchain guarantees the token's existence, not the artwork's immortality.


Resources I Used


Top comments (0)