Mint an NFT using policy script on cardano

77 views Asked by At

I'm trying to run validations before minting an asset/nft on cardano. I have written the policy script using plu-ts and transactions using mesh sdk.

Script

export const mintNFT = pfn(
  [datum.type, redeemer.type, PScriptContext.type],
  bool
)((datum, message, ctx) => {
  return pBool(true);
});

Transaction

const script: PlutusScript = {
  code: nftScriptCbor,
  version: "V2",
};

const recipient = await wallet.getChangeAddress();

const redeemer: Partial<Action> = {
  tag: "MINT",
};

const tx = new Transaction({ initiator: wallet });

const metadata: AssetMetadata = {
  name: "Test Token",
  description: "This is a test nft",
  image: "ipfs://",
  mediaType: "image/jpg",
};

const asset: Mint = {
  assetName: "MeshToken",
  assetQuantity: "1",
  metadata,
  label: "721",
  recipient,
};

const myUTxOs = await wallet.getUtxos();
tx.setCollateral(myUTxOs);

tx.mintAsset(script, asset, redeemer);

const unsignedTx = await tx.build();
const signedTx = await wallet.signTx(unsignedTx);
const txHash = await wallet.submitTx(signedTx);

return txHash;

The issue is that it mints the NFT, but doesn't run the validations. Although in transaction, it shows that contract is executed, but even if I return false from script, it still gets minted.

export const mintNFT = pfn(
  [datum.type, redeemer.type, PScriptContext.type],
  bool
)((datum, message, ctx) => {
  return pBool(false);
});

Can someone please explain how can I resolve this issue?

1

There are 1 answers

0
Michele Nuzzi On

I hope this answer doesn't come too late.

the problem is that you are trying to use a contract meant to validate a spending of an utxo for minting instead.

when used for minting you DO NOT need a datum.

datums are only used for spending scripts.

what happens here is that the node only passes 2 arguments to the script. which implies the script is only partially applied; hence it returns a new function, without never throwing an error.

not throwing an error causes the node to think the contract agreed to the transaction, and proceeded.

the fix is easy.

you just want to remove the datum from the contract definition.

so your contract would look like this:

export const mintNFT = pfn(
  [redeemer.type, PScriptContext.type],
  bool
)((message, ctx) => {
  return pBool(false);
});