I tried to use the inline datum of a reference input in the minting policy below:
{-# INLINABLE validateMinting2 #-}
validateMinting2 :: TxOutRef -> BuiltinData -> BuiltinData -> ()
validateMinting2 oref _ rawCtx =
check $
if not hasUsedUTXO
then not $ cdEndContract contractData
else True
where
ctx = unsafeFromBuiltinData rawCtx
symbol = ownCurrencySymbol ctx
info = scriptContextTxInfo ctx
inputs = txInfoInputs info
contractData = case filter f $ map m $ txInfoReferenceInputs info of
[TxOut{txOutDatum}] -> case txOutDatum of
NoOutputDatum -> traceError "NoDat"
OutputDatumHash _ -> traceError "Hash"
OutputDatum (Datum d) -> case fromBuiltinData @ContractData d of
Just dat -> dat
_ -> traceError "nothing"
_ -> traceError "nope"
where
f TxOut{txOutValue} = valueOf txOutValue symbol contractDataTokenName == 1
m inInfo = txInInfoResolved inInfo
hasUsedUTXO :: Bool
hasUsedUTXO
| [_] <- filter ((oref ==) . txInInfoOutRef) inputs = True
| otherwise = False
When I use the cli to mint with reference input (--read-only-tx-in-reference
) everything works as expected and the inline datum can be used, but when I try to write offchain code for this it fails with:
Contract instance stopped with error: "WalletContractError (ValidationError (ScriptFailure (EvaluationError [\"Hash\"] \"CekEvaluationFailure: An error has occurred: User error:\\nThe machine terminated because of an error, either from a built-in function or from an explicit use of 'error'.\")))"
This error is shown when I use the following offchain code:
pkh <- ownFirstPaymentPubKeyHash
outRef <- getUnspentOutput
o <- fromJust <$> unspentTxOutFromRef outRef
let
policy = mintValidator outRef
symbol = scriptCurrencySymbol policy
mintValue = Value.singleton symbol contractDataTokenName 1 <> Value.singleton symbol chunkCreationTokenName 1 <> Value.singleton symbol (chunkTokenName 0) 1
l = Constraints.unspentOutputs (Map.singleton outRef o) <> Constraints.plutusV2MintingPolicy policy
constr = Constraints.mustMintValueWithRedeemer (Redeemer $ toBuiltinData ()) mintValue <>
Constraints.mustSpendPubKeyOutput outRef <>
Constraints.mustPayWithInlineDatumToPubKey pkh (Datum $ toBuiltinData $ ChunkDatum (Address (PubKeyCredential $ unPaymentPubKeyHash pkh) Nothing) "") (Value.singleton symbol chunkCreationTokenName 1 <> Value.singleton symbol (chunkTokenName 0) 1) <>
Constraints.mustPayWithInlineDatumToPubKey pkh (Datum $ toBuiltinData $ ContractData [] [] 100000 False) (Value.singleton symbol contractDataTokenName 1)
-- ... create, sign, submit ...
ciTransaction <- fmap (txOutRefMap . fromJust) $ txFromTxId $ getCardanoTxId signed
let
fVal tokenName (citxo, _) = valueOf (citoValue citxo) symbol tokenName == 1
[dataRef] = Map.keys $ Map.filter (fVal contractDataTokenName) ciTransaction
[chunkRef] = Map.keys $ Map.filter (fVal (chunkTokenName 0)) ciTransaction
dataOut <- fromJust <$> unspentTxOutFromRef dataRef
chunkOut <- fromJust <$> unspentTxOutFromRef chunkRef
addr <- ownAddress
let
dat = Datum $ toBuiltinData $ ContractData [] [] 100000 False
mintValue2 = Value.singleton symbol (otherTokenName 0 0) 1
l2 = Constraints.plutusV2MintingPolicy policy <> Constraints.unspentOutputs (Map.singleton chunkRef chunkOut <> Map.singleton dataRef dataOut) <> Constraints.otherData dat
constr2 = Constraints.mustReferenceOutput dataRef <> Constraints.mustMintValueWithRedeemer (Redeemer $ toBuiltinData ()) mintValue2 <> mustSpendPubKeyOutput chunkRef <>
Constraints.mustPayWithInlineDatumToPubKey pkh (Datum $ toBuiltinData $ OtherDatum 0 0 0 addr 2000000) (Value.singleton "" "" 2000000 <> mintValue2) <>
Constraints.mustPayWithInlineDatumToPubKey pkh (Datum $ toBuiltinData $ ChunkDatum (Address (PubKeyCredential $ unPaymentPubKeyHash pkh) Nothing) "") (Value.singleton symbol chunkCreationTokenName 1 <> Value.singleton symbol (chunkTokenName 0) 1)
-- ... create, sign, submit ...
Why does the transaction that is created in offchain code not contain the inline datum but a hash? Is this currently possible with plutus-apps or do I still have to wait for this feature to be implemented?
If this is not possible at the moment I have one additional question: Is there a way to profile the execution cost of a script with the cardano-cli? I only know of --calculate-plutus-script-cost
which produces a json file of the cost, but I also want to know which part of the script cost how much, similar to the writeScriptsTo
way.