I'm currently going through week 5 of the plutus piooner lectures, and I have some questions about the NFT process. Here is a reference with the complete code, but here are the important parts:
The on-chain part makes sense to me. We want our NFT to be unique, so we take as input a UTxO (always is unique) and check that we're minting only one token:
mkPolicy :: TxOutRef -> TokenName -> ScriptContext -> Bool
mkPolicy oref tn ctx = traceIfFalse "UTxO not consumed" hasUTxO &&
traceIfFalse "wrong amount minted" checkMintedAmount
where
...
The off-chain part is what brings me some confusion, so let's lay down what we want to achieve:
We need to build a transaction that spends a specified UTxO and mints only one token.
The most relevant part of the off-chain code is this:
let val = Value.singleton (curSymbol oref tn) tn 1
lookups = Constraints.monetaryPolicy (policy oref tn) <> Constraints.unspentOutputs utxos
tx = Constraints.mustForgeValue val <> Constraints.mustSpendPubKeyOutput oref
I understand that
mustSpendPubKeyOutput
makes sure that the transaction to be built contains the necessary UTxO (oref
) so that the on-chain policy passes. What happens behind the scenes? If the constraint is not specified Plutus will just use it's own logic to grab the UTxO used for building this transaction? If the constraint is not specified, is there still a chance that the right UTxO will be used?What we need is to build a transaction that spends the required UTxO. One way of doing this is what we done before by specifying a constraint. But what if we only pass one UTxO to the lookup? Then transaction will be forced to be built with that UTxO right? There are no other options to be picked. Well, I tried that and it fails, this very clearly proves my understanding is wrong, why?
So far in the course we never had to pass UTxOs on the lookups and Plutus was able to find them automatically. Why it's only in this specific scenario that we need?