1

The problem

Please consider the following case: a token (NFT) needs to holds some state, ie {a: 234, b: "someState"}, which needs to be mutable and it needs to abide to specific rules.

The solution

I found this to be possible by storing this state in the mint transaction redeemer, which works as follows:

  1. The token is initially minted with said state
  2. We now want to mutate the state, the token is burned and minted at the same time, where once again the minted token holds the mutated state in the redeemer of the mint transaction.
  3. At any time we can look up the state by issuing the most recent mint transaction redeemer.

The state can be enforced into a specific format using the minting policy; the mint is rejected if the redeemer is in a wrong format. We can also check using the contract (minting policy) that the same token was both minted and burned in the same transaction. This solution would also allow for mutating the token metadata since in each new mint we can alter the metadata. This was inspired by CIP-25 which states that metadata can be updated by minting the token with new data.

The error

I implemented a simple example of this in Aiken and Lucid for the on-chain and off-chain code respectively. The implementation, however, fails in step 2 when trying to mint and burn in the same transaction:

.mintAssets({
    [assetName] : -1n,
}, BurnRedeemer) // Just to tell the script we are burning the token
.mintAssets({
    [assetName] : 1n,
}, MintRedeemer) // Holds the new state

The following error code is returned: Error: "transaction submit error ShelleyTxValidationError ShelleyBasedEraBabbage (ApplyTxError [UtxowFailure (FromAlonzoUtxowFail (WrappedShelleyEraFailure (ExtraneousScriptWitnessesUTXOW (fromList [ScriptHash \"6edbbd728fa1a6488c18994ece35cc5cc6d4e472a00b7e2e621218f0\"])))),UtxowFailure (FromAlonzoUtxowFail (ExtraRedeemers [RdmrPtr Mint 0])),UtxowFailure (FromAlonzoUtxowFail (PPViewHashesDontMatch (SJust (SafeHash \"98eab4d1a6dd11919b5b8ea820b1b867ca261c4f85e50ec4afa99f392950e81a\")) (SJust (SafeHash \"c06babada7564b7629ddadc5ef3689ad7fcc64b2d3bc3c85a489dde1eaccc29a\"))))])"

My question now is, is it possible to mint and burn a token in the same transaction and is this implementation possible? If not, what other options are there for doing this? Please note that CIP-68 is not an option (minUtxo value is too expensive for my use case).

2 Answers 2

0

The "mint" field in a transaction is a single "Value", defined as:

newtype Value = Value {
getValue :: Map CurrencySymbol (Map TokenName Integer)
}
newtype CurrencySymbol = CurrencySymbol {
unCurrencySymbol :: BuiltinByteString
}
newtype TokenName = TokenName {
unTokenName :: BuiltinByteString
}

not a list of values, so you can't mint and burn the same asset within a single transaction.

Not sure how lucid handles you code exactly, it's possible that the first call is just overwritten and therefore the signature for the utxo to burn is extraneous, resulting in the "ExtraneousScriptWitnessesUTXOW" error.

2
  • It is useful to know Cardano doesn't allow a mint and burn in the same transaction! Is the code you provided plutus code?
    – Duco
    Apr 30 at 14:55
  • It's from the official Plutus documentation, but it's a general ledger property. Apr 30 at 17:32
0

ExtraneousScriptWitnessesUTXOW indicates that the same script is provided multiple times within a single transaction. It is only necessary and valid to provide the script once, either by including it in the transaction body as a witness or by referencing a UTxO containing the reference script.

This implies that there can only be one redeemer, making it impossible to execute the same policy more than once in a single transaction, irrespective of the values being minted or burned

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.