<p>I totally understand your confusion, in my opinion as explained in the plutus pioneer program is totally unclear the concept of NFT.</p>
<h1>identify an NFTs in Cardano</h1>
<hr />
<p>each (fungible) token &quot;collection&quot; is uniquely identified by its <code>AssetClass</code>, which is nothing more than a <code>PolicyHash</code>(equivalent to the policy-id) and a <code>TokenName</code> together</p>
<p><strong>a Non Fungible Token is a Fungible token with a total supply of 1</strong></p>
<p>from the moment that a series of tokens are identified by both the <code>PolicyHash</code> and the <code>TokenName</code>, in order to make the <code>AssetClass</code> unique at the very least one between the <code>PolicyHash</code> and the <code>TokenName</code> has to be unique.</p>
<p>examples:</p>
<ul>
<li><p><strong>HOSKY</strong> is a fungible token because the Billions of tokens circulating do have all the same <code>PolicyHash</code> and the <code>TokenName</code></p>
</li>
<li><p><strong>SpaceBudz</strong> are an NFT collection because all the tokens do have the same <code>PolicyHash</code> but different (and unique) <code>TokenName</code>s (thanks to the number at the end)</p>
</li>
<li><p>an <strong>Oracle identifier</strong> is an NFT because is generally created thanks to a <code>MintingPolicy</code> parametrized by  a <code>TxOutRef</code></p>
</li>
</ul>
<h1><code>MintingPolicy</code> parametrized by  a <code>TxOutRef</code></h1>
<hr />
<p>in the plutus pioneer program, the given minting policy is <strong>guaranteed</strong> to make an NFT because a <code>TxOutRef</code> can exist only once and never again (but <strong>is NOT</strong> the only way to make an NFT as specified above)</p>
<p>so when you do something like</p>
<pre><code>type MyRawRedeemer = BuiltinData

myMintingPolicy :: TxOutRef -&gt; MyRawRedeemer -&gt; ScriptContext -&gt; Bool
myMintingPolicy outRef _reedemer ctx =
    isUTxOSpent &amp;&amp; totalSupplyOf1
    where
        isUTxOSpent :: Bool
        isUTxOSpent = -- check between the tx inputs
        
        totalSupplyOf1 :: Bool
        totalSupplyOf1 = case flattenValue ( txInfoMint ( scriptContextTxInfo ctx ) ) of
            [] -&gt; False -- nothing to mint (should never happen)
            [( sym, _tokenName, amount )] -&gt; -- single asset class minted
                sym == ownCurrencySymbol ctx &amp;&amp; 
                amount == 1
            _ -&gt; traceError &quot;multiple assets mints not allowed&quot;
</code></pre>
<p>you are sure that this minting policy will be valid only for that transaction and never again, and by checking <code>amount == 1</code> you are sure that the sìtotal supply is, and will ever be, 1</p>

CC BY-SA 4.0
2022-06-26T12:13:34.953Z
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](https://github.com/dcSpark/fracada-il-primo)


Which I think for me gives me a lot of insight, on how I could implement my own NFT collection. 

Thanks again!
Kaloyan Yosifov
CC BY-SA 4.0
2022-06-26T12:21:22.747Z
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```
Michele Nuzzi
CC BY-SA 4.0
2022-06-26T12:23:41.467Z
I see. I didn't know that. 

Thank you again!
Kaloyan Yosifov
CC BY-SA 4.0
2022-06-26T10:15:21.077Z
2022-06-26T10:15:21.077Z
Michele Nuzzi
<p>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.</p>
<p>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).</p>
<p>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</p>
<pre><code>curSymbol :: TxOutRef -&gt; TokenName -&gt; CurrencySymbol
curSymbol oref tn = scriptCurrencySymbol $ policy oref tn
</code></pre>
<p>So hopefully I gave some info about what I am talking about and will start with the questions:</p>
<ol>
<li>Doesn't the <code>curSymbol</code> 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?</li>
<li>What stops a user from getting my code in a public repository and initiating a transaction with a different UTXO</li>
<li>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 <code>1.25 ADA</code></li>
<li>I tried understanding the horrorcubes scripts . But got more confused from the:</li>
</ol>
<pre><code>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)
</code></pre>
<p>What do they mean by &quot;The value limit, after this limit is reached, this eUTXO can not be spent again.&quot;.</p>
<p>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!</p>

<plutus><plutus-pioneer-program><nft><haskell>
Cannot wrap my head on NFTs
# Cannot wrap my head on NFTs

(Asked by: username_0 on 2022-06-25)

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:

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?
What stops a user from getting my code in a public repository and initiating a transaction with a different UTXO
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
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!

**Tags:** plutus, plutus-pioneer-program, nft, haskell

---

## 1 answers

### Answer by username_1 on 2022-06-26. Score: 0 | Accepted answer

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.
examples:

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
    where
        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

> **Comments:**
> **username_0**: 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](https://github.com/dcSpark/fracada-il-primo)   Which I think for me gives me a lot of insight, on how I could implement my own NFT collection.   Thanks again!  
> **username_1**: 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```  
> **username_0**: I see. I didn't know that.   Thank you again!  

---

