Resource guide

Making NFTs on Cardano, from policy to wallet.

Everything a creator needs before minting: how policies fix supply, which metadata standard to use, where the media should live, what a mint costs today, how wallets sign, which tools to use, how to test, and what to check before launch.

01

What an NFT is on Cardano

Cardano tokens are native assets. The ledger tracks them directly, in the same UTxOs that hold ADA, so sending an NFT is an ordinary transaction. No token contract runs when it moves.

Every token is identified by two parts:

  • Policy ID: the 28-byte (56 hex character) hash of the minting policy script. Because it is a hash of the rules, the rules are bound to the token forever.
  • Asset name: up to 32 bytes that distinguish tokens under one policy. It can be empty.

Together they form the asset ID, policyId.assetName. An NFT is simply a token whose quantity is exactly 1 and whose policy guarantees that no second unit can ever be minted. The same asset name under a different policy is a different token.

The asset fingerprint (CIP-14)

Wallets and explorers often show a short asset1… string. CIP-14 defines it as a bech32 encoding of the blake2b-160 hash of policy ID and asset name concatenated. It is a convenient label, not a separate identity: two fingerprints match only if policy and name both match.

The policy ID is the authenticity anchor. Names, images and descriptions can be copied by anyone. Only the policy ID proves which issuer and which rules produced a token.

02

Minting policies: who can mint, when, and how many

Whenever a transaction mints or burns tokens under a policy, that policy's script runs and must succeed. Positive quantities mint; negative quantities burn. A policy can allow one and forbid the other.

Native scripts: signatures and time

The simplest policies need no smart contract. A native script combines signature and time conditions. The standard NFT pattern requires the issuer's signature and only works before a chosen slot:

{
  "type": "all",
  "scripts": [
    { "type": "before", "slot": 90000000 },
    { "type": "sig", "keyHash": "<policy key hash>" }
  ]
}

Once that slot passes, nobody can mint again under the policy, so the supply is provably fixed. Set the slot deliberately: a slot already in the past makes the policy unusable from the start.

Plutus policies: rules as code

When signatures and time are not enough, the policy is a validator written in a language such as Aiken and compiled to Plutus. Common patterns:

  • One-shot: the policy requires one specific UTxO to be spent. A UTxO can be spent only once, so the policy can succeed only once in history. This is the protocol-level way to guarantee uniqueness.
  • Parameterized: values such as that UTxO are baked into the script at build time, so each configuration gets its own policy ID.
  • Stateful (state thread): a one-shot mint creates a single state token held at a script address; every later mint must spend and advance that state. This lets a finite, pre-committed collection be issued across many transactions. Data is Beautiful uses this pattern (see section 11).
What each policy type can guarantee
PolicyWhat it guaranteesWhat it does not
Signature only (native)Only the key holder can mint or burnAny supply limit: the key can mint again at any time
Signature + before slot (native)No minting after the slot, so supply is fixed once it passesWhat was minted before the deadline, or in what order
One-shot (Plutus)Exactly one minting transaction, everAnything after that single transaction; the whole collection must fit in it
State thread / finite registry (Plutus)A committed list of assets, each minted at most once, in the order the script allows, across many transactionsAnything the script does not check (metadata, for example)

How a collector can check that a policy is closed

  • Native script: get the script from the creator's own site, confirm its hash equals the policy ID, and confirm the before slot is in the past.
  • Plutus policy: get the published source and blueprint, rebuild it, apply the published parameters, and confirm the resulting hash equals the policy ID. With Aiken that is aiken build, aiken blueprint apply and aiken blueprint policy. Then read the code, or rely on an independent review, to understand what it allows.
03

Metadata standards: CIP-25, CIP-68 and CIP-27

CIP-25: metadata in the minting transaction

CIP-25 (the media token metadata standard) attaches name, image and other properties to the transaction that mints the token, under metadata label 721. Its rules:

  • name and image are required. image must be a full URI with a scheme, such as ipfs://….
  • mediaType, description and files are optional; inside each files entry, mediaType and src are required.
  • Every ledger metadata string is limited to 64 bytes. Longer values, such as long URIs, become an array of chunks that viewers join back together.
  • Version 1 uses the policy ID and asset name as text map keys (the asset name must be UTF-8). Version 2 ("version": 2) uses their raw bytes as keys, which suits asset names that are not readable text.
{
  "721": {
    "<policy_id>": {
      "<asset_name>": {
        "name": "Plate 1",
        "image": ["ipfs://", "bafy…"],
        "mediaType": "image/png",
        "description": "One of one.",
        "files": [{ "name": "Plate 1", "mediaType": "image/png", "src": ["ipfs://", "bafy…"] }]
      }
    },
    "version": 2
  }
}

