Onchain vs Offchain NFTs: Why Permanency Matters

December 15th, 2021

Onchain vs Offchain NFTs: Why Permanency Matters

The NFT market is now a thing. Everyone's buying, selling, and trading digital assets like they're going out of style. But here's the thing, most people have no idea what they're actually buying. They see a JPEG, they see a price, and they think they own something. In most of the cases, they're wrong.

The reality is that most NFTs are just pointers to external files, like a with something inside. The actual art, the thing you think you "own" when you buy it, lives somewhere else. And that somewhere else can disappear, change, or be taken down at any moment. You're not buying art, you're buying a receipt that points to art that might not exist tomorrow.

This is the permanency problem, and it's bigger than most people realize.

What Are You Actually Buying?

When you buy an NFT, you're buying a token on the blockchain. That token contains metadata, and that metadata usually contains a link to the actual artwork. The artwork itself? That's stored somewhere else entirely.

// Typical NFT metadata structure
{
  "name": "Cool Art #123",
  "description": "This is amazing art",
  "image": "https://example.com/artwork/123.png",
  "attributes": [...]
}

The image field is just a URL. It could point to:

  • A centralized server (risky)
  • IPFS (better, but not perfect)
  • Arweave (good for permanency)
  • The blockchain itself (truly permanent)

Most NFTs use the first option. They point to a server that someone controls, which means someone can change or delete your art at any time.

The Storage Spectrum

1. Centralized Servers (The Worst)

{
  "image": "https://mycompany.com/nft-art/123.png"
}

This is what most NFTs do. The art lives on a server that someone controls. The risks are obvious:

  • Server goes down? Your art disappears
  • Company changes the image? Your art changes
  • Company goes out of business? Your art is gone
  • Someone hacks the server? Your art could be replaced

I've seen this happen already. Projects that were worth millions suddenly had their art replaced with "This NFT has been moved" messages. The blockchain still shows you own it, but the art is gone. Oh, but who can help me, the reality is that no-one can.

2. IPFS (Better, But Not Perfect)

{
  "image": "ipfs://QmHash..."
}

IPFS (InterPlanetary File System) is decentralized storage. Your art gets a unique hash, and as long as someone is pinning it, it stays available. The problem? If no one pins it, it disappears.

// IPFS pinning example
const ipfs = require('ipfs-http-client');

// Pin your content
const result = await ipfs.add(artworkData);
const hash = result.path;

// But what happens when you stop pinning?
// The content becomes garbage collected

IPFS is better than centralized servers, but it's not permanent. It's only as permanent as the people who choose to keep it alive.

3. Arweave (Good for Permanency)

{
  "image": "ar://transaction-hash"
}

Arweave is designed for permanent storage. You pay once, and your data is stored forever. It's more expensive than IPFS, but it's actually permanent.

// Arweave upload example
const arweave = Arweave.init({
  host: 'arweave.net',
  port: 443,
  protocol: 'https'
});

const transaction = await arweave.createTransaction({
  data: artworkData
});

await arweave.transactions.sign(transaction);
await arweave.transactions.post(transaction);

Arweave is probably the best option for offchain storage, but it's still not as permanent as storing directly on the blockchain.

3.5. Art Blocks: The Hybrid Approach

Art Blocks is interesting because they're trying to solve the onchain permanency problem, but they're not quite there yet. They store artist scripts onchain but still rely on external dependencies.

How Art Blocks Actually Works (2021 Reality):

  1. Artist Scripts: Stored onchain ✅
  2. Dependencies: External libraries like p5.js, three.js hosted offchain ❌
  3. Rendering: Requires external servers to combine script + dependencies ❌
  4. Hybrid Solution: Not fully onchain, but better than most
// Art Blocks approach - hybrid onchain/offchain
contract ArtBlocks {
    // Artist script stored onchain
    string public artistScript;
    
    // But dependencies are external
    function getTokenHtml(uint256 tokenId) public view returns (string memory) {
        // Combines onchain script with offchain dependencies
        // Still requires external p5.js, three.js libraries
        return assembleHTML(artistScript, tokenId, externalDependencies);
    }
}

The Reality Check:

  • Artist scripts are onchain - This is good, the generative code is permanent
  • Dependencies are external - p5.js, three.js still hosted on CDNs
  • Rendering requires external servers - Not truly independent
  • Better than most - But not fully onchain

Why This Matters:

Even Art Blocks has to compromise. They store the generative script onchain but still depend on external libraries for rendering. This shows how hard it is to achieve true onchain permanency.

The dependency problem is real. You can't just store the script onchain if it depends on external libraries. Those libraries can disappear, change, or be taken down. Yet the art is generated from the script itself if there is a lost of the key dependencies that your artwork depends on, it will be lost forever.

4. Onchain Storage (Truly Permanent)

// Art stored directly in the contract
string public constant SVG_HEADER = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">';
string public constant SVG_FOOTER = '</svg>';

function generateSVG(uint256 tokenId) public view returns (string memory) {
    return string(abi.encodePacked(
        SVG_HEADER,
        generateArt(tokenId),
        SVG_FOOTER
    ));
}

This is the gold standard. Your art is stored directly on the blockchain. It can't be changed, deleted, or taken down. It's as permanent as the blockchain itself.

This idea really stuck with me, this is where true innovation emerges: a new language for digital art. Suddenly, you have the tools to create digital art that is as permanent, perhaps even more so, since it does not degrade over time from physical decay, as a sculpture or a painting done in oil.

