I am getting an error at the time of submit txn for a mint nft in cardano testnet

Command failed: transaction submit Error: Error while submitting tx: ShelleyTxValidationError ShelleyBasedEraAlonzo (ApplyTxError [UtxowFailure (WrappedShelleyEraFailure (MissingVKeyWitnessesUTXOW (WitHashes (fromList [KeyHash “a693ad5dbaf5c6e411ce38a747b2ead8b55544dd25db0e3349c9a2c6”])))),UtxowFailure (WrappedShelleyEraFailure (UtxoFailure (OutsideValidityIntervalUTxO (ValidityInterval {invalidBefore = SNothing, invalidHereafter = SJust (SlotNo 54624283)}) (SlotNo 54725015))))])

Please help on this.

Could you send the entire Command, please. Probably easier to debug from there. From a first look I would guess your $currentSlot is not set right? …

1 Like

Looks like two errors:

Not signed by the correct keys and --invalid-hereafter in the past.

1 Like

I resolved that error by providing the current slot. But getting this error MissingVKeyWitnessesUTXOW

For the signing transaction I am using bellow command.
cardano-cli transaction sign,
--signing-key-file user.payment.skey,
--signing-key-file user.policy.skey,
--testnet-magic 1097911063 --tx-body-file ${path}/matx.raw,
--out-file ${path}/matx.signed

1 Like

Can you please mention which signing key I need to provide at the time of sign the transaction. Now I am providing the wallet signing key and wallet policy signing key.

Hard to tell without knowing, what you are trying to do.

Looks like you are minting a token. Maybe the key hash in the policy file does not match the policy signing key that you use to sign the transaction.

1 Like

I am trying to minting a native token.

Following link: Minting NFTs | Cardano Developer Portal

I have taken a testnet wallet address from Nami wallet to do this steps.

  1. Create protocol parameter.
    Command:-
    cardano-cli query protocol-parameters
    –testnet-magic 1097911063
    –out-file protocol.json

  2. Create Policy Key Pairs.
    Command:
    cardano-cli address key-gen
    –verification-key-file payment.vkey
    –signing-key-file payment.skey

  3. Generate and update policy:
    Command:
    echo “{” >> policy/policy.script
    echo " “type”: “all”," >> policy/policy.script
    echo " “scripts”:" >> policy/policy.script
    echo " [" >> policy/policy.script
    echo " {" >> policy/policy.script
    echo " “type”: “before”," >> policy/policy.script
    echo " “slot”: $(expr $(cardano-cli query tip --mainnet | jq .slot?) + 10000)" >> policy/policy.script
    echo " }," >> policy/policy.script
    echo " {" >> policy/policy.script
    echo " “type”: “sig”," >> policy/policy.script
    echo " “keyHash”: “$(cardano-cli address key-hash --payment-verification-key-file policy/policy.vkey)”" >> policy/policy.script
    echo " }" >> policy/policy.script
    echo " ]" >> policy/policy.script
    echo “}” >> policy/policy.script

  4. Create policy id

Command: cardano-cli transaction policyid --script-file ./policy/policy.script > policy/policyID

  1. Generate Metadata

Command: echo “{” >> metadata.json
echo " “721”: {" >> metadata.json
echo " “$(cat policy/policyID)”: {" >> metadata.json
echo " “$(echo $realtokenname)”: {" >> metadata.json
echo " “description”: “This is my first NFT thanks to the Cardano foundation”," >> metadata.json
echo " “name”: “Cardano foundation NFT guide token”," >> metadata.json
echo " “id”: “1”," >> metadata.json
echo " “image”: “ipfs://$(echo $ipfs_hash)”" >> metadata.json
echo " }" >> metadata.json
echo " }" >> metadata.json
echo " }" >> metadata.json
echo “}” >> metadata.json

  1. Build a txn
    command:
    cardano-cli transaction build
    –testnet-magic 1097911063
    –alonzo-era
    –tx-in $txhash#$txix
    –tx-out $address+$output+"$tokenamount $policyid.$tokenname"
    –change-address $address
    –mint="$tokenamount $policyid.$tokenname"
    –minting-script-file $script
    –metadata-json-file metadata.json
    –invalid-hereafter $slotnumber
    –witness-override 2
    –out-file matx.raw

  2. Sign the txn

