JPEG Unplugged

An Ethereum NFT survival test

Your NFT.
No internet.
Now what?

If the internet outside Ethereum disappeared tomorrow, how many NFTs would still exist?

Pull the plug. Watch the pixels go dark.
Then see which artworks survive below. ↓

– collections as pixels● LIVE TEST

One pixel per collection.

-

Reading the census…

Read the pixel grid

    Famous names. Fragile connections.

    The 100 biggest NFT collections

    100 collections. Pull the plug.

        Tap a name for its row and evidence. × = dead or degraded delivery.

        Source: CryptoSlam’s wash-filtered all-time Ethereum ranking; 3 sampled tokens each. See the full table ↓

        The findings / beyond the gallery

        “On-chain” has fine print.

        The art can live forever. Its dependencies might not.

        Receipts, not promises

        Show me the data.

        Non-spam Ethereum NFT collections with at least 100 holders, and what its token pointers actually point at.

        The top 100: every row

        Ranked by all-time sales. Select a name for control details and saved evidence. Back to the wall ↑

        Top 100 metadata, media, liveness and control
        RankCollectionMetadataMediaDelivery todayWho can change itEvidence

        Where does the art live?

        Does it load today?

        On-chain JSON, off-chain media

        Does age matter?

        Whose gateway is baked in?

        Project storage claims, reviewed

          These counts cover the full reviewed claimant set, including collections outside the random sample. It is a discovery-biased set, not an estimate for all NFTs. Outcomes concern each statement's scope; storage does not establish immutable control or successful rendering.

          Every collection

          Method, limits, prior art

          Public evidence records list each call and fetch (URL, status, time, SHA-256); corrections welcome.

          The top 100

          The wall uses CryptoSlam’s wash-filtered all-time Ethereum sales ranking in historical USD, with duplicate contract aliases removed. It is a separate famous-collection panel, not the random census or a definitive global ranking. Three token units per collection were checked (306 in total across source-listed contracts); 888 Inner Circle has only two distinct IDs, with a second fungible unit sampled. Small samples do not establish collection-wide health.

          “Fully on-chain” requires metadata and every declared sampled media field on-chain, including CryptoPunks’ separately sealed legacy data renderer. The wall colours the media route; mixed routes use web server, then IPFS, then Arweave, with unresolved media coloured by its metadata route. Broken means the contract returned no usable metadata. Unplugging keeps only the six fully on-chain routes lit; this is a route illustration, not a browser render test. Alternate recovery contracts may exist.

          “Dead or degraded” describes repeated sampled metadata or primary-image failures in this snapshot; unknown responses are excluded. Mooncats refers to the ranked wrapper’s empty metadata, not a dead legacy artwork. Art Gobblers has two loading samples and one repeated 404. One-key repointing counts live EOA pointer powers, excluding data-only edits. Server dependence counts ordinary HTTP metadata or media; dependencies overlap. Withheld origins remain unnamed. Full snapshot and definitions.

          What we counted

          The unit is one Ethereum mainnet ERC-721 or ERC-1155 collection contract with at least - holders, as of -. For each, we read tokenURI (or uri) with eth_call for sampled tokens, classified where the metadata JSON and the image or animation live, and then tried to fetch them. Every row links to a record of the calls and fetches (URL, status, time and SHA-256).

          The classes: data-uri (a data: URI stored in the contract), onchain-renderer (a data: URI the contract builds when you call it), ipfs, arweave, http, broken (reverts, empty, undecodable), and unknown for media whose location cannot be read because the off-chain metadata that names it could not be fetched. The fully on-chain candidate set has metadata and sampled media on-chain, with no external reference detected by a static scan. It is an upper bound on art that survives; rendering was tested only for the gallery set. The census includes financial position and receipt NFTs. The "On-chain JSON, off-chain media" chart counts any off-chain media field, including animation_url.

          Liveness is conservative. Timeouts, rate limits and bot walls are recorded as unknown. Rows labelled metadata unavailable failed to return usable metadata after retries. Direct negative evidence includes DNS, TLS, HTTP errors, malformed URIs, invalid JSON, connection errors and parked responses. Contract call reverts and IPFS or Arweave content not found through public gateways are separate categories; neither establishes permanent content loss.

          Takeover-risk candidates include hosts that look like deleted cloud resources whose names may be re-creatable; reclaimability was not tested. Hostnames are withheld from the public data.

          How the gallery is rendered

          For each gallery token we read the art from the chain only. Most contracts return a data: URI; for Art Blocks we call its on-chain generator contract, which assembles the page from the project script and its dependencies. The result is a self-contained HTML or SVG file. The page above loads that file into an iframe with sandbox="allow-scripts" and no allow-same-origin.

          • Plugged in runs the file as is, so it can fetch whatever it asks for.
          • Unplugged puts a Content-Security-Policy meta tag first inside the document head: default-src 'none'; script-src 'unsafe-inline' 'unsafe-eval' data: blob:; connect-src data: blob:; style-src 'unsafe-inline' data:; img-src data: blob:; font-src data:; media-src data: blob:. The browser refuses every network request, and the piece's own code still runs. The policy includes connect-src data: blob: so pieces can fetch() a data: URI that is part of their own bytes, for example a shader; that reaches nothing outside the document.
          • Unplugged + archive serves the same file with each declared dependency (for example processing.js from cdnjs) copied inline from a local archive.

          Pieces report what they try to fetch, and what breaks, back to the page with postMessage; the small counters on each tile come from that, live. The verdict labels (identical, broken, restored) come from a separate, scripted run in headless Chromium that compared screenshots under each condition; its evidence is in the repository.

          Who can change the art

          The historical mutation audit covers - contracts selected for on-chain data or candidate claims. We read verified source for URI setters, renderer swaps, data edits and upgrades, then checked the gates with owner(), access-control roles, proxy admin slots and freeze flags. Classes include the recorded renderer or descriptor dependencies. Broad mutation classes include data-only edits; repointability requires a live effective URI, renderer or upgrade path. This retains the original control-state observations and limited dependency coverage, rather than claiming a fresh exhaustive audit. The reviewed project-authored storage statements and their outcomes are assessed independently. The displayed swap history comes from the saved setter CSV.

          Limits

          • This is a snapshot of one day's fetches. Servers that are down tonight can come back, and the reverse.
          • The census unit is the collection. A collection with a million tokens counts once, and we sample tokens inside each collection.
          • Collections with at least 100 holders is a popularity cut. It leaves out the long tail, where link rot is probably worse.
          • "Alive" means a fetch succeeded. Comparing the bytes with what the artist minted (hash checks) is future work.
          • The gallery is a hand-assembled set of on-chain candidates. How common each outcome is comes from the census.
          • The gallery tests the chain as it is today. Art Blocks' on-chain dependency registry is controlled by an admin, and the same generator call produced a CDN script tag before p5.js was uploaded on-chain in 2024.
          • Nouns’ tokenURI needs ~119M gas. Of six public RPCs that answered, three refused it even at 150M, one needed gas set by hand and two served it by default. We also read it from a local fork of mainnet pinned at a fixed block.
          • The CSP blocks fetches, forms and frames. The sandbox blocks navigation and popups. WebRTC is untested.
          • The thumbnails and verdicts come from headless Chromium with software WebGL; WebGL pieces run faster on a real GPU.

          Prior art

          People have measured NFT link rot and storage before us. What we add is a 2026 snapshot, a by-deploy-year breakdown, a test of whether "on-chain" art draws with the network off, and a comparison of "fully on-chain" claims with what the contracts do. We did not find earlier work on those four points, in a search that was careful but not exhaustive.

          That Art Blocks pieces depend on a CDN-hosted p5.js was known before this project (Right Click Save, 2023; Art Blocks' own documentation). What we measure is how far it goes, across more than one platform.

          Data and code