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

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!

**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) `TokenName`s (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!  

---

