UPDATE:
I'm making progress. It is apparent the TxOutRef
stored on-chain has some extra-structure. For evidence I "printed" the TxOutRef
's of the 'utxo' hard-wired in my minting policy and the one stored onchain. For the former/latter I uncommented the first/second comment in
hasUTxO :: Bool
hasUTxO = case txInfoInputs info of
-- [i] -> traceError . decodeUtf8 . getTxId . txOutRefId $ oref
-- [i] -> traceError . decodeUtf8 . getTxId . txOutRefId . txInInfoOutRef $ i
_ -> traceError "many inputs"
The "printouts", given by the transaction errors returned by cardano-cli were, respectively:
1.
Command failed: transaction build Error: The following scripts have execution failures:
<ommited stuff>
The machine terminated because of an error, either from a built-in function or from an explicit use of 'error'.
Script debugging logs: Redeemer decoded successfully
Script context decoded successfully
9c087132a325f6483aca8398bab1a56eda1390e762984ba054c25cafd738486c
Command failed: transaction build Error: The following scripts have execution failures:
<ommited stuff>
The machine terminated because of an error, either from a built-in function or from an explicit use of 'error'.
Caused by: [
(builtin decodeUtf8)
(con
bytestring #9c087132a325f6483aca8398bab1a56eda1390e762984ba054c25cafd738486c
)
]
Script debugging logs: Redeemer decoded successfully
Script context decoded successfully
It is apparent that in 2. the relevant txOutRefId
is buried inside some extra structure. The question now is, how can I extract the txOutRefId
from all this structure?
ORIGINAL POST:
This simple minting policy should serve to mint an NFT by consuming a UTxO parametrized by TxOutRef
:
{-# INLINABLE mkPolicy #-}
mkPolicy :: TxOutRef -> () -> ScriptContext -> Bool
mkPolicy utxo () ctx = traceIfFalse "UTxO not consumed" hasUTxO
where
info :: TxInfo
info = scriptContextTxInfo ctx
hasUTxO :: Bool
hasUTxO = any (\i -> txInInfoOutRef i == utxo) $ txInfoInputs info
(To simplify, we don’t even check that the number of minted tokens is one, since that is a non-issue here.)
I have been unable to deploy a concrete instance of this minting policy using cardano-cli. I now describe my procedure. Hopefully somebody can point out where the mistake is!
The UPLC policy and corresponding currency symbol are obtained with:
policy :: TxOutRef -> MintingPolicy
policy oref = mkMintingPolicyScript $
$$(PlutusTx.compile [|| mkUntypedMintingPolicy . mkPolicy ||])
`PlutusTx.applyCode`
PlutusTx.liftCode oref
curSymbol :: TxOutRef -> CurrencySymbol
curSymbol = Scripts.scriptCurrencySymbol . policy
Meanwhile I have a wallet on Testnet PreProd with one UTxO:
[bash]$ cardano-cli query utxo --address $(cat wallet1.addr) --testnet-magic 1
TxHash TxIx Amount
--------------------------------------------------------------------------------------
9c087132a325f6483aca8398bab1a56eda1390e762984ba054c25cafd738486c 1 9784666930 lovelace + TxOutDatumNone
so I define an instance of my minting policy with:
oref_1 :: TxOutRef
oref_1 = TxOutRef
{ txOutRefId = TxId "9c087132a325f6483aca8398bab1a56eda1390e762984ba054c25cafd738486c"
, txOutRefIdx = 1
}
policy_1 :: MintingPolicy
policy_1 = policy oref_1
curSymbol_1 :: CurrencySymbol
curSymbol_1 = curSymbol oref_1
(Note that I have enabled the language extension OverloadedStrings
.)
Now I serialize the minting policy and currency symbol, as well as the unit redeemer, with:
Prelude Deploy SimpleMinting> writePolicy "ledger/mint_1.plutus" policy_1
Right ()
Prelude Deploy SimpleMinting> writeCS "ledger/mint_1.hex" curSymbol_1
Prelude Deploy SimpleMinting> writeUnit "ledger/unit.json"
where the commands writePolicy
, writeCS
and writeUnit
are defined in this Deploy.hs.
Now, also inside directory 'ledger', I wrote the shell script 'mint.sh':
cardano-cli transaction build \
--babbage-era \
--testnet-magic 1 \
--tx-in $(cat oref1.tmp) \
--tx-in-collateral $(cat oref1.tmp) \
--tx-out $(cat wallet1.addr)+"2000000 lovelace"+"1 $(cat mint_1.hex).$(cat tokenName.hex)" \
--change-address $(cat wallet1.addr) \
--mint "1 $(cat mint_1.hex).$(cat tokenName.hex)" \
--mint-script-file mint_1.plutus \
--mint-redeemer-file unit.json \
--protocol-params-file protocol-params.json \
--out-file tx.body
('tokenName.hex' was generated with echo -n "FUNKYTOKEN" | xxd -ps > tokenName.hex
.)
Let us verify that 'oref1.tmp' stores the correct TxOutRef
as queried above with cardano-cli:
[bash]$ cat oref1.tmp ; echo
9c087132a325f6483aca8398bab1a56eda1390e762984ba054c25cafd738486c#1
which is indeed correct. So we try to build the transaction by executing:
[bash]$ ./mint.sh
Command failed: transaction build Error: The following scripts have execution failures:
the script for policyId 0 (in the order of the PolicyIds) failed with:
The Plutus script evaluation failed: An error has occurred: User error:
The machine terminated because of an error, either from a built-in function or from an explicit use of 'error'.
Script debugging logs: Redeemer decoded successfully
Script context decoded successfully
UTxO not consumed
PT5
The "UTxO not consumed" error message implies that my Minting Policy fails to recognize the TxOutRef
. I am really puzzled about what am I doing wrong.
For reference, here is the complete haskell code for the plutus minting policy: SimpleMinting.hs.