In version 2 the two keys shown as placeholders are raw byte strings in the actual transaction, not hex text. Because the metadata lives in the minting transaction, it cannot be changed later.

CIP-68: metadata in a datum

CIP-68 mints two tokens under the same policy: a reference NFT (label 100) locked in an output whose datum holds the metadata, and a user token that the owner holds (label 222 for NFTs; 333 and 444 are the fungible and rich-fungible classes). If the reference NFT sits at a script address, that script decides whether and how the metadata can be updated. Scripts can also read the metadata on chain, which CIP-25 metadata cannot offer.

The labels follow CIP-67: each label is a 4-byte prefix at the start of the asset name. The reference NFT for label 100 starts with 000643b0 and a 222 user token starts with 000de140. That leaves 28 of the 32 asset-name bytes for the name itself.

Choosing between CIP-25 and CIP-68
If you needConsider
Fixed metadata written once at mintCIP-25
Metadata that can be updated under rules you defineCIP-68 with the reference NFT at a script
Metadata that other scripts can read on chainCIP-68
The whole 32-byte asset name for your own data (a hash, for example)CIP-25 version 2, since CIP-68 labels use 4 bytes

CIP-27: royalties

CIP-27 records a royalty rate and payout address under label 777, written to a token with an empty asset name under the collection's own policy. Marketplaces are told to honour only the first minted royalty token, so it must be minted before any other asset under that policy. After it is minted, burning it is recommended but not required. This is a community convention that marketplaces choose to follow; the ledger does not enforce payment.

Check marketplace support yourself. We have not verified which marketplaces display CIP-25 version 2 or CIP-68 tokens, or which honour CIP-27. Read each marketplace's own documentation and confirm with a test mint on preprod before you launch.

04

Media and storage

The token itself only carries a pointer to its image, so where that image lives decides how long the NFT stays viewable.

  • Use a scheme. CIP-25 requires ipfs://<CID> (or ar:// for Arweave), never a bare content identifier. Viewers may not find a bare CID.
  • Never split inside a CID. When a URI is longer than 64 bytes, split it into array chunks such as ["ipfs://", "<CID>"]. CIP-25 lists a CID cut in half as invalid.
  • CIDv0 or CIDv1. CIDv0 strings start with Qm, use base58 and a fixed hash and codec. CIDv1, usually bafy… in base32, describes its own hash and codec and is the more future-proof choice. Both are valid in an ipfs:// URI.
  • Pinning is what keeps it alive. A CID only names the content. Someone has to keep serving the bytes, so budget for pinning with more than one provider, or keep the bytes yourself.
  • Fully on-chain media is possible with a data: URI (base64 needs the data:<mime_type>;base64, prefix). It must fit inside the 16,384-byte transaction together with everything else, so it only suits small SVGs and similar files.
  • Record a hash. Putting a SHA-256 of the image bytes in the metadata lets anyone check later that a gateway served the original file. Data is Beautiful records image hashes this way.
05

Costs and limits

These are live Cardano mainnet protocol parameters (Koios, epoch 657, checked 2026-09-26). Governance can change them, so read them from a provider when you build.

Max transaction size
16,384 bytesEverything: inputs, outputs, scripts, witnesses and metadata.
Max execution per transaction
16.5M memory / 10B stepsThe budget for all Plutus scripts in one transaction.
Minimum ADA per output
(160 + output bytes) × 4,310Lovelace per byte, per CIP-55.
Transaction fee
44 × bytes + 155,381Lovelace, plus Plutus execution and reference-script fees.
Other protocol parameters relevant to minting
ParameterMainnet valueWhy it matters
Execution prices0.0577 per memory unit, 0.0000721 per stepPlutus policies pay for the memory and CPU steps they use
Reference-script fee15 lovelace per byte (min_fee_ref_script_cost_per_byte)Applies to scripts a transaction reads from a reference UTxO
Collateral150% of the fee, at most 3 collateral inputsA Plutus transaction must post collateral, which it loses only if a script fails on chain
Max value size5,000 bytesCaps how many different tokens one output can hold
Metadata strings64 bytes eachLonger text must be chunked (see CIP-25)
Asset name0 to 32 bytesSet by the ledger rules

Worked examples

An ADA-only output at a base address encodes to 65 bytes, so it needs at least (160 + 65) × 4,310 = 969,750 lovelace, about 0.97 ADA. The same output holding one NFT with a 32-byte name encodes to 133 bytes and needs 1,262,830 lovelace, about 1.26 ADA. That ADA travels with the NFT; it is not a fee. (Output sizes computed with the Cardano multiplatform library on 2026-09-27; wallets calculate this for you.)

