Searchโ€ฆ
Cardano Native Asset (NFT) ๐Ÿ’ฐ
Let's make some native assets on Cardano โค๏ธโœจ

Who is this guide for?

    For people who want to make NFT's or Native Assets on Cardano
    For people who know about Cardano

Benefits of NFT's on Cardano

    Low transaction fees
    Native on the blockchain

Prerequisites

We made this tutorial for use with Raspberry-Pi-ARM machines running on Linux OS so make sure to download the correct node.js for your local machine/CPU and OS. Currently, the Cardano-node and Cardano-cli are meant to be built from source on Linux machines. Any other OS will have its own build complexities, and we do not cover them in any of our tutorials as of right now. How to build Cardano Node from sourceโ€‹
If you are using a Raspberry Pi machine here is an easy-to-follow tutorial we made to get a Cardano Relay Node running.
    cardano-node / cardano-cli set up on local machine
    Make sure you have a Cardano node running and fully synced to the database
    Make sure node.js installed
1
#Copy/Paste this into your terminal if node.js is not installed
2
curl -sL https://deb.nodesource.com/setup_14.x | sudo -E bash -
3
sudo apt-get install -y nodejs
Copied!

Verify everything is set up properly on our machine โš™๏ธ

1
#Copy/paste into terminal window
2
cardano-cli version; cardano-node version
Copied!
Your output should look like this ๐Ÿ‘‡
1
cardano-cli 1.26.2 - linux-aarch64 - ghc-8.10
2
git rev 0000000000000000000000000000000000000000
3
cardano-node 1.26.2 - linux-aarch64 - ghc-8.10
4
git rev 0000000000000000000000000000000000000000
Copied!

Verify our node.js version is correct and is on v14.16.1

1
#Copy/paste into terminal window
2
node -v
Copied!
1
v14.16.1
Copied!

Video Walk-through:

Create our project directory and initial setup

1
# check for $NODE_HOME
2
echo $NODE_HOME
3
โ€‹
4
# if the above echo didn't return anything, you need to set a $NODE_HOME
5
# or use a static path for the CARDANO_NODE_SOCKET_PATH location
6
โ€‹
7
export NODE_HOME="/home/ada/pi-pool"
8
# Change this to where cardano-node creates socket
9
export CARDANO_NODE_SOCKET_PATH="$NODE_HOME/db/socket"
10
โ€‹
11
mkdir cardano-minter
12
cd cardano-minter
13
npm init -y #creates package.json)
14
npm install cardanocli-js --save
Copied!
    1.
    Copy the Cardano node genesis latest build number from the IOHK hydra website
    2.
    Create a bash shell script to Download the latest Genesis config file needed
