This is a deprecated tutorial. Now, it will be archived just for people to use the old tutorial for their own education
Youtube Video: https://www.youtube.com/watch?v=OeOliguGn7Y
- For people who want to make NFT's
- For people who perhaps know Cardano
- Low transaction fees
- Native on the blockchain (perhaps compare with Ethereum, eth is smart contract based)
- cardano-node / cardano-cli set up on local machine (https://docs.cardano.org/projects/cardano-node/en/latest)
- node.js installed
curl -sL https://deb.nodesource.com/setup_14.x | sudo -E bash -
sudo apt-get install -y nodejs
- Verify everything is set up properly
cardano-cli
cardano-cli version
output should be similar:
cardano-cli 1.34.1 - linux-aarch64 - ghc-8.10
git rev 0000000000000000000000000000000000000000
cardano-node
cardano-node version
output should be similar:
cardano-node 1.34.1 - linux-aarch64 - ghc-8.10
git rev 0000000000000000000000000000000000000000
node.js
node -v
v14.19.0
-
verify env
-
create project and initial setup
#make sure our db is in our $PATH
CARDANO_NODE_SOCKET_PATH="$NODE_HOME/db/socket"
mkdir cardano-minter
cd cardano-minter
npm init -y #creates package.json)
npm install cardanocli-js --save
-
Copy the Cardano node genesis latest build number from IOHK hydra website
-
Download Genesis config file needed for shelly-era
nano fetch-config.sh
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
wget -N https://hydra.iohk.io/build/${NODE_BUILD_NUM}/download/1/testnet-shelley-genesis.json
chmod +x fetch-config.sh
./fetch-config.sh
- make src folder/directory and then create Cardano client
mkdir src; cd src
nano cardano.js
const CardanocliJs = require("cardanocli-js");
const os = require("os");
const path = require("path");
const dir = path.join(os.homedir(), "cardano-minter");
const shelleyPath = path.join(
os.homedir(),
"pi-pool/files",
"testnet-shelley-genesis.json"
);
const cardanocliJs = new CardanocliJs({
// era: "mary",
network: 'testnet-magic 1097911063',
dir,
shelleyGenesisPath: shelleyPath,
});
module.exports = cardanocliJs
- create wallet
nano create-wallet.js
const cardano = require("./cardano");
const createWallet = (account) => {
cardano.addressKeyGen(account);
cardano.stakeAddressKeyGen(account);
cardano.stakeAddressBuild(account);
cardano.addressBuild(account);
return cardano.wallet(account);
};
createWallet("ADAPI");
cd cardano-minter
node src/create-wallet.js
- Verify balance wallet balance is Zero, then we fund the wallet
- First we need to create a get-balance.js script
# open text editor
cd cardano-minter/src; nano get-balance.js
// create get-balance.js
const cardano = require("./cardano");
const sender = cardano.wallet("ADAPI");
console.log(sender.balance());
- check the balance (utxo)
cd ..
node src/get-balance.js
-
Download IPFS
-
Upload your files to IPFS
- image - ipfs://QmQqzMTavQgT4f4T5v6PWBp7XNKtoPmC9jvn12WPT3gkSE
- src - ipfs://Qmaou5UzxPmPKVVTM9GzXPrDufP55EDZCtQmpy3T64ab9N
-
Generate policy id
-
Define your meta data
-
create mint transaction
const cardano = require("./cardano")
// 1. Get the wallet
const wallet = cardano.wallet("ADAPI")
// 2. Define mint script
const mintScript = {
keyHash: cardano.addressKeyHash(wallet.name),
type: "sig"
}
// 3. Create POLICY_ID
const POLICY_ID = cardano.transactionPolicyid(mintScript)
// 4. Define ASSET_NAME
const ASSET_NAME = "TimeWarpBerry"
// Convert Asset ASCII name to HEX
const ASSET_NAME_HEX = ASSET_NAME.split("").map(c => c.charCodeAt(0).toString(16).padStart(2, "0")).join("");
// 5. Create ASSET_ID
const ASSET_ID = POLICY_ID + "." + ASSET_NAME_HEX
// 6. Define metadata
const metadata = {
721: {
[POLICY_ID]: {
[ASSET_NAME]: {
name: ASSET_NAME,
image: "ipfs://QmUxRuzTi3UZS33rfqXzbD4Heut7zwtGUhuD7qSv7Qt584",
description: "Time Warp Berry NFT",
type: "image/png",
src: "ipfs://QmUxRuzTi3UZS33rfqXzbD4Heut7zwtGUhuD7qSv7Qt584",
// other properties of your choice
authors: ["PIADA", "SBLYR"]
}
}
}
}
// 7. Define transaction
const tx = {
txIn: wallet.balance().utxo,
txOut: [
{
address: wallet.paymentAddr,
value: { ...wallet.balance().value, [ASSET_ID]: 1 }
}
],
mint: [
{ action: "mint", quantity: 1, asset: ASSET_ID, script: mintScript },
],
metadata,
witnessCount: 2
}
if(Object.keys(tx.txOut[0].value).includes("undefined")|| Object.keys(tx.txIn[0].value.includes("undefinded"))){
delete tx.txOut[0].value.undefined
delete tx.txIn[0].value.undefined
}
// 8. Build transaction
const buildTransaction = (tx) => {
const raw = cardano.transactionBuildRaw(tx)
const fee = cardano.transactionCalculateMinFee({
...tx,
txBody: raw
})
tx.txOut[0].value.lovelace -= fee
return cardano.transactionBuildRaw({ ...tx, fee })
}
console.log(tx)
const raw = buildTransaction(tx)
// 9. Sign transaction
const signTransaction = (wallet, tx) => {
return cardano.transactionSign({
signingKeys: [wallet.payment.skey, wallet.payment.skey ],
txBody: tx
})
}
const signed = signTransaction(wallet, raw)
// 10. Submit transaction
const txHash = cardano.transactionSubmit(signed)
console.log(txHash)
- Run the minting script, then wait a few moments to check the balance (utxo)
cd ..
node src/mint-asset.js
node src/get-balance.js
- send your nft back to your wallet
- Create anew script to send nft to wallet
const cardano = require("./cardano");
// 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 utxo
// 6. build the final transaction
// 7. sign the transaction
// 8. submit the transaction
const sender = cardano.wallet("ADAPI");
console.log(
"Balance of Sender wallet: " +
cardano.toAda(sender.balance().amount.lovelace) +
" ADA"
);
const receiver =
"addr_test1qqqydvg5wzd6twvernsjcdjd9akmygyqp7gky7zpm0hrmq3ccwlnumzzuum6k6ja2k47g5dv2p4kwt753mpjjzx8fsmsq2aj0p";
const txInfo = {
txIn: cardano.queryUtxo(sender.paymentAddr),
txOut: [
{
address: sender.paymentAddr,
amount: {
lovelace: sender.balance().amount.lovelace - cardano.toLovelace(1.5),
},
},
{
address: receiver,
amount: {
lovelace: cardano.toLovelace(1.5),
"9e57c3a4aa769063ab4963e3e2fc18aeafb6808b3adbc3f1670a9c00.54696d65576172704265727279": 1,
},
},
],
};
const raw = cardano.transactionBuildRaw(txInfo);
const fee = cardano.transactionCalculateMinFee({
...txInfo,
txBody: raw,
witnessCount: 1,
});
//pay the fee by subtracting it from the sender utxo
txInfo.txOut[0].amount.lovelace -= fee;
//create final transaction
const tx = cardano.transactionBuildRaw({ ...txInfo, fee });
//sign the transaction
const txSigned = cardano.transactionSign({
txBody: tx,
signingKeys: [sender.payment.skey],
});
//subm transaction
const txHash = cardano.transactionSubmit(txSigned);
console.log("TxHash: " + txHash);
-
view your nft in your wallet
-
View your asset on cardanoassets.com
-
View your asset on pool.pm (see the actual picture)
-
Show the original minting metadata
-
open the src ipfs to prove that it work