I am running through the Plutus Pioneer Program and I have reached week 5. Also as a reference, I will use the LobsterChallenge repository. I am a bit confused about how NFTs work for the Cardano blockchain.

From what I understood and me asking in the discord channel when making the policy we accept a TxOutRef as a parameter to the policy. That's all fine, but let's say I want to have 10000 users to mint my collection. Then I need to provide users a way to build, sign, and submit a transaction (To my knowledge I build the off-chain code, and with PAB I provide endpoints the construct everything? Please do correct me If I am wrong as it's still fuzzy for me).

So the off-chain code chooses a TxOutRef from the user's wallet and generates the policy (currency Symbol) by passing the UTXO when compiling the policy

curSymbol :: TxOutRef -> TokenName -> CurrencySymbol
curSymbol oref tn = scriptCurrencySymbol $ policy oref tn

So hopefully I gave some info about what I am talking about and will start with the questions:

  1. Doesn't the curSymbol function return a different currency symbol every time? When that is the case, how do I know that a wallet has been minted from my collection? Do I store this currency symbol in my databases as a reference to the wallet?
  2. What stops a user from getting my code in a public repository and initiating a transaction with a different UTXO
  3. How do I limit mints? Do I mint all 10000 NFTs to a script I create and allow only for the script to mint more (so nobody can try and initiate the policy). And minting 10000 NFTS, wouldn't that require 10000 UTXOs? From what I understand in a UTXO there must be at least 1.25 ADA
  4. I tried understanding the horrorcubes scripts . But got more confused from the:
data CounterDatum = CounterDatum {
        cdValue :: !Integer, -- ^ The current counter value.
        cdLimit :: !Integer  -- ^ The value limit, after this limit is reached, this eUTXO can not be spent again.
    } deriving (Show, Generic, FromJSON, ToJSON)

What do they mean by "The value limit, after this limit is reached, this eUTXO can not be spent again.".

Isn't the purpose of a UTXO to never be spent again? I think these are my questions for now. Thanks a lot to the people who will respond!

1 Answer 1


I totally understand your confusion, in my opinion as explained in the plutus pioneer program is totally unclear the concept of NFT.

identify an NFTs in Cardano

each (fungible) token "collection" is uniquely identified by its AssetClass, which is nothing more than a PolicyHash(equivalent to the policy-id) and a TokenName together

a Non Fungible Token is a Fungible token with a total supply of 1

from the moment that a series of tokens are identified by both the PolicyHash and the TokenName, in order to make the AssetClass unique at the very least one between the PolicyHash and the TokenName has to be unique.


  • HOSKY is a fungible token because the Billions of tokens circulating do have all the same PolicyHash and the TokenName

  • SpaceBudz are an NFT collection because all the tokens do have the same PolicyHash but different (and unique) TokenNames (thanks to the number at the end)

  • an Oracle identifier is an NFT because is generally created thanks to a MintingPolicy parametrized by a TxOutRef

MintingPolicy parametrized by a TxOutRef

in the plutus pioneer program, the given minting policy is guaranteed to make an NFT because a TxOutRef can exist only once and never again (but is NOT the only way to make an NFT as specified above)

so when you do something like

type MyRawRedeemer = BuiltinData

myMintingPolicy :: TxOutRef -> MyRawRedeemer -> ScriptContext -> Bool
myMintingPolicy outRef _reedemer ctx =
    isUTxOSpent && totalSupplyOf1
        isUTxOSpent :: Bool
        isUTxOSpent = -- check between the tx inputs
        totalSupplyOf1 :: Bool
        totalSupplyOf1 = case flattenValue ( txInfoMint ( scriptContextTxInfo ctx ) ) of
            [] -> False -- nothing to mint (should never happen)
            [( sym, _tokenName, amount )] -> -- single asset class minted
                sym == ownCurrencySymbol ctx && 
                amount == 1
            _ -> traceError "multiple assets mints not allowed"

you are sure that this minting policy will be valid only for that transaction and never again, and by checking amount == 1 you are sure that the sìtotal supply is, and will ever be, 1

  • Thank you for your answer! I think I was pretty much focused on the TxOutRef parameterization and how it would work. But I checked the projects you pointed out in the answer and used SpaceBudz to understand the code, but for me, I couldn't find their off-chain code and found only their market. So went deeper and found out this gem Which I think for me gives me a lot of insight, on how I could implement my own NFT collection. Thanks again! Jun 26, 2022 at 12:13
  • the offchain code can be written in any language as long the output is compatible with the protocol. in spacebudz the marketplace is the off-chain code, and it is written in javascript thanks to the cardano-serialization-lib Jun 26, 2022 at 12:21
  • I see. I didn't know that. Thank you again! Jun 26, 2022 at 12:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.