<p>Minting validator functions only take two arguments: Redeemer and ScriptContext whereas your <code>nft_policy</code> function is defining three.</p>
<p>Here's an updated version of your validator that uses the most recent version of Aiken as of this post (v1.0.29-alpha)</p>
<pre class="lang-rust prettyprint-override"><code>use aiken/dict.{to_pairs}
use aiken/list
use aiken/transaction.{Mint, OutputReference, ScriptContext, Transaction}
use aiken/transaction/value.{from_minted_value, tokens}

// NFT policy (same as week05's one)
validator(utxo_ref: OutputReference, token_name: ByteArray) {
  fn nft_policy(_r: Data, ctx: ScriptContext) -&gt; Bool {
    // Pattern-match to get policy_id and Fail if it's not a minting transaction
    expect Mint(policy_id) = ctx.purpose
    // Pattern-match to get the transaction inputs and minted values
    let ScriptContext { transaction: Transaction { inputs, mint, .. }, .. } =
      ctx
    // Pattern-match to get the minted tokens and Fail if it's not a single asset minted
    expect [Pair(asset_name, amount)] =
      mint |&gt; from_minted_value() |&gt; tokens(policy_id) |&gt; to_pairs()

    // Check if the transaction consumes the utxo_ref passed as parameter
    let is_ouput_consumed =
      list.any(inputs, fn(input) { input.output_reference == utxo_ref })
    // Final checks
    is_ouput_consumed? &amp;&amp; (1 == amount)? &amp;&amp; (asset_name == token_name)?
  }
}
</code></pre>
<p>You can checkout a runnable version this example using the Lucid emulator on the <a href="https://github.com/wowica/jungle_vault?tab=readme-ov-file#plutus-pioneer-nft-example" rel="nofollow noreferrer">following Github repo.</a></p>
<p>If you try changing the amount to anything greater than <code>1n</code> <a href="https://github.com/wowica/jungle_vault/blob/main/run_ppp_emulation.ts#L79-L80" rel="nofollow noreferrer">on this line</a> you will notice the mint fails.</p>

CC BY-SA 4.0
2024-07-12T23:54:33.987Z
Strangely, if i remove the `_d: Data` argument from the `nft_policy` validator function, then i do get an error when i try to mint with the wrong inputs. but if i have it as unused  `fn nft_policy( _d: Data, _r: Data, ctx: ScriptContext)`  i'm again able to mint incorrectly. Now i'm confused about when to provide the necessary arguments, used and unused (with underscore)
tyvan266
CC BY-SA 4.0
2024-07-13T12:09:19.113Z
Oh I think I see the issue with your code. A Mint function from a validator only takes 2 arguments: a Redeemer and ScriptContext. My guess is that when you define a function with 3 arguments, it's not being run during mint hence you are able to mint as many tokens as you want.
caike
CC BY-SA 4.0
2024-07-12T20:11:25.553Z
2024-07-13T12:11:32.857Z
2024-07-13T12:11:32.857Z
caike
<p>The aiken validator from the lecture is</p>
<pre><code>validator(utxo_ref: OutputReference, token_name: AssetName) {
  fn nft_policy(_d: Data, _r: Data, ctx: ScriptContext) -&gt; Bool {
    expect Mint(policy_id) = ctx.purpose
    let ScriptContext { transaction: Transaction { inputs, mint, .. }, .. } =
      ctx
 
    expect [(asset_name, amount)] =
      mint |&gt; from_minted_value() |&gt; tokens(policy_id) |&gt; to_list()
    let is_output_consumed =
      list.any(inputs, fn(input) { input.output_reference == utxo_ref })

    is_output_consumed? &amp;&amp; (1 == amount)? &amp;&amp; (asset_name == token_name)?
  }
}
</code></pre>
<p>I am able to mint my tokens in lucid, but the validator does not fail when I set n &gt; 1 in</p>
<pre><code>const tx = await lucid 
    .newTx()
    .mintAssets({ [token]: 7n }, Data.void())   
    .attachMintingPolicy(policy)
    .collectFrom([utxo], Data.void())             
    .complete()

</code></pre>

<plutus-pioneer-program><lucid><aiken>
Aiken Mint NFT code allows minting of more than one
# Aiken Mint NFT code allows minting of more than one

(Asked by: username_0 on 2024-07-11)

The aiken validator from the lecture is
validator(utxo_ref: OutputReference, token_name: AssetName) {
  fn nft_policy(_d: Data, _r: Data, ctx: ScriptContext) -> Bool {
    expect Mint(policy_id) = ctx.purpose
    let ScriptContext { transaction: Transaction { inputs, mint, .. }, .. } =
      ctx
 
    expect [(asset_name, amount)] =
      mint |> from_minted_value() |> tokens(policy_id) |> to_list()
    let is_output_consumed =
      list.any(inputs, fn(input) { input.output_reference == utxo_ref })

    is_output_consumed? && (1 == amount)? && (asset_name == token_name)?
  }
}

I am able to mint my tokens in lucid, but the validator does not fail when I set n > 1 in
const tx = await lucid 
    .newTx()
    .mintAssets({ [token]: 7n }, Data.void())   
    .attachMintingPolicy(policy)
    .collectFrom([utxo], Data.void())             
    .complete()

**Tags:** plutus-pioneer-program, lucid, aiken

---

## 1 answers

### Answer by username_1 on 2024-07-12. Score: 0 | Accepted answer

Minting validator functions only take two arguments: Redeemer and ScriptContext whereas your nft_policy function is defining three.
Here's an updated version of your validator that uses the most recent version of Aiken as of this post (v1.0.29-alpha)
use aiken/dict.{to_pairs}
use aiken/list
use aiken/transaction.{Mint, OutputReference, ScriptContext, Transaction}
use aiken/transaction/value.{from_minted_value, tokens}

// NFT policy (same as week05's one)
validator(utxo_ref: OutputReference, token_name: ByteArray) {
  fn nft_policy(_r: Data, ctx: ScriptContext) -> Bool {
    // Pattern-match to get policy_id and Fail if it's not a minting transaction
    expect Mint(policy_id) = ctx.purpose
    // Pattern-match to get the transaction inputs and minted values
    let ScriptContext { transaction: Transaction { inputs, mint, .. }, .. } =
      ctx
    // Pattern-match to get the minted tokens and Fail if it's not a single asset minted
    expect [Pair(asset_name, amount)] =
      mint |> from_minted_value() |> tokens(policy_id) |> to_pairs()

    // Check if the transaction consumes the utxo_ref passed as parameter
    let is_ouput_consumed =
      list.any(inputs, fn(input) { input.output_reference == utxo_ref })
    // Final checks
    is_ouput_consumed? && (1 == amount)? && (asset_name == token_name)?
  }
}

You can checkout a runnable version this example using the Lucid emulator on the following Github repo.
If you try changing the amount to anything greater than 1n on this line you will notice the mint fails.

> **Comments:**
> **username_0**: Strangely, if i remove the `_d: Data` argument from the `nft_policy` validator function, then i do get an error when i try to mint with the wrong inputs. but if i have it as unused  `fn nft_policy( _d: Data, _r: Data, ctx: ScriptContext)`  i'm again able to mint incorrectly. Now i'm confused about when to provide the necessary arguments, used and unused (with underscore)  
> **username_1**: Oh I think I see the issue with your code. A Mint function from a validator only takes 2 arguments: a Redeemer and ScriptContext. My guess is that when you define a function with 3 arguments, it's not being run during mint hence you are able to mint as many tokens as you want.  

---

