Etherscan Blog
Published in

Etherscan Blog

Souls of Immortal NFTs

Classifying fully on-chain non-fungible tokens

Table of Contents

  • Introduction
  • Classification Scheme #1: Michelin Guide
    – External pointer (❌)
    – Calldata (⭐️)
    – Parameters + code on chain (⭐️⭐️)
    – Entire NFT on chain (⭐️⭐️⭐️)
  • Classification Scheme #2: Practical Implications
    – Recoverable
    – Summonable
    – Composable
    – Evolvable
  • How Can You Tell?
    – Art Blocks example
  • Conclusion
  • Background and Further Reading
  • Endnotes and Disclosures


Signal founder Moxie Marlinspike recently penned a critique of “web3.” It became the conversation topic of all of Crypto Twitter for a day or so. In this critique, he describes a number of significant challenges, especially for non-fungible tokens (NFTs) and the infrastructure they depend on. Here’s a prominent passage that was quoted by many on Twitter:

“Most people think of images and digital art when they think of NFTs, but NFTs generally do not store that data on-chain. For most NFTs of most images, that would be much too expensive. … Instead of storing the data on-chain, NFTs instead contain a URL that points to the data.” — Moxie’s 1/7/22 critique

This concern has been raised many times by others for years. But Moxie’s point is fair — it’s a concern worthy of continuing discussion.

One response to Moxie’s critique is that there are many projects that store their assets on the blockchain. These are the so-called “on-chain NFTs.” These NFTs are stored internally, directly inside the blockchain in some way. So they are immortal souls, preserved forever (or, for as long as their home ledger survives).

Consider just Ethereum, which was Moxie’s main target. On Ethereum, these projects are now so numerous that it is possible to describe on-chain NFTs according to classification schemes and standards.

Classification Scheme #1: Michelin Guide

It is useful to think of on-chain NFTs in technical terms. Dom Hoffman’s “Michelin guide” thread was widely circulated last year, and offers a star rating based on how an NFT’s asset is stored:

@dhof’s guide to on-chain NFTs
Hoffman’s guide to on-chain NFTs

j1mmyeth offered a similar assessment in 2019, and CryptoSketches pronounced on-chain as a critical feature in their release in earlier 2018.

CryptoSketches from 2018 may have been the first fully on-chain art. Disclosure: Takens owns this “Collectible Vitalik,” token #21.
CryptoSketches from 2018 may have been the first fully on-chain art. Disclosure: Takens owns this “Collectible Vitalik,” token #21, by artist Joe Chiappetta.

Dom Hoffman’s lowest score ❌ is assigned to NFTs that only point to some other resource (like a file on IPFS, or a centralized website). This is by far the most common setup. When you own an NFT on a project, the contract points to the relevant asset with a URL to a JPEG, PNG, etc. But because this file is off chain, on an external resource (like a website), there are few assurances that this resource will be secured forever. If the site goes down, the asset is gone. IPFS is a peer-to-peer decentralized file system and is an improvement here. But IPFS still has an issue when a resource can be lost because no user or server has “pinned it” (akin to bookmarking, see ClubNFT’s great summary).

For ⭐️, an NFT’s asset has to be stored at least in the “calldata” of a transaction. Calldata is bits of data that can be sent along with an Ethereum transaction. This is cheaper for storage, but cannot be used for any on-chain functionality (you need a chain explorer, node or other source of data to access it). A great discussion by 0xmons summarizes this. When an NFT is stored in calldata, it will live forever in the ledger—that calldata will forever be assigned to that transaction’s entry.

For ⭐️⭐️, the data must at least be stored inside the contract itself (“sstore” refers to the opcode in Ethereum that saves data in memory), but an outside script or compiler may be needed to fully reconstruct it. For example, 0xDEAFBEEF’s series 1 (“Angular”) pieces can be reconstructed using code stored in the calldata of this transaction. In order to use that code, the NFT contract stores required seeds and parameters on chain:

0xDEAFBEEF’s Series 1 token #130
0xDEAFBEEF’s Series 1 token #130

A ⭐️⭐️⭐️ designation is achieved when the data on the contract is enough to reproduce the NFT directly inside the contract itself. All of it is on chain, no additional code or compiler needed.

This is an excellent scheme because it’s clear and easy to assess (see also Art For All’s ratings system, which released around the same time). With a blockchain explorer like Etherscan, you can quickly investigate what kind of encoding your asset has. When an exchange like OpenSea looks to an NFT’s contract, it first summons tokenURI(_tokenId) to get a token’s metadata. That metadata will reveal the location of the asset along with its various properties.