One Data is Beautiful issuance, measured on a full-ledger emulator on 2026-09-26, with the Plutus script attached and a 1,618-byte CIP-25 version 2 metadata envelope:

Measured cost of one Data is Beautiful issuance
MeasureValue
Unsigned transaction size4,152 bytes (about a quarter of the limit)
Fee368,923 lovelace, about 0.37 ADA, covering the two signatures added afterwards
Script memory226,828 (mint) + 41,793 (spend) = 268,621, about 1.6% of the per-transaction memory limit
Script steps70,223,334 (mint) + 13,972,096 (spend)

The fee checks out against the formula: the size component (44 × bytes + 155,381, with each signature adding roughly 100 bytes) plus execution priced at the rates above.

06

Wallets and signing

Browser wallets expose a standard bridge to web pages, CIP-30. A minting site uses a small set of calls:

CIP-30 calls used when minting
CallWhat it does
cardano.<wallet>.enable()Asks the user to connect the wallet to the site
getNetworkId()0 for testnets, 1 for mainnet
getUtxos(), getChangeAddress()The wallet's spendable outputs and where change should go, used to build the transaction
signTx(tx, partialSign)Asks the user to sign. With partialSign true the wallet signs what it can and returns only its signatures (a witness set)
submitTx(tx)Submits a fully signed transaction through the wallet

What to check before you sign

  • The network: a testnet mint should never be signed on a mainnet wallet, and the reverse.
  • What leaves your wallet: the ADA amount and any tokens in the outputs.
  • What is minted: the policy ID and asset name should match what the creator publishes.
  • Your recovery phrase is never needed to mint or to connect. Anyone asking for it is trying to take your funds.

Cardano wallets include Lace, Eternl, VESPR and Yoroi. To connect to a minting site, a wallet needs a browser extension or in-app browser that supports CIP-30. Install wallets only from their official sites.

07

Tooling

Tools for building Cardano NFT mints
ToolUse it forNotes
cardano-cliNative-script policies and manual transactionsBuilds, signs and submits from the command line; the Cardano developer portal walks through a time-locked NFT mint
AikenWriting Plutus V3 policies and validatorsBuilt-in unit and property tests; aiken build writes a CIP-57 blueprint (plutus.json)
Lucid EvolutionBuilding transactions in TypeScriptIncludes an emulator, and by default evaluates Plutus scripts locally while building
KoiosChain data and submissionPublic API, free tier without a key; mainnet, preprod and preview endpoints
BlockfrostChain data, submission and IPFS pinningHosted API with a project key

Provider endpoints you will use

  • Submit: Koios POST /submittx and Blockfrost POST /tx/submit. Both take raw CBOR bytes with Content-Type: application/cbor.
  • Evaluate scripts: Blockfrost POST /utils/txs/evaluate; Koios passes evaluation through to Ogmios at POST /ogmios.
  • UTxOs: Koios POST /address_utxos; Blockfrost GET /addresses/{address}/utxos.
  • Protocol parameters: Koios POST /epoch_params; Blockfrost GET /epochs/latest/parameters.

Koios endpoints are RPC style (JSON bodies, mostly POST); Blockfrost uses REST paths. The preprod bases are https://preprod.koios.rest/api/v1 and https://cardano-preprod.blockfrost.io/api/v0.

Blueprints and multi-purpose scripts

CIP-57 defines the blueprint format that Aiken emits: each validator's compiled code, hash and parameters. Under CIP-69 a single Plutus V3 script can serve several purposes. The same script hash can be both a minting policy and a spending address, which is how a policy can guard its own state.

Pin your compiler. Aiken v1.1.24 and stdlib v4.0.0 were both released on 26 September 2026, and stdlib v4.0.0 renames the Value type to Assets. We build with Aiken v1.1.23 and stdlib v3.1.0, and move to newer versions deliberately. Whatever you choose, pin exact versions and record them with the blueprint.

08

Testing before anything is real

Test in three layers: fast unit tests, then a full-ledger emulator, then a public testnet.

  1. Unit tests against hand-built transactions, in Aiken itself. Fast, and good for covering every branch.
  2. Emulator tests that build real transactions with fees, minimum ADA, collateral and Plutus evaluation, for example with Lucid Evolution's emulator.
  3. Preprod or preview, the public testnets, with test ADA from the official testnet faucet. Only here do you see what real wallets, explorers and marketplaces display.

A lesson from our own build. In Aiken v1.1.23, one of our checks compared the minted tokens with minted == [Pair(name, 1)]. The unit tests passed because they built values in memory. In the emulator, with ledger-built data, the same comparison returned false and every valid mint was rejected. Pattern matching fixed it. Never accept unit tests alone: every branch must also pass the emulator.