A system for artists to create permanent interactive artworks that persist, forever. Truly gamechanger.

Building Onchain NFTs

Ok, hands on, how does this work? The goal is for the entire image to be built directly on the blockchain, so what is returned is a complete graphic that can be rendered by any browser. This means the image is truly permanent. We can also be very creative with the composability and dynamics of building these graphics. If you know the SVG format, it allows for a wide level of programmatic edits, especially when those edits are based on current blockchain data.

Let's try to build a simple onchain NFT that generates SVG art directly from the contract:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/utils/Strings.sol";
import "@openzeppelin/contracts/utils/Base64.sol";

contract OnchainArt is ERC721 {
    using Strings for uint256;
    
    uint256 public totalSupply;
    
    constructor() ERC721("Onchain Art", "ONCHAIN") {}
    
    function mint() public {
        _mint(msg.sender, totalSupply);
        totalSupply++;
    }
    
    function tokenURI(uint256 tokenId) public view override returns (string memory) {
        require(_exists(tokenId), "Token does not exist");
        
        string memory svg = generateSVG(tokenId);
        string memory json = Base64.encode(
            bytes(
                string(
                    abi.encodePacked(
                        '{"name": "Onchain Art #',
                        tokenId.toString(),
                        '", "description": "Art generated onchain", "image": "data:image/svg+xml;base64,',
                        Base64.encode(bytes(svg)),
                        '"}'
                    )
                )
            )
        );
        
        return string(abi.encodePacked('data:application/json;base64,', json));
    }
    
    function generateSVG(uint256 tokenId) public pure returns (string memory) {
        // Generate art based on tokenId
        uint256 seed = uint256(keccak256(abi.encodePacked(tokenId)));
        
        // Extract colors from seed
        string memory color1 = getColor(seed);
        string memory color2 = getColor(seed >> 8);
        string memory color3 = getColor(seed >> 16);
        
        return string(
            abi.encodePacked(
                '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">',
                '<rect width="100" height="100" fill="',
                color1,
                '"/>',
                '<circle cx="50" cy="50" r="30" fill="',
                color2,
                '"/>',
                '<rect x="20" y="20" width="60" height="60" fill="',
                color3,
                '" opacity="0.5"/>',
                '</svg>'
            )
        );
    }
    
    function getColor(uint256 seed) private pure returns (string memory) {
        uint256 hue = seed % 360;
        return string(
            abi.encodePacked(
                'hsl(',
                hue.toString(),
                ', 70%, 50%)'
            )
        );
    }
}

This contract generates unique SVG art for each token. The art is stored directly in the contract code, making it truly permanent. No external dependencies, no risk of disappearing.

The Permanency Problem in Practice

I've seen this play out in real projects. Here are some examples:

The Bored Ape Problem

Bored Ape Yacht Club stores their art on IPFS. If the IPFS nodes stop pinning the content, the art disappears. You still own the NFT, but the art is gone. For a project worth billions, this is a massive risk.

The Server Downtime Problem

I've seen projects where the art was stored on a company server. The company went out of business, the server went down, and suddenly thousands of NFTs had no art. The blockchain still showed ownership, but the art was gone.

The Content Change Problem

Some projects have had their art changed after minting. The NFT still points to the same URL, but the image is different. This breaks the permanency promise of NFTs.

Why This Matters

The permanency problem isn't just theoretical, it's happening right now. People are paying thousands, sometimes millions, for NFTs that could disappear tomorrow. They think they're buying digital art, but they're really buying a receipt that points to art that might not exist.

This is especially problematic because:

  1. Lack of knowledge: Most buyers don't understand the technical details
  2. FOMO: People are buying without understanding what they're getting
  3. Misleading marketing: Projects don't clearly explain storage risks
  4. No regulation: There's no requirement to disclose storage methods

The Solution: Education and Better Standards

The solution isn't to stop buying NFTs, it's to understand what you're buying. Before you buy an NFT, ask:

  • Where is the art stored?
  • Who controls the storage?
  • What happens if the storage fails?
  • Is the art truly permanent?

For developers, the solution is to build better. Use onchain storage when possible, or at least use permanent storage like Arweave. Be transparent about storage methods. Don't mislead buyers about permanency.

Building for Permanency

If you're building an NFT project, consider these options:

1. Onchain SVG Generation

Store the art generation logic directly in the contract. The art is generated on-demand and can't be changed.

2. Onchain Data Storage

Store the actual image data in the contract. This is expensive but truly permanent.

3. Arweave Integration

Use Arweave for permanent storage. It's more expensive than IPFS but actually permanent.

4. Hybrid Approaches

Store critical data onchain and less critical data on IPFS or Arweave.

The Future of NFT Permanency

The NFT market is still young, and permanency standards are still being developed. But the trend is clear: people want truly permanent digital assets. Projects that deliver on this promise will have a competitive advantage.

The technology exists to build truly permanent NFTs. The question is whether developers will use it and whether buyers will demand it.

Conclusion

The permanency problem is real, and it's affecting millions of NFT owners right now. Most NFTs are just pointers to external files that can disappear, change, or be taken down. This breaks the fundamental promise of NFTs as permanent digital assets.

The solution isn't to avoid NFTs, it's to understand what you're buying and demand better standards. For developers, it's to build with permanency in mind. For buyers, it's to ask the right questions before purchasing.

The blockchain is permanent. The art should be too.


This post is part of a series on NFT fundamentals. Previous: Working with Tuples in Solidity. Next: Implementing EIP-2981 Royalties.