Souls of Immortal NFTs
Classifying fully on-chain non-fungible tokens
Table of Contents
- Classification Scheme #1: Michelin Guide
– External pointer (❌)
– Calldata (⭐️)
– Parameters + code on chain (⭐️⭐️)
– Entire NFT on chain (⭐️⭐️⭐️)
- Classification Scheme #2: Practical Implications
- How Can You Tell?
– Art Blocks example
- 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:
j1mmyeth offered a similar assessment in 2019, and CryptoSketches pronounced on-chain as a critical feature in their release in earlier 2018.
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:
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):
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 (
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:
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.
Classification Scheme #2: Practical Implications
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 ether.actor 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.
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:
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.
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:
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.
projectScriptByIndex(_index) you see that Art Blocks has encoded the p5js script needed to regenerate hex6c’s works.
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 0xchain.art 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
- CryptoSketches: “CryptoSketches is a blockchain art gallery. Here’s how it works” from March, 2018
- artnome’s post about Autoglyphs from April, 2019
- j1mmyeth’s thread describing limitations of off-chain and IPFS from October 2019
- WPeaster’s “The On-Chain Art Movement Has Arrived” from December, 2020
- 0xmons’s “0xmons v2 Cthulhu: On-chain Encoding” from April, 2021
- Art For All’s detailed guide to NFT ratings from June, 2021
- dhof’s “Michelin guide” tweet from June, 2021
- kwigbelle’s June 2021 guide to Avastar SVG retrieval on Etherscan
- simondlr’s “Flavours of On-Chain SVG NFTs on Ethereum” from August, 2021 (thorough, wide ranging)
- divergencearran’s great thread from September 2021 about the Mandala Tokens project
- emrecolako’s superb guide to on-chain projects (see 0xchainArt)
- Article from the MoonCat community: “On Chain”, “Generative” “Art”?
Endnotes and Disclosures
- I’m obviously abstracting over what kind of node, but indeed a full node (not archival) may be sufficient for most purposes.
- 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.
- 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. Update: I was indeed not paid for this post, but Etherscan offered a very small token of thanks after it was released and I accepted.