Negative tests worth writing

A policy is only as good as what it refuses. Each of these should be rejected by the script itself, not only by your own front end:

  • Minting out of order, or skipping ahead
  • Minting the same asset twice
  • Minting an asset that is not in the collection
  • Minting quantity 2
  • Minting without the required signatures
  • Moving or stealing the state output, including through a burn
  • Initializing the collection a second time
  • Minting after the collection is closed

You can try our policy on preprod with your own wallet at the Data is Beautiful test mint.

09

Launch checklist

What should be settled, in writing, before a mainnet mint:

  • Policy design decided, and reviewed by someone other than its author.
  • Supply frozen: the exact list of assets or the closing slot, published before minting starts.
  • Metadata validated byte-for-byte against the standard you chose, including chunking and key encoding.
  • Media pinned and hashed, with more than one copy, and the hashes recorded in the metadata.
  • Signing-key custody: who holds the keys, how many signatures are required, and how they are backed up.
  • Preprod rehearsal of the whole lifecycle: initialization, several mints, closing, and a burn.
  • Reference-script deployment, if you use one, so that each mint does not carry the full script.
  • Marketplace display checks on the platforms you care about, using a test mint.
  • A public verification page on your own domain that states the policy ID and how to check it.
  • An incident plan: what you pause, what you tell collectors, and how you recover if a mint fails or a key is exposed.
10

Safety for collectors and creators

  • Verify the policy ID on the creator's own website before buying. Look-alike collections can copy every name and image, but not the policy ID.
  • Read what you sign. Check the network, the ADA and tokens leaving your wallet, and the policy of anything being minted.
  • Never share a recovery phrase. No mint, airdrop or support agent needs it.
  • Know whether the policy is locked. A signature-only policy can mint more at any time; a time-locked or one-shot policy cannot.
  • Burning is permanent. If a policy allows holders to burn, a burned token is gone. Whether it could be minted again depends entirely on the policy.
  • Creators: keep policy keys off internet-connected machines where you can, and never reuse a policy key for other purposes.
11

How Data is Beautiful mints

Data is Beautiful turns Cardano blocks into plates of art. Each NFT's asset name is the block's own 32-byte hash, so the collection needs CIP-25 version 2 and a policy that can issue a fixed list over many transactions. Our design:

  • One Plutus V3 policy per finite volume. The script is parameterized by a one-shot seed UTxO, the ordered registry, its size and the issuer keys, so the policy ID commits to all of them.
  • The ordered registry is a hash chain: chain([]) = empty and chain([n, ..rest]) = blake2b-256(n ++ chain(rest)). The policy stores only the chain of the unissued remainder.
  • One state token. Initialization spends the seed and locks a single state token with the full chain and a cursor of 0.
  • Each mint reveals the next block hash. The script checks that hashing it with the rest of the chain matches the stored commitment, mints exactly one unit, and advances the cursor. Skipping, repeating, substituting or minting two units all fail.
  • Closed forever after the last plate. The final state cannot advance, and the seed cannot be spent again to restart.
  • Holders may burn their plates. Burning never touches the state, so a burned plate can never be minted again.
  • Optional CIP-27 royalty token, allowed only at initialization so that it is the policy's first mint.
  • Issuer custody is a required number of signatures from a set of keys (m-of-n).
  • Metadata is CIP-25 version 2 with raw-byte keys. The script cannot see metadata, so the minting software checks it byte-for-byte before signing.

The policy passes 24 Aiken unit tests and 6 lifecycle tests on a full-ledger emulator, including every negative case listed in section 8.

Status. Mainnet minting is not open. Signing-key custody, an independent review of the policy and the launch terms have not been decided. Nothing on this page is an offer to sell.

12

Glossary

Glossary of Cardano NFT terms
TermMeaning
UTxOAn unspent transaction output: ADA and tokens at an address, which a transaction spends whole and replaces with new outputs
Policy IDThe 28-byte hash of the minting policy script; the part of a token's identity that proves who could mint it
Asset nameUp to 32 bytes that distinguish tokens under one policy
FingerprintThe asset1… label from CIP-14: a bech32 blake2b-160 hash of policy ID and asset name
DatumData attached to an output, which scripts can read; CIP-68 stores metadata there
RedeemerThe argument a transaction passes to a script, such as which action to take
CollateralADA a Plutus transaction pledges, and loses only if a script fails on chain
Reference scriptA script stored in an output that other transactions can use without including its bytes
CIPCardano Improvement Proposal: the community process that publishes standards such as CIP-25 and CIP-30
13

Sources

Primary sources used for this guide. CIP pages were read from their original text.

Published 27 September 2026 by Adalion. Corrections update this page and its modified date.