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

```rust
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.](https://github.com/wowica/jungle_vault?tab=readme-ov-file#plutus-pioneer-nft-example)

If you try changing the amount to anything greater than `1n` [on this line](https://github.com/wowica/jungle_vault/blob/main/run_ppp_emulation.ts#L79-L80) 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.  

---