Command:
cardano-cli transaction sign
–signing-key-file payment.skey
–signing-key-file policy/policy.skey
–testnet-magic 1097911063 --tx-body-file matx.raw
–out-file matx.signed.

  1. Submit the transaction

Command:
cardano-cli transaction submit --tx-file matx.signed --testnet-magic 1097911063

Getting error:
Command failed: transaction submit Error: Error while submitting tx: ShelleyTxValidationError ShelleyBasedEraAlonzo (ApplyTxError [UtxowFailure (WrappedShelleyEraFailure (MissingVKeyWitnessesUTXOW (WitHashes (fromList [KeyHash “a693ad5dbaf5c6e411ce38a747b2ead8b55544dd25db0e3349c9a2c6”]))))

Is this the right process to mint a native token in cardano? Can I use any test-net address to mint a token or I need to create new address every time?

Is it required to create the skey and vkey file before generate the wallet address or we can generate vkey and skey for any wallet address?

Lots of questions. So, you can reuse the payment key pair without problems. For the policy key pair, it’s best to use a new one every time.

But the payment key pair also has to be the one that is really used to pay for the minting transaction.

So, the --tx-in $txhash#$txix has to come from that address. That’s why there is the cardano-cli query utxo step in the guide before that. And for that to be possible, you first have to send some tADA into that address.

Your Nami testnet wallet does not have much to do with it if you follow the guide.

You could use a “normal” wallet address as payment address, but that would involve using cardano-address or cardano-wallet in addition to cardano-cli and I currently don’t know, where there is a good guide.

Thank you for your suggestion.

I have doubt like can we use same wallet skey and vkey for any wallet address or it will be different for different wallet address.

I added test ada to that address which is 1000000000 lovelace.
For the build txn command I am using 500000000 for tokenamount and output is 2000000. Is it correct? As I am not following the process like first make a draft version of transaction and then update that txn with calculating the fees.

Also I tried all step by step following the link using CMD and I got success there, but when I am tying to make the functions not getting the success result. I think I am submitting wrong value.
Can you please help me to understand the input value of build txn command for “output”, “tokenamount” variable.
I am trying to mint 500000000 lovelace.

“cardano-cli transaction build”,
“–testnet-magic 1097911063”,
“–alonzo-era”,
--tx-in "${txhash}#${txix}",
--tx-out "${address}+${output}+ ${tokenamount} ${policyid}.${realtokenname}",
--change-address ${address},
--mint="${tokenamount} ${policyid}.${tokenname}",
--minting-script-file ${policyscriptfile},
--metadata-json-file ${path}/metadata.json,
--invalid-hereafter ${slotnumber},
--witness-override 0,
--out-file ${path}/matx.raw

There are no wallets involved, here, but you can use the same payment key pair for all your mints.

The token amount is 100% your choice, you can mint as many or as few as you want. But for NFTs the amount is usually 1. Those shall be NFTs. Non-fungible tokens. If you mint 500 000 000 of them, those 500 million are very much fungible.

The output is also your choice, but it has to be less than what is in the transaction input(s) minus the transaction fee and more than the minimum UTxO value (which is around 1.4 ADA for an output with one native token).

??? You can’t mint (t)ADA or Lovelace. You can only mint your own tokens.

--tx-out "${address}+${output}+ ${tokenamount} ${policyid}.${realtokenname}": This should also be ${tokenname}, not ${realtokenname}. ${realtokenname} is only used in the metadata.json file.

--witness-override 0: This should be --witness-override 2, since you need two witnesses – the payment key that pays for the transaction and the policy key for the policy of the minted token.

--tx-in "${txhash}#${txix}": You have set these two according to the beginning of the “Crafting the transaction” section https://developers.cardano.org/docs/native-tokens/minting-nfts/#crafting-the-transaction?

Hi @HeptaSean. Thank you for your response.
We are currently building a NFT marketplace where user will connect their wallet. Then they can create, mint, buy and sell NFTs.
So we are developing feature to create NFT for the Artists.

The functionalities we are having currently are as follows.

variables:
const CARDANO_CLI_PATH = “cardano-cli”;
const CARDANO_NETWORK_MAGIC = 1097911063;
const PATH= walletaddressvalue (A folder created with the name of user wallet address)

Steps:

  1. Creating the s-key and v-key for that wallet address.
    cmd.runSync([
    ${CARDANO_CLI_PATH} address key-gen,
    “–verification-key-file”, ${walletaddressvalue}.vkey,
    “–signing-key-file”, ${walletaddressvalue}.skey].join(" "));

  2. Creating protocol parameter for that address.
    cmd.runSync([
    ${CARDANO_CLI_PATH},
    “query”, “protocol-parameters”,
    “–testnet-magic”, CARDANO_NETWORK_MAGIC,
    “–out-file”, ${PATH}/protocol.json].join(" "));

  3. Create policy key pairs for that address.

cmd.runSync([
${CARDANO_CLI_PATH}, “address key-gen”, " \ ",
“–verification-key-file”, ${PATH}/policy/policy.vkey, " \ “,
“–signing-key-file”, ${PATH}/policy/policy.skey].join(” "));

  1. Creating policy script and update policy script for that wallet address.
    Create

cmd.runSync([
“touch”, ${PATH}/policy/policy.script
].join(" "));

Update

cmd.runSync([
echo "{" >> ${PATH}/policy/policy.script echo " '\"type\"': '\"all\"'," >> ${PATH}/policy/policy.script echo " '\"scripts\"':" >> ${PATH}/policy/policy.script echo " [" >> ${PATH}/policy/policy.script echo " {" >> ${PATH}/policy/policy.script echo " '\"type\"': '\"before\"'," >> ${PATH}/policy/policy.script echo " '\"slot\"': $(expr $(cardano-cli query tip --testnet-magic 1097911063 | jq .slot?) + 10000)" >> ${PATH}/policy/policy.script echo " }," >> ${PATH}/policy/policy.script echo " {" >> ${PATH}/policy/policy.script echo " '\"type\"': '\"sig\"'," >> ${PATH}/policy/policy.script echo " '\"keyHash\"': '\"$(cardano-cli address key-hash --payment-verification-key-file ${PATH}/policy/policy.vkey)\"'" >> ${PATH}/policy/policy.script echo " }" >> ${PATH}/policy/policy.script echo " ]" >> ${PATH}/policy/policy.script echo "}" >> ${PATH}/policy/policy.script].join(" "))

  1. Create policy id for that wallet address.

cmd.runSync([
“cardano-cli”, “transaction”,
“policyid”, “–script-file”,
${PATH}/policy/policy.script,
${PATH}/policy/policyID].join(" "))

  1. Generating metadata for that wallet address.

variables:
tokenname, description, ipfs_hash,
realtokenname = stringToHex(tokenname)

cmd.runSync([
echo "{" >> ${PATH}/metadata.json echo " '\"721\"': {" >> ${PATH}/metadata.json echo " '\"$(cat ${PATH}/policy/policyID)\"': {" >> ${path}/metadata.json echo " '\"${realtokenname}\"': {" >> ${PATH}/metadata.json echo " '\"description\"': '\"${description}\"'," >> ${PATH}/metadata.json echo " '\"name\"': '\"Cardano foundation NFT guide token\"'," >> ${PATH}/metadata.json echo " '\"id\"': '\"1\"'," >> ${PATH}/metadata.json echo " '\"image\"': '\"${ipfs_hash}\"'" >> ${PATH}/metadata.json echo " }" >> ${PATH}/metadata.json echo " }" >> ${PATH}/metadata.json echo " }" >> ${PATH}/metadata.json echo "}" >> ${PATH}/metadata.json
].join(" "))

  1. Build the transaction for that wallet address.

variable:
tokenname, txhash, txix, tokenamount, address(User wallet address), output, policyid, slotnumber(current slot no+10000),
realtokenname = stringToHex(tokenname)

cmd.runSync([
“cardano-cli transaction build”,
“–testnet-magic 1097911063”,
“–alonzo-era”,
--tx-in "${txhash}#${txix}",
--tx-out "${address}+${output}+ ${tokenamount} ${policyid}.${realtokenname}",
--change-address ${address},
--mint="${tokenamount} ${policyid}.${tokenname}",
--minting-script-file ${policyscriptfile},
--metadata-json-file ${path}/metadata.json,
--invalid-hereafter ${slotnumber},
--witness-override 0,
--out-file ${path}/matx.raw
].join(" "))

  1. Signing the transaction

cmd.runSync([
“cardano-cli transaction sign”,
--signing-key-file ${path}/${walletaddressvalue}.payment.skey,
--signing-key-file ${PATH}/policy/policy.skey,
--testnet-magic 1097911063 --tx-body-file ${PATH}/matx.raw,
--out-file ${PATH}/matx.signed
].join(" "))

  1. Submit the transaction for that wallet address.

cmd.runSync([
cardano-cli transaction submit,
--tx-file ${PATH}/matx.signed,
--testnet-magic 1097911063
].join(" "));

Basically the static value we are providing now is tokenamount = 500000000, output = 2000000.

After completing these steps we are getting this error on step 9.
Command failed: transaction submit Error: Error while submitting tx: ShelleyTxValidationError ShelleyBasedEraAlonzo (ApplyTxError [UtxowFailure (WrappedShelleyEraFailure (MissingVKeyWitnessesUTXOW (WitHashes (fromList [KeyHash “a693ad5dbaf5c6e411ce38a747b2ead8b55544dd25db0e3349c9a2c6”]))))

Can you please check all the steps and provide me the actual solution to resolve this issue.

That’s quite a bit, so let’s see:

  1. If you are planning to build an NFT marketplace, you probably have good Javascript developers on hand. It might be less painful to use an API such as Blockfrost or cardano-wallet-js instead of runSyncing the command line tools. (BTW: Why cmd.runSync and not the native child_process.execSync?)
  1. In any case, building JSON files by runSyncing echo commands is really weird. (Does that code even work. I don’t see newlines in there. Have you looked at the resulting files?)
    Build the policy (and the metadata) in Javascript and then use JSON.stringify and fs.writeFileSync.
  2. Throughout you wildly mix ${PATH} and ${path}. Is that an artifact of trying to copy and paste it into the forum or is it really that way in your code? The latter will lead to chaos.
  3. As you already asked, you really should not create one payment key pair per customer (your step 1.). You would have to fund each of these individually and you would have to wait until the funds arrive, before you can even start the minting.
  4. You really do not have to download the protocol parameters for each individual customer (your step 2.). Those are protocol parameters. They change very seldomly. Actually, you don’t need them at all, since you use transaction build and not transaction build-raw. It’s an error in the documentation that they still needlessly download them.
  5. In your step 1., you save the payment key to --signing-key-file ${walletaddressvalue}.skey, but in step 8., you try to load it with --signing-key-file ${path}/${walletaddressvalue}.payment.skey. Is that the same path?
  6. How do you set txhash and txix? I don’t see the code for that. You have to query the UTxOs of the payment address that you later also use to sign the transaction for that.
  7. You say “address (User wallet address)”, but then use --tx-out "${address}+${output}+ ${tokenamount} ${policyid}.${realtokenname}" as well as --change-address ${address}. That way you will always send everything in your minting payment address to your customers. I’m not sure if you really want that. I’d say, these should be different addresses. Controlled output to your customer, change back to your payment address.
  8. As already said, in --tx-out "${address}+${output}+ ${tokenamount} ${policyid}.${realtokenname}" it should be ${tokenname}, not ${realtokenname}.
  9. As already said, it has to be --witness-override 2, not --witness-override 0.

If this is the code that is executed, I’m a bit surprised that it even gets to the MissingVKeyWitnessesUTXOW error and does not error out earlier. Reasons for that specific error could be 6. and 7. in the list above. Or totally broken policy file due to 2. Or wrong files loaded due to 3.

Thanks for showing your interest on this topic.

  1. I am using Node JS, Express JS framework and found cmd.runsync an easy process for development.

  2. Its works perfectly. Let me share the screen shot of metadata.json.
    Reference: Image 5

  3. I tried to write down the code here and made this mistakes. Both the {PATH} and {path} are same on my code.

  4. Ok so for all users we can use the same payment s.key and v.key.

  5. That’s mean we can use same protocol.json file all users.

  6. Yes this is the same path.

  7. I develop another function by which I can get the txix and txhash of wallet address and taking the value from there.

  8. What I understand from the example that they are using the same address on the build txn command.
    Reference: Image 1

Can you please give more information about that like which address I need to provide here.

  1. I am using hex format of the “tokenname” value. I am storing the hex value to “realtokenname” variable. as I found on the example that we need to provide hex value of token name. I am using cardano-node version 1.32.0

Reference: Image 2

  1. I tried with “–witness-override 2” but same error.

Policy Script screenshot
Reference: Image 3

File details which generated after executing the functions.
Reference: Image 4

I am not able to share screenshot more than 1 so I am attaching all the image reference in one single file.

Okay, still hard to read and debug as code, but if you like it. :man_shrugging:

Has another problem, now that I see it: The asset name should not be hex-encoded in the file, but in UTF-8. See 9. below.

It actually means, you do not need a protocol.json file at all.

That might be the problem. Which wallet address? It has to be the payment address, not the address of the customer. You don’t have access to that. You only have the keys for the payment address.

Yes, but they are minting to their own payment address in this example and only later send the minted token to a recipient address. If you want to mint to the recipient address directly, you are sending everything away like this and have to fund again, before you can do the next mint.

You can also do it exactly like in the example. Costs double the transaction fees, but is okay. But then, the recipient’s address will not appear in the minting at all.

You do realise that they are doing it the other way round? $realtokenname contains the original string, while $tokenname contains the hex-encoded version.

Your realtokenname = stringToHex(tokenname) inverses that, which is utterly confusing.

Anyway, all arguments to cardano-cli have to be hex-encoded (if tokenname is the non-encoded version, then your --mint argument is wrong). The asset/token name in metadata.json must not be hex-encoded (which it is at the moment). Name the variables in any way you like, but at the moment it’s mixed up.

You will want it anyway. Otherwise, you will get the next error (fee too low), after this one is fixed.

Why do you put the policy keys and script into the customer/mint specific subdirectory, but leave metadata.json, matx.raw and matx.signed in the parent directory? They are also specific to the mint. It will later help in debugging to put everything specific to one mint into the directory.

In fact, it should probably not be named by the customer’s address (since the customer might mint multiple NFTs and you wouldn’t want to overwrite the files). Each mint should probably get a unique ID and that should be used for the folder.

Good morning @Hepta Sean. Thank you for your help.
I think I am not able to describe you the actual issue and also I am getting confuse about the process now.
Is there any possible way to hop on a meeting you and me, discuss in detail and if you can help to show me the right direction for this marketplace.

You should increase slotNo

You need a policy key to sign the transaction too

Yes. Its works after increasing the slot no “invalidHereafter = SJust (SlotNo 54624283)}) (SlotNo 54725015))))”. Thanks.