Hey I have this simple stupid validator:

validator {
  fn nft(datum: Datum, _redeemer: Void, context: ScriptContext) {
    let ScriptContext { transaction, purpose } = context
    when purpose is {
      Mint(policy_id) -> False
      _ -> False

Now when performing a call to this validator to Mint it still returns True for the transaction and the native token is minted. I'm confused, how can this be?

2 Answers 2


That is because the interface of the source you have is for a spending validator, and NOT for a minting policy.

Let me explain.

for the chain there is not difference between spending validators and minting policies, it is all just UPLC.

on top of that, the node considers any script that doesn't fail (aka. never evaluates an error) to be correct.

so when you run a script you apply a bunch of data and then you only check if it throws an error or not.

now, the key difference is that a spending validator expects 3 pieces of data ( datum, redeemer, context );

all the others (minting policies, staking validators, etc) expect only 2 pieces of data ( redeemer and context )

when you use your source ( that takes 3 inputs ) as a minting policy ( which expects 2 inputs ) the node only passes 2 of the 3 inputs.

now applying those two inputs is equivalent to a partial function application.

so the result of the application is a new function, and it is a totally valid evaluation because no error is evaluated!

basically, when applying only two inputs (as in this case) the evaluation always succeeds.

NOTE: behind the scenes aiken (and also plu-ts and many other languages) are wrapping your contract that returns a boolean in a simple "if then else" that evaluates an error if the condition is false!

  • Been trying so many different thinks... Also had with a redeemer datum and context only but also got an error. Seems like I must have forgotten to compile or something. It works now at least thank you
    – user9852
    Aug 20, 2023 at 15:14

There is a misunderstanding regarding "Script purpose". From Alonzo ledger document,

The script purpose is passed to it to allow the script to reference itself via its hash, and to be aware of what it is validating.

So for minting policy, it's often useful to know minting policy script's own currency symbol, which would hence be given via Mint script purpose.

For the validator which is taking in datum, then it's purpose is exactly to validate spending of script outputs. I.e., validating spending of a UTxO locked in this phase-2 script. It's script purpose can't be Mint as your code is assuming, but has to be Spending, where it would give you the output reference of the UTxO being spent in question.


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.