What is ERC-721?
Ethereum's non-fungible token standard — and the gaps a minimum interface left to integrators.
ERC-721 is the standard that made Ethereum the home of the NFT — every CryptoPunk, every Bored Ape, every art drop, every PFP collection speaks the same nine-function interface that Dieter Shirley first drafted in September 2017 and that William Entriken led to final specification on 24 January 2018. That minimalism is exactly why so much built on top of it, and exactly why every team since has paid an integration tax for metadata that goes offline, approvals that drain entire collections, and safe-transfer hooks that the spec itself describes as a deliberate "caller-control" tradeoff. This page walks the history, the ABI, the limits people keep working around, and the LSP8 standard the author of ERC-20 designed instead.
on this page
- What is ERC-721?
- At a glance
- Origin story
- The spec
- What's broken
- tokenURI trap
- setApprovalForAll is collection-wide
- safeTransferFrom is only half a hook
- uint256 tokenIds force a single integer namespace
- One token, one transaction — gas at scale
- Criticism from the source
- LUKSO alternative
- ERC-721 vs LSP8
- When to use which
- FAQ
- Sources
- Keep reading
The standard, in one card.
- Standard
- ERC-721 / EIP-721
- Drafted
- 22 September 2017
- Finalized
- 24 January 2018
- Authors
- Entriken · Shirley · Evans · Sachs
- Required functions
- 9 (8 + ERC-165)
- ID type
- uint256
- Modern alternative
- LUKSO LSP8
- Canonical spec
- eips.ethereum.org / EIP-721
The origin story.#
On 22 September 2017, Dieter Shirley — then CTO at Dapper Labs — opened GitHub issue #721 on the Ethereum repository with a draft proposal for a non-fungible token standard. The team at Dapper Labs was a few months from launching CryptoKitties, and the spec was the substrate they needed: a way for each kitty to be a uniquely-owned on-chain object with its own provenance, transferable through the same primitives that ERC-20 had standardized for fungible balances.
CryptoKitties launched on 28 November 2017 — between Shirley's draft and the spec's finalization — and immediately demonstrated both the thesis and the limits. The thesis: people would pay real money for unique on-chain assets. The limit: ERC-721's one-transfer-per-token model meant the viral growth congested Ethereum, with the network briefly overwhelmed by kitty breeding and trading.
Over the next few months William Entriken took on the lead-author role, joined by Shirley, Jacob Evans, and Nastassia Sachs, and EIP-721 was finalized on 24 January 2018. Entriken's framing — visible in his later interviews and in his GitHub bio ("Lead author of ERC-721") — was that he had deliberately designed "a minimal standard which is ERC-721," after studying use cases that went well beyond the cat-collecting example: government assets, identities, physical goods, provenance.
The minimum interface is a feature, not a limitation. It is what made the rest of the NFT economy possible — the same interface used by CryptoKitties is the one used by Punks, Bored Apes, Art Blocks, and every collection since.
The cost shows up in the parts the spec deliberately left to the application layer. The Rationale section of EIP-721 is honest about one of these tradeoffs:
Different functions are used for
transferandsafeTransferFromto give the caller control over their risk.
That is the authors saying, in plain text, that the safety hook is opt-in by design. The rest of this page is about what each "control over their risk" delegation has cost the people building on the standard since — and how one of the co-authors (Shirley) has framed those costs in retrospect, in the dedicated Criticism from the source section below.
- Sept 2017 Dieter Shirley (CTO, Dapper Labs) opens GitHub issue #721 with a draft proposal for a non-fungible token standard. ↗
- Nov 2017 CryptoKitties launches on 28 November 2017 and immediately exposes ERC-721's per-token gas cost when its growth congests Ethereum.
- Jan 2018 EIP-721 is finalized on 24 January 2018 with William Entriken as lead author, alongside Shirley, Evans, and Sachs. ↗
- 2020-09 ERC-2981 (NFT Royalty Standard) proposed to give NFTs a recommended royaltyInfo function — enforcement is left to the marketplace. ↗
- 2021–22 NFT mania. ERC-721 absorbs PFP collections, generative art, music drops, gaming, and brand experiments. Every limit the spec left to the application layer gets paid for at scale.
- 2022-04 ERC-4906 adds the MetadataUpdate event so contracts can signal that off-chain tokenURI JSON has changed. ↗
- 2023 LUKSO mainnet launches with LSP8 as the native NFT primitive — bytes32 IDs, per-token ERC-725Y metadata, LSP1 receiver hooks, and LSP6 operator scoping. ↗
- 2024–26 Marketplace royalty enforcement debates continue. Transfer-validator patterns and creator-token standards emerge as opt-in policy layers on top of ERC-721, while LSP8 carries the same policy as substrate-level account permissions.
What ERC-721 actually is.#
// EIP-721 — required
function balanceOf(address owner) external view returns (uint256);
function ownerOf(uint256 tokenId) external view returns (address);
function safeTransferFrom(address from, address to, uint256 tokenId, bytes data) external payable;
function safeTransferFrom(address from, address to, uint256 tokenId) external payable;
function transferFrom(address from, address to, uint256 tokenId) external payable;
function approve(address to, uint256 tokenId) external payable;
function setApprovalForAll(address operator, bool approved) external;
function getApproved(uint256 tokenId) external view returns (address);
function isApprovedForAll(address owner, address operator) external view returns (bool);
event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
// EIP-165 — required (interface detection)
function supportsInterface(bytes4 interfaceId) external view returns (bool);
// EIP-721 metadata extension — optional
function name() external view returns (string memory);
function symbol() external view returns (string memory);
function tokenURI(uint256 tokenId) external view returns (string memory);
// EIP-721 receiver — required for safe-transfer destinations
function onERC721Received(address operator, address from, uint256 tokenId, bytes data)
external returns (bytes4);
balanceOf · ownerOf · getApproved · isApprovedForAll transferFrom · safeTransferFrom · approve · setApprovalForAll Transfer · Approval · ApprovalForAll name · symbol · tokenURI The mental model is small: an ownership map (ownerOf), a way to move ownership (transferFrom / safeTransferFrom), a way to delegate authority (per-token approve or collection-wide setApprovalForAll), and three events so the chain can be indexed. The optional metadata extension adds the tokenURI(tokenId) that returns a string — typically a URL pointing to off-chain JSON. EIP-721 mandates ERC-165 (supportsInterface) so consumers can ask a contract whether it implements the NFT interface before calling into it. The canonical specification is at eips.ethereum.org/EIPS/eip-721.
What's broken about ERC-721.#
Five gaps, in order of how often they cost users money or render their collections unviewable. Each one has produced its own follow-on EIP, its own marketplace policy fight, its own startup. None of those follow-ons fix the substrate.
-
The tokenURI trap.#
tokenURI(tokenId) returns one string per token — typically an HTTPS URL or an ipfs:// CID — pointing to off-chain JSON. The contract has no opinion on what the string points to, what the JSON schema should be, whether the host is still up, who can change the contents, or what changed when. The resolution chain is brittle by design: a marketplace fetches the URI, downloads the JSON from a server or IPFS gateway, parses it according to its own interpretation of OpenSea's de-facto metadata schema (name, description, image, attributes, animation_url, external_url), then fetches the image referenced inside the JSON from yet another host. Each hop is a separate point of failure, and none of the points are typed or verified on-chain. When a pinning subscription expires or a backend goes down, the NFT renders blank in every wallet and marketplace simultaneously — a problem that has hit collections worth hundreds of millions of dollars. Marketplaces and wallets cache results on their own schedules, which is why 'refresh metadata' buttons exist: there is no standard signal for what changed. ERC-4906 (April 2022) added a MetadataUpdate event, but it only signals that *something* changed — it doesn't carry the new state, name the affected field, or guarantee anyone re-reads the URI. Dynamic NFTs, on-chain attribute updates, evolving art, royalty configuration, and trait revelations all depend on off-chain infrastructure the spec deliberately leaves undefined. The contract holds the tokenId; everything that makes the NFT visually or semantically real lives somewhere else, on terms set by whoever is hosting it.
ERC-721tokenURI(tokenId) returns (string)LSP8 + LSP4getDataForTokenId(tokenId, key) returns (bytes)workarounds tried- mutable IPFS pointers (still depends on someone pinning the CID)
- Arweave permanent storage (paid once at upload)
- server-rendered metadata APIs (Manifold, Reservoir, custom backends)
- ERC-4906 MetadataUpdate event (signal-only — doesn't carry the new state)
- fully on-chain SVG generators (expensive, awkward for rich media)
- base64-encoded data URIs (on-chain bytes inside the tokenURI string)
-
setApprovalForAll is collection-wide.#
A single signature grants blanket authority over every token in the collection — past, present, and future mints. Marketplaces ask for it once and never have to ask again. The phishing pattern that has drained named NFT collections again and again rides this primitive: trick the holder into one bad signature and every token is gone. Per-token approve exists, but the operator-for-all pattern is the de-facto UX.
ERC-721setApprovalForAll(operator, true)LSP8 + LSP6authorizeOperator(op, tokenId, data)workarounds tried- revoke.cash
- marketplace allowlists
- signed-order patterns
- transfer-validator hooks
-
safeTransferFrom is only half a hook.#
ERC-721 defines IERC721Receiver and a safeTransferFrom variant that checks it — but the check is opt-in, the receiver shape is ERC-721-specific, and the non-safe transferFrom still ships. NFTs land in contracts that have no idea what to do with them. The spec's own Rationale is honest about this: 'Different functions are used for transfer and safeTransferFrom to give the caller control over their risk.' The receiver problem was a deliberate scope-out.
ERC-721onERC721Received(...) returns (bytes4)LSP1universalReceiver(typeId, data)workarounds tried- implement every receiver interface per asset standard
- OpenZeppelin Holder mixins
- sweeper / rescue contracts
-
uint256 tokenIds force a single integer namespace.#
Cheap and predictable for sequential mints. Awkward when the ID needs to mean something — a content hash, a serial keyed to off-chain state, a structured reference. Teams end up maintaining side mappings to translate, and the ID itself stops being self-describing. You read tokenId 42 and have to consult the contract (or a backend) to know what it points to.
ERC-721uint256 tokenIdLSP8bytes32 tokenIdworkarounds tried- off-chain registries
- hash truncation to uint256
- multiple side mappings
-
One token, one transaction — gas at scale.#
Transferring 50 NFTs is 50 transactions. CryptoKitties exposed the consequence at launch in late 2017, when its viral growth congested Ethereum and made the per-token gas tax visible at scale. Every airdrop, marketplace sweep, and inventory migration since has paid the same tax. ERC-721A (Azuki's gas-optimized implementation) batches mints internally but still ships the same one-call-per-token transfer ABI; ERC-1155 redesigned the standard from scratch to fix it.
ERC-721safeTransferFrom(from, to, id) × NLSP8 + LSP25batch ops + relay executionworkarounds tried- ERC-721A (Azuki impl — mint-batching, same transfer ABI)
- ERC-1155 (different standard entirely)
- marketplace bulk-action wrappers
LUKSO designed it differently.#
ERC-721's authors did exactly what a minimum-interface standard is supposed to do — they shipped a primitive small enough to be adopted everywhere, and explicit about the parts they were leaving to application code. The downside is the downside of every minimum spec: every gap turns into a known problem the rest of the industry pays for forever.
Fabian Vogelsteller had already lived this once. He wrote ERC-20 in November 2015 and watched the same dynamic play out on the fungible side: a minimum interface that won the network effect, plus six years of layered EIPs trying to patch what the substrate didn't say. When he co-founded LUKSO with Marjorie Hernandez in 2017 — the same year Shirley drafted ERC-721 — the thesis was direct: design the surrounding system that a minimum interface deliberately can't specify.
For non-fungible tokens, that surrounding system is LSP8. The structural moves are small and deliberate:
bytes32tokenIds. The integer case still works — cast auint256and proceed. The new cases (content hashes, encoded serials, structured references) become first-class instead of side mappings. The ID becomes a typed value, not a counter pretending to be a name.- Per-token ERC-725Y data, via
getDataForTokenId(tokenId, key). The metadata stops being a URL behind a server you don't control. It's a typed key-value graph on-chain, dynamic updates aresetDatacalls gated by LSP6 account permissions, and off-chain media still works — withVerifiableURIwhen you want hash-anchored integrity. - Receiver hooks via LSP1 on every transfer, not only on the opt-in
safeTransferFromvariant. One hook, every asset type, declared policy. - Operator authorization scoped per token and gated through LSP6 on the account side. The collection-wide
setApprovalForAllpattern simply doesn't exist; an operator can be authorized for a specific tokenId, with the controller doing the authorization itself bound by named, revocable permissions.
LUKSO mainnet went live in 2023. LSP8 is an EVM contract — it doesn't require the LUKSO chain to run; it requires the LUKSO chain to cohere. On Ethereum, an LSP8 contract works, but every marketplace and indexer around it still expects ERC-721's ABI. On LUKSO, the substrate matches the standard: Universal Profiles hold the assets, LSP6 authorizes the operators, LSP1 routes the transfer hooks, LSP4 holds the metadata, and a non-fungible token finally gets to live in a system designed for it instead of one bolted on.
The practical takeaway: if an ERC-721 collection depends on fragile tokenURI infrastructure, collection-wide approvals, opt-in receiver hooks, or one-token-per-transfer flows, LSP8 and LSP4 show the NFT model rebuilt around typed IDs, typed metadata, receiver awareness, and account-level permissions.
- LSP8 Identifiable Digital Asset NFTs with bytes32 tokenIds, per-token typed metadata, and the same receiver-aware transfer model as LSP7. The LUKSO direct answer to ERC-721.
- LSP4 Digital Asset Metadata Typed metadata under ERC-725Y keys: name, symbol, description, icon, images, attributes, traits, royalty config — every field is a typed value at a typed key, readable from other contracts (not just from web3 clients) and updatable via account-permissioned setData calls. The VerifiableURI primitive lets a key point to off-chain media with an on-chain hash, so the chain enforces what the off-chain blob must be — no silent swap of the JPEG after sale. Per-token metadata uses the same model via getDataForTokenId(tokenId, key). Replaces the tokenURI string-dance with structured, typed, per-key storage downstream contracts can actually read and reason about.
- LSP1 Universal Receiver One hook for every asset type and every transfer. The receiver problem ERC-721's safeTransferFrom only half-solved, generalised.
- LSP6 Key Manager Operator permissions are account-level, not collection-level. The fix for setApprovalForAll: scoped, named, revocable session keys instead of blanket grants.
- LSP0 ERC-725 Account A smart-contract account that owns and operates NFTs natively — receives via LSP1, holds typed metadata, authorizes through LSP6, recovers through controllers.
- LSP3 Profile Metadata Profiles are first-class on the account: name, avatar, bio, links. NFTs gain a holder identity to display alongside, not just a hex address.
- LSP7 Digital Asset The fungible companion to LSP8 — same receiver model, same operator authorization shape. Multi-asset apps stop implementing four receiver interfaces.
- LSP25 Execute Relay Call Signed messages a third party can submit on-chain. Gasless mint, gasless transfer, gasless onboarding — without bundlers, paymasters, or a bolted-on mempool.
ERC-721 vs LSP8 in one table.#
| row | ERC-721 | LSP8 |
|---|---|---|
| token ID type | uint256 | bytes32 |
| metadata model | tokenURI(id) → string (off-chain JSON, untyped, unverifiable, optional) | getDataForTokenId(id, key) → bytes (typed, on-chain, VerifiableURI-anchored) |
| metadata readable from contracts | no — string return only usable from web3 clients | yes — typed bytes, callable from other contracts |
| off-chain media integrity | trust the host (silent swap possible) | VerifiableURI on-chain hash — swap detectable |
| transfer hook | onERC721Received (only on safeTransferFrom) | universalReceiver (LSP1) on every transfer |
| transfer data payload | bytes _data (only on safeTransferFrom) | bytes data on every transfer + force flag |
| interface ABI | ERC-721 selectors — consumed by code that hardcodes them | distinct LSP8 selectors — won't accidentally dispatch as ERC-721 |
full matrix → erc-721 vs lsp8
FAQ.#
-
What does ERC-721 stand for? #
ERC stands for Ethereum Request for Comments. ERC-721 is the 721st proposal in that series, and it specifies a minimum interface for non-fungible tokens on Ethereum — assets that are unique and individually owned, in contrast to ERC-20's fungible balances. The proposal was formalized as EIP-721 (Ethereum Improvement Proposal 721), which is the canonical specification at eips.ethereum.org/EIPS/eip-721.
-
Who created ERC-721? #
Dieter Shirley, then CTO of Dapper Labs, drafted the original proposal on GitHub on 22 September 2017 as the substrate for CryptoKitties. The finalized EIP-721 was published on 24 January 2018 with William Entriken as lead author, alongside Shirley, Jacob Evans, and Nastassia Sachs. Entriken's GitHub bio identifies him as the 'Lead author of ERC-721'.
-
When was ERC-721 created? #
The GitHub draft proposal opened on 22 September 2017 (ethereum/EIPs issue #721). The formalized EIP-721 was published on 24 January 2018. CryptoKitties launched on Ethereum mainnet on 28 November 2017, between the two milestones, and provided the early load-bearing test of the spec.
-
Is ERC-721 the same as EIP-721? #
Yes — they refer to the same standard. ERC-721 is the original community proposal name (the proposal number assigned to the GitHub issue); EIP-721 is the formalized specification once it moved into the EIP repository. Most developers say ERC-721 in casual use; eips.ethereum.org/EIPS/eip-721 is the authoritative spec.
-
What's the difference between ERC-20 and ERC-721? #
ERC-20 is a fungible token standard — balances are interchangeable. balanceOf(address) returns a uint256 and one token is worth the same as any other token in the contract. ERC-721 is a non-fungible token standard — each tokenId is unique and individually owned via ownerOf(tokenId). Both were proposed by Vogelsteller (ERC-20) and Shirley/Entriken et al (ERC-721) in 2015 and 2017–18 respectively. See ercsolved.dev/erc-20/ for the fungible counterpart.
-
What is an NFT? #
A non-fungible token is a unique, individually-owned, on-chain identifier — most commonly an ERC-721 tokenId on Ethereum or an EVM-compatible chain. The token itself carries little data: it's a uint256 with an ownerOf(...) mapping. Everything visual or semantic about the NFT (image, attributes, description) is typically referenced through tokenURI as off-chain JSON. This is why pinning, hosting, and metadata standards matter so much in practice.
-
What's wrong with ERC-721? #
Five gaps. (1) tokenURI returns one string per token with no on-chain typing or integrity check — pinning failures kill rendering. (2) setApprovalForAll grants blanket collection-wide authority to operators, the primitive behind nearly every NFT phishing drain. (3) safeTransferFrom only checks IERC721Receiver, is opt-in, and is shipped alongside a non-safe transferFrom that strands tokens silently. (4) uint256 tokenIds are awkward for hashes or structured IDs. (5) One transfer = one transaction, which is what CryptoKitties exposed at launch and every airdrop has paid for since.
-
What is LSP8? #
LSP8 is the LUKSO Identifiable Digital Asset standard — the LUKSO equivalent of ERC-721, designed by Fabian Vogelsteller (the author of ERC-20). It keeps ERC-721's ownership model and widens tokenId to bytes32, replaces tokenURI with a typed per-token ERC-725Y key/value store, and routes every transfer through the LSP1 Universal Receiver. Paired with LSP6 on the account side, operator authorization stops being a forever-promise to a marketplace.
-
What is ERC-721A, and does it fix anything? #
ERC-721A is Azuki's gas-optimized implementation of the ERC-721 standard — same external ABI, same selectors, batch-mint optimizations on the internal storage. It materially reduces gas for sequential mints of large collections (the original use case was Azuki's 10,000-piece drop). It does not change tokenURI, doesn't add transfer hooks, doesn't fix the approval model, and doesn't replace the standard. It's an implementation, not a new specification.
-
What about NFT royalties? #
ERC-721 itself does not define royalties — that was a deliberate scope-out. ERC-2981 added a royaltyInfo recommendation in 2020, but enforcement is marketplace-side and inconsistent. On the LUKSO side, LSP8 likewise doesn't define royalties in its base contract; instead, the LSP6 Key Manager and transfer-layer permissions give finer-grained policy control — royalty enforcement becomes a controller decision on the account, not a marketplace policy negotiation.
-
Can I migrate an ERC-721 collection to LSP8? #
Yes. The ownership model is the same, so migration is contract-level rather than user-level. The LUKSO docs publish an end-to-end guide for deploying an LSP8 equivalent and bridging holders; the site's own walkthrough is at ercsolved.dev/build/migrate/erc721-to-lsp8/.
-
What is tokenURI and how does it work in ERC-721? #
tokenURI(tokenId) is the optional ERC-721 function that returns a single string per token — typically an HTTPS URL or an ipfs:// CID — pointing to off-chain JSON describing the NFT. Marketplaces and wallets resolve it by fetching the URI, downloading the JSON, parsing it according to the de-facto OpenSea metadata schema (name, description, image, attributes, animation_url), then fetching the referenced image from yet another host. Nothing about this is enforced on-chain: the contract has no opinion on what the URI points to, what schema the JSON should follow, or whether the host is still up. ERC-721 mandates ERC-165 for interface detection but doesn't mandate the metadata extension at all — it's optional. The result is that 'an NFT' depends on infrastructure outside the contract for everything visual or semantic, which is the source of most NFT metadata problems.
-
Why do NFT images disappear or show as broken? #
Because the actual image isn't on-chain — the contract just stores a tokenURI string pointing to off-chain JSON, which in turn points to the image at another off-chain location. When any link in that chain fails, the NFT renders blank. Common causes: IPFS pinning subscriptions expire and no peer is keeping the CID alive; the backend server hosting the metadata API goes down or is decommissioned; the image hosting (Cloudflare, S3, the project's own server) returns 404 or is taken down; or the project shuts down and metadata stops being maintained. ERC-4906 added a MetadataUpdate event in 2022 so contracts can tell marketplaces 'refresh this token' — but it doesn't fix any of the underlying availability issues. The LSP4 + VerifiableURI model on LUKSO addresses this by putting typed metadata on-chain under ERC-725Y storage and (for off-chain media) anchoring the hash on-chain so the chain enforces what the off-chain blob must be — a swap of the underlying file becomes detectable on-chain.
-
Has any ERC-721 co-author publicly criticised the standard? #
Yes. In a March 2020 Medium essay, Dieter Shirley — co-author of ERC-721 and then-CTO of Dapper Labs (the team that built CryptoKitties) — named three specific shortcomings of the standard he helped design: ERC-721 assumes only Ethereum addresses can own an NFT (asset-owning-asset composability needed the more complicated ERC-998 extension); features can't be added retroactively because deployed Ethereum contracts are immutable; and the central-ledger storage model makes per-asset rent accounting unfair (citing the live CryptoKitties contract: ~2M Kitties, 111MB of on-chain data, all in one mapping). The full verbatim quotes paired with their LUKSO LSP answers are in the 'Criticism from the source' section above (ercsolved.dev/erc-721/#author-criticism). The other three co-authors (William Entriken, Jacob Evans, Nastassia Sachs) don't have equivalent retrospective criticism on the record.
glossary 15 terms used on this page
- NFT
- Non-fungible token. A unique, individually-owned on-chain identifier — most commonly an ERC-721 tokenId. Unlike an ERC-20 balance, each NFT is distinct.
- tokenURI
- The optional ERC-721 metadata function returning a single string URL per token, pointing to off-chain JSON describing the asset. The contract holds the string; the JSON, the schema interpretation, and the image hosting all live elsewhere.
- OpenSea metadata schema
- The de-facto JSON shape NFT marketplaces and wallets interpret tokenURI payloads against: name, description, image, attributes, animation_url, external_url. Not part of EIP-721 — just what the largest indexer expected, and everyone followed.
- ERC-4906
- April 2022 EIP that added the MetadataUpdate(tokenId) event so contracts can signal to marketplaces that a token's metadata changed. Signal-only — doesn't carry the new state or specify which field changed.
- ERC-725Y
- The typed key-value storage substrate underneath every LUKSO account and asset. bytes32 keys map to bytes values, with LSP2 schemas defining how to interpret them. The 'on-chain database' LSP4 metadata lives in.
- VerifiableURI
- An LSP4 metadata primitive that lets an ERC-725Y key point to off-chain media WITH an on-chain hash, so the chain enforces what the off-chain blob must be. A silent swap of the underlying file becomes detectable on-chain.
- data URI
- A URI scheme (data:image/svg+xml;base64,...) that encodes content directly in the URL. Used by on-chain NFT projects to ship the entire image inside tokenURI itself — eliminates the off-chain dependency at the cost of gas.
- IPFS
- InterPlanetary File System. Content-addressed storage commonly used to host NFT metadata and media. Files persist only as long as someone pins them; the address (CID) is permanent but the data may not be.
- Arweave
- A permanent storage network paid for once at upload. Used by NFT projects that want stronger durability guarantees than IPFS pinning.
- pinning
- Telling an IPFS node to keep a file available. If no one is pinning the CID, peers may garbage-collect the content and the NFT becomes unviewable — even though the CID still resolves to nothing.
- mint
- Creating a new NFT — the transaction that calls _mint(to, tokenId) and emits Transfer(0x0, to, tokenId).
- PFP
- Profile-picture NFT. A collection (typically 5,000–10,000 pieces) designed to be used as a social avatar — the dominant NFT format from 2021 onward.
- royalty
- A percentage of secondary-sale proceeds paid to the original creator. Not defined by ERC-721; recommended by ERC-2981; enforced (or not) by marketplaces.
- EIP-2981
- The NFT Royalty Standard. Adds royaltyInfo(tokenId, salePrice) so marketplaces can read a recommended royalty. Compliance is voluntary.
- ERC-165
- Standard for runtime interface detection — supportsInterface(bytes4). ERC-721 mandates ERC-165 so consumers can ask a contract 'are you an NFT?'.
Where this page draws from.#
- Original GitHub issue #721 (Dieter Shirley, 22 Sept 2017)
- EIP-721 finalized specification (24 Jan 2018)
- William Entriken on GitHub (lead author, ERC-721)
- CoinGecko Spotlight #3 — interview with William Entriken
- Dieter Shirley (ERC-721 co-author, Dapper Labs CTO) — "Resource-Oriented Programming: A Better Model for Digital Ownership" (Medium, 23 March 2020)
- ERC-998 Composable Non-Fungible Token Standard (the extension Shirley cited as the workaround for ERC-721's address-owner assumption)
- ERC-2981 NFT Royalty Standard
- ERC-4906 MetadataUpdate event
- LUKSO LSP8 Identifiable Digital Asset docs
- LUKSO ERC-721 → LSP8 migration guide