I am following this tutorial on creating an NFT on the Cardano testnet. The tutorial references a payment.skey and a policy.skey that are needed to build and sign a transaction that creates the NFT on the blockchain.

What is the difference between a payment.skey and policy.skey, and what is the difference between a payment.vkey and policy.vkey? How can I create these from a mnemonic that I have stored on another device?

1 Answer 1


On blockchains, you generally have verification keys and signing keys, here the verification key is derived from the signing key. These keys allow users to sign transactions to permit actions on the blockchain, like spending funds.

From each verification key, an address can be derived by hashing the verification key and performing some actions on it. These actions include adding a marker to which network the address corresponds to, a testnet (has a magic number associated with each) or mainnet. A transaction that tries to spend from that address is only valid if the signature of the signing key associated with the verification key is present with the transaction. This signing key is thus something that you keep secret!

Your payment.*key pair represent the above construction. The address is derived from the .vkey via the command,

cardano-cli address build \
--payment-verification-key-file payment.vkey \
--out-file payment.addr \
--testnet-magic 1097911063       <--- this is a testnet marker!

Now Cardano has more utility besides simple payment addresses as described above, additionally the ledger supports native assets. These are values that behave just like Ada in that they can capture value, two fields mark them. The first is their policy ID, this is a unique marker that captures how tokens under that policy ID can be minted. More explicitly, similar to the address just discussed, it is derived from the hash of the policy script used. In the tutorial you linked, this script had the following form,

  "type": "all",
     "type": "sig",
     "keyHash": "6d1321490cde0b447794edff9239cf0668ae01f0df33823d0a3bbcf7"

This script allows minting/burning of assets under its policy ID only if the minting transaction has a signature of the signing key associated with the verification key that hashes to 6d132....bbcf7. Now, a step earlier in the tutorial, you generated this pair under the name policy.skey and policy.vkey. These keys are just normal spending keys, and you could derive an address from them. So at its core there is no difference between the pairs payment.*key and policy.*key. The only difference is that the script can only mint assets if the signature of the policy.skey is present in the minting transaction.

In the linked example we indeed see that when the minting transaction is constructed both skey's are present. The payment.skey to spend funds from its address, to pay the fee's of the mint. And the policy.skey to add its signature for a valid execution of the script.

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

Lastly, regarding your last question, can you derive these from a mnemonic? Yes you can, there are multiple ways and languages possible to do this (JS, python, a client and more). For example, consider this packages by IOG (1). And for its documentation, view this link (2). There are some SE questions that go into this.

Your Answer

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

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