1
nano fetch-config.sh
Copied!
MAINNET
TESTNET
1
#NODE_BUILD_NUM may be different
2
NODE_BUILD_NUM=6198010
3
echo export NODE_BUILD_NUM=$(curl https://hydra.iohk.io/job/Cardano/iohk-nix/cardano-deployment/latest-finished/download/1/index.html | grep -e "build" | sed 's/.*build\/\([0-9]*\)\/download.*/\1/g') >> $HOME/.bashrc
4
wget -N https://hydra.iohk.io/build/${NODE_BUILD_NUM}/download/1/mainnet-shelley-genesis.json
Copied!
1
NODE_BUILD_NUM=6198010
2
echo export NODE_BUILD_NUM=$(curl https://hydra.iohk.io/job/Cardano/iohk-nix/cardano-deployment/latest-finished/download/1/index.html | grep -e "build" | sed 's/.*build\/\([0-9]*\)\/download.*/\1/g') >> $HOME/.bashrc
3
wget -N https://hydra.iohk.io/build/${NODE_BUILD_NUM}/download/1/testnet-shelley-genesis.json
Copied!
Now we need to give permissions to our new script to execute then we will run our script and download the genesis files.
1
sudo chmod +x fetch-config.sh
2
./fetch-config.sh
Copied!

Next, we make our src folder/directory and then create the Cardano client.

1
mkdir src
2
cd src
3
nano cardano.js
Copied!
If you are using testnet make sure you have the correct testnet-magic version number. You can find the current testnet version here.
MAINNET
TESTNET
1
const Cardano = require("cardanocli-js");
2
โ€‹
3
const cardano = new Cardano({
4
network: "mainnet",
5
dir: __dirname + "/../",
6
shelleyGenesisPath: __dirname + "/../mainnet-shelley-genesis.json",
7
});
8
โ€‹
9
module.exports = cardano;
Copied!
1
const Cardano = require("cardanocli-js")
2
โ€‹
3
const cardano = new Cardano({
4
network: "testnet-magic 1097911063",
5
dir: __dirname + "/../",
6
shelleyGenesisPath: __dirname + "/../testnet-shelley-genesis.json"
7
});
8
โ€‹
9
module.exports = cardano;
Copied!

Video Walk-through :

Untitled
โ€‹
โ€‹
โ€‹

Create a local wallet

1
nano create-wallet.js
Copied!
1
const cardano = require('./cardano')
2
โ€‹
3
const createWallet = (account) => {
4
cardano.addressKeyGen(account);
5
cardano.stakeAddressKeyGen(account);
6
cardano.stakeAddressBuild(account);
7
cardano.addressBuild(account);
8
return cardano.wallet(account);
9
};
10
โ€‹
11
createWallet("ADAPI")
Copied!
1
cd ..
2
node src/create-wallet.js
Copied!

Verify balance wallet balance is Zero, then we fund the wallet

    First, we need to create a get-balance.js script
1
cd src
2
nano get-balance.js
Copied!
1
// create get-balance.js
2
const cardano = require('./cardano')
3
โ€‹
4
const sender = cardano.wallet("ADAPI");
5
โ€‹
6
console.log(
7
sender.balance()
8
)
Copied!
    Now, Check the balance of our wallet.
1
cd ..
2
node src/get-balance.js
Copied!
    We can go ahead and send some funds (ADA) into our wallet we created, wait a few minutes, and then check the balance again to make sure the transaction was successful.
If you are using testnet you must get your tADA from the testnet faucet here.

Video Walk-through :

Untitled
โ€‹

Mint our Native-Asset/NFT on Cardano

Before we proceed to mint our Native Asset we must have a few things taken care of. We need to first get our "asset" onto our IPFS node and generate the IPFS link. If you do not know about IPFS or what it actually does we recommend having a read through the documentation here or watching this video.
Since we are using an image file to be our asset we should upload a smaller thumbnail-sized version of our image (ideally less than 1MB). This will be used on sites like pool.pm to display our assets nicely in our wallets. We then upload the full-size image as our source image.
    Download IPFSโ€‹
    Upload your asset's files to IPFS
    Get our image thumbnail IPFS link
    Get the src IPFS link

For reference:

    image (thumbnail version) - ipfs://QmQqzMTavQgT4f4T5v6PWBp7XNKtoPmC9jvn12WPT3gkSE
    src (full-size version) - ipfs://Qmaou5UzxPmPKVVTM9GzXPrDufP55EDZCtQmpy3T64ab9N

Create our mint-asset.js script

This script has three main components:
    1.
    Generate policy id
    2.
    Define your metadata
    3.
    Create mint transaction
1
nano mint-asset.js
Copied!
1
const fs = require("fs");
2
const cardano = require("./cardano");
3
โ€‹
4
// 1. Get the wallet
5
// 2. Define mint script
6
// 3. Create POLICY_ID
7
// 4. Define ASSET_NAME
8
// 5. Create ASSET_ID
9
// 6. Define metadata
10
// 7. Define transaction
11
// 8. Build transaction
12
// 9. Sign transaction
13
// 10. Submit transaction
14
โ€‹
15
const buildTransaction = (tx) => {
16
const raw = cardano.transactionBuildRaw(tx);
17
const fee = cardano.transactionCalculateMinFee({
18
...tx,
19
txBody: raw,
20
});
21
tx.txOut[0].amount.lovelace -= fee;
22
return cardano.transactionBuildRaw({ ...tx, fee });
23
};
24
โ€‹
25
const signTransaction = (wallet, tx, script) => {
26
return cardano.transactionSign({
27
signingKeys: [wallet.payment.skey, wallet.payment.skey],
28
scriptFile: script,
29
txBody: tx,
30
});
31
};
32
โ€‹
33
const wallet = cardano.wallet("ADAPI");
34
โ€‹
35
const mintScript = {
36
keyHash: cardano.addressKeyHash(wallet.name),
37
type: "sig",
38
};
39
โ€‹
40
const POLICY_ID = cardano.transactionPolicyid(mintScript);
41
const ASSET_NAME = "BerrySpaceGreen";
42
const ASSET_ID = POLICY_ID + "." + ASSET_NAME;
43
โ€‹
44
const metadata = {
45
721: {
46
[POLICY_ID]: {
47
[ASSET_NAME]: {
48
name: "token name",
49
image: "ipfs://QmQqzMTavQgT4f4T5v6PWBp7XNKtoPmC9jvn12WPT3gkSE",
50
description: "Super Fancy Berry Space Green NFT",
51
type: "image/png",
52
src: "ipfs://Qmaou5UzxPmPKVVTM9GzXPrDufP55EDZCtQmpy3T64ab9N",
53
authors: ["PIADA", "SBLYR"],
54
},
55
},
56
},
57
};
58
โ€‹
59
const tx = {
60
txIn: wallet.balance().utxo,
61
txOut: [
62
{
63
address: wallet.paymentAddr,
64
amount: { ...wallet.balance().amount, [ASSET_ID]: 1 },
65
},
66
],
67
mint: [{ action: "mint", amount: 1, token: ASSET_ID }],
68
metadata,
69
witnessCount: 2,
70
};
71
โ€‹
72
const raw = buildTransaction(tx);
73
const signed = signTransaction(wallet, raw, mintScript);
74
const txHash = cardano.transactionSubmit(signed);
75
console.log(txHash);
Copied!
    Run the minting script, then wait a few moments to check the balance in our wallet
1
cd ..
2
node src/mint-asset.js
Copied!
Video Walk-through:
Untitled
โ€‹

Sending your NFT back to Daedulus or Yoroi wallet

Now we must create a new script to send our newly minted NFT to a wallet.
1
cd cardaon-minter/src
2
nano send-back-asset-to-wallet.js
Copied!
There are few main parts we have to this script in order to send the asset:
    1.
    Get the wallet
    2.
    Define the transaction
    3.
    Build the transaction
    4.
    Calculate the fee
    5.
    Pay the fee by subtracting it from the sender's utxo
    6.
    Build the final transaction
    7.
    Sign the transaction
    8.
    Submit the transaction
1
const cardano = require("./cardano");
2
โ€‹
3
const sender = cardano.wallet("ADAPI");
4
โ€‹
5
console.log(
6
"Balance of Sender wallet: " +
7
cardano.toAda(sender.balance().amount.lovelace) +
8
" ADA"
9
);
10
โ€‹
11
const receiver =
12
"addr1qym6pxg9q4ussr96c9e6xjdf2ajjdmwyjknwculadjya488pqap23lgmrz38glvuz8qlzdxyarygwgu3knznwhnrq92q0t2dv0";
13
โ€‹
14
const txInfo = {
15
txIn: cardano.queryUtxo(sender.paymentAddr),
16
txOut: [
17
{
18
address: sender.paymentAddr,
19
amount: {
20
lovelace: sender.balance().amount.lovelace - cardano.toLovelace(1.5),
21
},
22
},
23
{
24
address: receiver,
25
amount: {
26
lovelace: cardano.toLovelace(1.5),
27
"ad9c09fa0a62ee42fb9555ef7d7d58e782fa74687a23b62caf3a8025.BerrySpaceGreen": 1,
28
},
29
},
30
],
31
};
32
โ€‹
33
const raw = cardano.transactionBuildRaw(txInfo);
34
โ€‹
35
const fee = cardano.transactionCalculateMinFee({
36
...txInfo,
37
txBody: raw,
38
witnessCount: 1,
39
});
40
โ€‹
41
//pay the fee by subtracting it from the sender utxo
42
txInfo.txOut[0].amount.lovelace -= fee;
43
โ€‹
44
//create final transaction
45
const tx = cardano.transactionBuildRaw({ ...txInfo, fee });
46
โ€‹
47
//sign the transaction
48
const txSigned = cardano.transactionSign({
49
txBody: tx,
50
signingKeys: [sender.payment.skey],
51
});
52
โ€‹
53
//subm transaction
54
const txHash = cardano.transactionSubmit(txSigned);
55
console.log("TxHash: " + txHash);
Copied!
1
cd ..
2
node src/send-back-asset-to-wallet.js
Copied!

Final Steps to view your NFT

    1.
    View your nft in your wallet
    2.
    View your asset on cardanoassets.com
    3.
    View your asset on pool.pm (see the actual picture)
    4.
    Show the original minting metadata
    5.
    Open the src and image ipfs links in your browser to prove that it worked

Video Walk-through:

If you liked this tutorial and want to see more like it please consider staking your ADA with any of our Alliance's Stake Pools, or giving a one-time donation to our Alliance https://cointr.ee/armada-alliance.
Last modified 2mo ago