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:
- The token is initially minted with said state
- 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.
- 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).