Consider the contract of generative ⭐️⭐️⭐️ on-chain art solSeedlings. You can access its tokenURI(_tokenId) function directly through Etherscan by visiting the verified contract and its read functions. Summoning the metadata for token #1 reveals the entire JSON needed to recover this art, including the artwork itself (in SVG format):

solSeedlings tokenURI() output for token #1
solSeedlings tokenURI() output for token #1

For most NFT projects, you will discover that tokenURI(_tokenId) only returns an external URL. In some on-chain projects, like Avastars and ChainFaces, there are still other on-chain functions to recover your piece (renderAvastar and getFace, respectively). So it’s worth looking around a contract’s functions on Etherscan, as there may be some dedicated to recovering the asset (more on this below). But for others, in fact for most (confirming Moxie’s critique), there is only an external URL. The recent project Oogaverse points to an Amazon Web Services server:

Oogaverse tokenURI() output
Oogaverse tokenURI() output

Hashmasks doesn’t have a tokenURI(_tokenId) function, suggesting it needed some special configuration to get listed on exchanges. This project uses a distinct IPFS-based hashing model for provenance, described on its site.

So using Etherscan alone you can investigate the likely on-chainness of your NFT. For further illustration, Simon de la Rouviere has written an excellent, detailed summary of this for several projects, also using Etherscan.

Hoffman’s scheme has now been used by 0xchainArt in a beautiful new website devoted to on-chain NFTs. The guide lists dozens of these projects, and specifies the “Michelin” on-chain rating.

@0xchainArt’s excellent new website for on-chain NFTs
0xchainArt’s excellent new website for on-chain NFTs

Classification Scheme #2: Practical Implications

Various on-chain projects by design emphasis: Colorglyphs, Edifice (Art Blocks), solSeedlings, Strange Attractors, Avastars, Fast Food Nouns, Moon in Motion, Every Icon

One potential critique of this scheme is that it focuses too much on basic contract technicals, and not enough on their practical consequences. Consider an alternative way of framing on-chain NFTs. It is useful to talk about the opportunities that an NFT’s asset affords without external resources. You could imagine it as a kind of “desert island” thought experiment in which you have only an Ethereum node and some basic developer tools. In this situation, an on-chain NFT is easy to define:

Recoverable. An on-chain NFT is one that can be recovered entirely from the data on an Ethereum node (along with some fair-game developer tools).

That’s it, that’s the whole definition. At base, an on-chain asset allows you to achieve the goal of recovery from the chain. Imagine you have available some standard compilers and other developer tools and only the data accessible through an Ethereum node¹. The set of on-chain NFTs is the set of those recoverable under these conditions.

A second type of on-chain NFT is a subset of this most general class:

Summonable. An on-chain NFT that can be put to use, without any further processing, directly from the chain.

If you were forced only to use an Ethereum node to supply your website with images, you’d have to restrict yourself to summonable on-chain NFTs — NFTs that can be used without further processing from the chain. These are assets that can be called directly into applications. A fun illustration of this erupted on Twitter last fall. NateAlexNFT discovered that isiain had created a tool that calls functions directly from smart contracts and displays output in a browser. Using this tool, you can test for “summonable” NFTs with a single call on chain.

Nate using his Squiggles, on-chain art generated on contract
Nate using his Squiggles, on-chain art generated on contract

Composable. An on-chain NFT that can be easily manipulated by other on-chain components (such as other contracts) in order to integrate, extend or modify it.

If you could only use an Ethereum node to modify NFTs, to prepare them for processing or display elsewhere, a composable NFT is one that can be readily manipulated by other Ethereum contracts using only the EVM’s capabilities. NFT composability is still evolving, and there are some exciting examples of this. For example, a single injection of CSS could directly alter the appearance of an Avastar, a benefit of its SVG data format. But composability is central to the entire Avastars enterprise: It is generated from layered SVG features that are freely moving and manipulable. This project released its “Replicants” phase last fall. Users can now take Avastars they own, combine features from them and assemble a whole new Avastar: a Replicant. Snoop Dogg has one now, in his likeness:

Snoop Dogg’s Avastar
Snoop Dogg’s Avastar

Evolvable. An on-chain NFT that is dynamic, changing with the chain over time.

The concept of “evolvability” might prompt eerie sci-fi ideas of AI or consciousness on chain, like Von Neumann’s famous formulations of self-programming and self-replicating machines. So this may seem like an oddball characterization of NFTs. But there is already simmering use of this concept in some on-chain projects².

