You want to create your own NFT? Here’s how you do it on the Cardano blockchain.

With the current hype around NFTs, you may think about creating your own. For those who are new to the crypto space, an NFT is a non-fungible token, this means unlike bitcoin (or other cryptocurrencies) those tokens are not mutually interchangeable. This results in a digital scarcity which creates a natural value for the token.

You may have heard of the Cardano blockchain and its native asset token ada. Cardano calls itself a third-generation blockchain and solves a lot of problems, ethereum or bitcoin are struggling with. Since the 2nd of March 2021, it’s officially possible to create NFTs and other assets on the Cardano blockchain! That’s why I will show you how to create your NFT on the Cardano blockchain! Enough theory, let’s get going.

First, this tutorial will assume the following:

  • You own (or have access to) a full Cardano-node

Alright, I will show you how I create two brand new NFTs for our project at bitPhant where we are trying to conserve biodiversity with NFTs and our own staking pool.

First, you have to create a new payment address for that you need two keys. Let’s generate them:

cardano-cli address key-gen \
--verification-key-file payment.vkey \
--signing-key-file payment.skey

Then generate the payment address:

cardano-cli address build \
--payment-verification-key-file payment.vkey \
--out-file payment.addr \
--mainnet

Display the content of the file with:

cat payment.addr
addr1v9hhyvjycngmhrng2xcqa58y9j759we4xxhhqhpx26lgpzqyvflfk

Now check the current UTXo of your address:

cardano-cli query utxo --address $(cat payment.addr) \
--mainnet --mary-era

This should output something like this:

TxHash                                 TxIx        Amount
--------------------------------------------------------------------------------------

This means you did not have any transactions on your address. In the next step, you need to fund your address. Copy your address, e.g.

 addr1v9hhyvjycngmhrng2xcqa58y9j759we4xxhhqhpx26lgpzqyvflfk

Go to your wallet of choice and transfer the amount you like to this address, you need at least 1 ada to create your NFT. Depending on how many you want to create, you may want to transfer more ada. Later, if you want to send your NFTs to your friends, you need at least 1.7 ada per transaction you are creating. This is because it is currently not possible to only send custom tokens, with every transaction you have to send a minimum amount of ada with it.

Again, check your UTXO:

cardano-cli query utxo --address $(cat payment.addr) \
--mainnet --mary-era

Now you should see something like this:

TxHash                                 TxIx        Amount
--------------------------------------------------------------------------------------
7211b05ef3cbe067b36469af2a81a63de5612b6a449cf8db47504ccc82726015 0 5000000 lovelace

I transferred 5 ada to my address. The amount is always displayed in lovelace. 1 ada = 1'000'000 lovelace.

Great, now you need to export the current network parameters to a file:

cardano-cli  query protocol-parameters \
--mainnet \
--out-file protocol.json

Awesome! Now comes the good part, you have to create your own policy. A policy can create and burn tokens. A token is always identified by the policy id and a token name. The token name is unique for the policy id but can be used with another policy id.

Again, you will need two keys two create your policy, so let’s do that:

cardano-cli address key-gen \
--verification-key-file policy.vkey \
--signing-key-file policy.skey

Now you are able to create your policy script, your script indicates the type of signing that is required to issue tokens.

touch policy.script && echo "" > policy.script 


echo "{" >> policy.script
echo " \"keyHash\": \"$(cardano-cli address key-hash --payment-verification-key-file policy.vkey)\"," >> policy.script
echo " \"type\": \"sig\"" >> policy.script
echo "}" >> policy.script

cat policy.script
{
"keyHash": "5805823e303fb28231a736a3eb4420261bb42019dc3605dd83cccd04",
"type": "sig"
}

Here you indicate with “sig” that only a single signature is needed to issue new tokens, meaning the policy key signing.

Now, let’s get the policy id out of your policy script:

cardano-cli transaction policyid --script-file policy.script> 677d3bbe3e01eeab498cd8786f7d261d92bd6ecea12109a332e86374

Create the transaction. You have one output (your own address), where you send all your ada, which you have to calculate first, that is why it’s currently zero, and all the tokens you mint with this transaction. Remember that the inputs and outputs always need to be equal, this is also true for custom tokens!

cardano-cli transaction build-raw \
--mary-era \
--fee 0 \
--tx-in 7211b05ef3cbe067b36469af2a81a63de5612b6a449cf8db47504ccc82726015#0 \
--tx-out $(cat payment.addr)+0+"1 677d3bbe3e01eeab498cd8786f7d261d92bd6ecea12109a332e86374.MountainGorilla + 1 677d3bbe3e01eeab498cd8786f7d261d92bd6ecea12109a332e86374.BrownBear"\
--mint="1 677d3bbe3e01eeab498cd8786f7d261d92bd6ecea12109a332e86374.MountainGorilla + 1 677d3bbe3e01eeab498cd8786f7d261d92bd6ecea12109a332e86374.BrownBear"\
--out-file matx.raw

Now you have the raw transaction, the next step is to calculate the transaction fees:

cardano-cli transaction calculate-min-fee \
--tx-body-file matx.raw \
--tx-in-count 1 \
--tx-out-count 1 \
--witness-count 2 \
--mainnet \
--protocol-params-file protocol.json
195509 Lovelace

The calculation needs the raw transaction, the number of transaction inputs, the number of transaction outputs, the number of keys needed to sign the transaction, and the network parameters.

Now you can build the transaction again, but this time with the fee:

cardano-cli transaction build-raw \
--mary-era \
--fee 195509 \
--tx-in b1ddb0347fed2aecc7f00caabaaf2634f8e2d17541f6237bbed78e2092e1c414#0 \
--tx-out $(cat payment.addr)+4804491+"1 677d3bbe3e01eeab498cd8786f7d261d92bd6ecea12109a332e86374.MountainGorilla + 1 677d3bbe3e01eeab498cd8786f7d261d92bd6ecea12109a332e86374.BrownBear"\
--mint="1 677d3bbe3e01eeab498cd8786f7d261d92bd6ecea12109a332e86374.MountainGorilla + 1 677d3bbe3e01eeab498cd8786f7d261d92bd6ecea12109a332e86374.BrownBear"\
--out-file matx.raw

Almost done, now sign the transaction:

cardano-cli transaction sign \
--signing-key-file payment.skey \
--signing-key-file policy.skey \
--script-file policy.script \
--mainnet \
--tx-body-file matx.raw \
--out-file matx.signed

And finally submit the transaction, if you don’t get any response, that is usually a sign that everything worked.

cardano-cli transaction submit --tx-file  matx.signed --mainnet

Go ahead and query your UTXo again, you should now see your newly minted tokens!

cardano-cli query utxo --address $(cat payment.addr) \
--mainnet --mary-era
TxHash TxIx Amount
--------------------------------------------------------------------------------------fd0790f3984348f65ee22f35480b873b4eb9862065514f3e3a9c0f04d0a6ad63 0 4804491 lovelace + 1 677d3bbe3e01eeab498cd8786f7d261d92bd6ecea12109a332e86374.MountainGorilla + 1 677d3bbe3e01eeab498cd8786f7d261d92bd6ecea12109a332e86374.BrownBear

Congratulations you just created your first NFT on the Cardano blockchain!

If this guide was helpful, consider supporting our cause by delegating some ada to our stake pool or check out our custom NFTs which represent a species on the IUCN Redlist. BitPhant is a non-profit that leverages blockchain technology to conserve biodiversity.

Data Engineer. I write about Machine Learning, Big Data, and Web Technologies.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store