examples for using the cardano-api library
This example taken from PPP0306
From the cardano-api perspective, there is no difference beween writeValidator
(see pay to script and the writeMintingPolicy
function below, both validator and minting policy are converted into a PlutusScriptSerialised
and then written to a file.
writeMintingPolicy :: FilePath -> Plutus.MintingPolicy -> IO (Either (FileError ()) ())
writeMintingPolicy file = writeFileTextEnvelope @(PlutusScript PlutusScriptV1) file Nothing . PlutusScriptSerialised . SBS.toShort . LBS.toStrict . serialise . Plutus.getMintingPolicy
Having the monetary policy script, we first need to calculate the policyId. This can be done by providing the script file from above to cardano-cli transaction policyid
. Under the hood, the script is hashed and serialised with the following two cardano-api functions:
serialiseToRawBytesHexText $ hashScript script
note: the ScriptHash
obtained by the hashScript
function is separate from the Hash
type to avoid the script hash type being parametrised by the era.
Besides the policyId, we need a token name to construct a value. The TokenName, called AssetName
on the cardano-api side, must be in hex form. so coming from the plutus side, we first need to convert it to the cardano-api type and then serialise it to hex bytes (and also unpack it as the cardano-cli expects a string):
unsafeTokenNameToHex :: TokenName -> String
unsafeTokenNameToHex = BS8.unpack . serialiseToRawBytesHex . fromJust . deserialiseFromRawBytes AsAssetName . getByteString . unTokenName
where
getByteString (BuiltinByteString bs) = bs
Having the policyId and tnHex, the value defined for the cardano-cli (see $v in --tx-out
and --mint
below) must be in the form of amt policyId.tnHex
, where amt is the amount of the token we want to mint.
Again, as for spending from a validator script, minting from a policy script is only possible with a script witness.
More precisely, the mint value passed to runTxBuild
in cardano-cli is of type (Value, [ScriptWitness WitCtxMint era])
, which is quite similar to the txIns
field of the transaction body content, but instead of a list of pairs (txIn, witness), we have just one value containing all the tokens to mint plus a list of script witnesses, this time with the context WitCtxMint
instead of WitCtxTxIn
.
The number of script witnesses depends on the number of the poliyIds contained in the value, of course. In our case there is just one token to mint, so there will be one script witness.
As for the datum needed for a script witness, the cardano-cli simply parses it - when in the WitCtxMint
context - to a value of NoScriptDatumForMint
. The redeemer meanwhile is a type alias for ScriptData
and thus context independent. As in the spendFromScript example, we use the unit.json redeemer.
The cardano-cli function createTxMintValue
finally produces a value of the correct type (see below) which we need for the txMintValue
field of the transaction body content.
data TxMintValue build era where
TxMintValue :: MultiAssetSupportedInEra era
-> Value
-> BuildTxWith build
(Map PolicyId (ScriptWitness WitCtxMint era))
-> TxMintValue build era
Once we have the value for the txMintValue
field of the transaction body content, we can proceed as in the pay to script example. Apart from running the minting script instead of the validator script, the balancing phase of the transaction building is identical, and same goes for signing and submitting the transaction.
cardano-cli transaction build \
$MAGIC \
--tx-in $oref \
--tx-in-collateral $oref \
--tx-out "$addr + 1500000 lovelace + $v" \
--mint "$v" \
--mint-script-file $policyFile \
--mint-redeemer-file testnet/unit.json \
--change-address $addr \
--protocol-params-file $ppFile \
--out-file $unsignedFile \
cardano-cli transaction sign \
--tx-body-file $unsignedFile \
--signing-key-file $skeyFile \
$MAGIC \
--out-file $signedFile
cardano-cli transaction submit \
$MAGIC \
--tx-file $signedFile