By implementing small-scale snippets of AI on chain, the_innerspace and CaptPixel created an arcade game in which the chain itself is playing. The NFT “plays” a classic game of snake, evolving with block height. When the game is complete, this project converts the gameplay into a retro, pixelated on-chain animation for the owner.

ArcadeGlyphs showing frames of the snake game
ArcadeGlyphs showing frames of the snake game

In another example, the artwork Every Icon uses an iterative process to visit every possible image inside a grid of a given size. In an impressive technical solution led by divergenceharri, these artworks will require an incomprehensible amount of time to complete their process, but the contract allows an owner to view the “current snapshot” of the piece (on-chain; note Every Icon does have some off-chain components, too). Here’s the function peekSVG() on Etherscan:

Every Icon’s peekSVG() output, a base64 encoded on-chain NFT asset.
Every Icon’s peekSVG() output, a base64 encoded on-chain NFT asset.

Proof of its “evolvability” comes from calling the peekSVG() function a few times consecutively. Although the SVG is base64 encoded, you can see the data changing each time you press. The piece is evolving with time, exploring the grid of all possible images, every icon.

An elegant constraint on evolvable on-chain NFTs is that they somehow have to use global variables exposed by the EVM, such as the base fee, current block height, and so on.

Along with this more practical focus, the present scheme has one more advantage. It does not distinguish on-chain NFTs as “better” or “worse.” On-chain NFTs, by definition, can be recovered — making them a fundamental kind of equivalence class. However we can ask what we want to achieve with a given on-chain NFT project. A non-summonable on-chain NFT, like Art Blocks, can do more with its on-chain strategy, it has more flexibility. And summonable, evolvable NFTs impose a constraint, but solving it can be enticing in its own aesthetic way.

How Can You Tell?

This second classification scheme on the affordances of NFTs assumes an Ethereum node, but you can also simulate these ideas using a blockchain explorer, like Etherscan. Your NFT is recoverable if you can use Etherscan alone to obtain the data and code for it. Consider an example: The transformative Art Blocks platform stores generative art on chain by encoding an artwork’s parameters on contract along with the explicit code needed to recover it. You can use Etherscan to find these resources after a bit of exploration.

Take a token ID from a crisp new project, such as hex6c’s InC release: #244000012. This is project 244 and minted token #12. Consulting Art Block’s main contract reveals several useful functions, such as projectDetails(_projectId). Art Blocks stores extensive information about projects and pieces directly in contract memory.

Art Blocks output from projectDetails(_projectId)
Art Blocks output from projectDetails(_projectId)

Using projectScriptByIndex(_index) you see that Art Blocks has encoded the p5js script needed to regenerate hex6c’s works.

hex6c’s p5js on-chain script.
hex6c’s p5js on-chain script.

If you’re relatively new to NFTs, it is worth selecting some of your favorite tokens and carrying out this exercise on Etherscan. It can help setup the “desert island” thought experiment — can you get your NFT’s core asset data through the block explorer itself?


There are many dozens of on-chain NFTs on Ethereum alone, many of them with a significant following such as Avastars, ChainFaces (and now ChainFaces Arena), Strange Attractors, Blitmap, Brotchain, Chain Runners, Autoglyphs and more (really do check out the website to see these and others). They can be organized in intriguing ways based on their technical details (Hoffman’s scheme) and their practical affordances (summonability, evolvability, etc.)³.

I began this post describing Moxie’s critique. If he’d consulted some of these projects, some of his innovative exploration may have been more interesting and less problematic. Indeed, in Moxie’s critique, he offers some pretty fun experimentation, such as having NFT assets change depending on who is calling them (such as which IP is summoning an NFT). These intriguing ideas would make for fun and far better explorations in on-chain configurations.

Background and Further Reading

Endnotes and Disclosures

  1. I’m obviously abstracting over what kind of node, but indeed a full node (not archival) may be sufficient for most purposes.
  2. I use the term “evolve” generically to mean to “change over time,” and not to reference any particular scientific theory, such as Darwinian processes, which invoke particular specific requirements.
  3. An important point about the second classification scheme is that its categories are fuzzier—for example, it could be argued that any on-chain SVG is composable by its nature, as a markup data structure. Moreover, a project may not have meant to be composable or evolvable but could be used that way later. There’s something I like about this more fluid categorization, as it encourages exploration of how a project could be adapted for new purposes.

Disclosures. I was asked if I would like to send any of my recent studies along with Etherscan’s newsletter. I eagerly accepted the kind invitation. I was not paid for this by Etherscan, but did enjoy writing it. Also I do like Etherscan (a lot). I’m on Twitter, and have some creative projects and other writing.



Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store