How to mint Cardano NFT using Smart Contract — Part II

Edward Tam
5 min readNov 4, 2021

--

Use case

In part I of this article, we’ve gone through how to build & run a Cardano smart contract (SC), send it some ADA and finally make a transaction to release the ADA stored.

Hope it gave you a basic idea on how the whole process works. The SC we developed before was rather useless as it doesn’t make any validation (release ADA whenever it’s called). We are now going to demo a more useful one, namely minting a non-fungible token (NFT).

Conditions of minting NFT

Actually, NFT can be minted before the launch of SC. At that time, we used a minting script that specifies the same token can’t be minted after certain timeslot. We’ve written an article on this back then. You can check it out here.

The disadvantage of this approach is that we have no idea if only 1 token is actually minted before the timeslot unless we check on blockchain explorer like Cardano Explorer and Cardano Scan.

With the introduction of SC (aka plutus script), it gives us another alternative to do this. The idea is to set the following 2 validations in the script:

  1. no of newly minted token == 1
  2. the input UTXO has to be equal to a specified value

The 1st one is easy to understand as by definition NFT can only has a quantity of 1. The 2nd one is using the trick that once a UXTO is spent, it can never be used again. Having both conditions met, we can ensure this NFT is truly unique in nature.

Plutus Script

We are using the examples from the Lobster challenge and Making NFTs with Plutus. Thanks to authors Lars Brünjes & Jonathan Fischoff for their open sources.

The core of the SC code is listed here:

The 1st validation is to check if UTXO equals to specified value

hasUTxO :: Bool
hasUTxO = any (\i -> txInInfoOutRef i == utxo) $ txInfoInputs info

the 2nd validation is to check if minted amount is 1

checkMintedAmount :: Bool
checkMintedAmount = case flattenValue (txInfoMint info) of [(_, tn', amt)] -> tn' == tn && amt == 1
_ -> False

Making a Minting Transaction

To get started, we have to download the source from github.

Then we need to generate a payment address

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

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

cardano-cli address build \
--payment-verification-key-file payment.vkey \
--stake-verification-key-file stake.vkey \
--out-file payment.addr \
--testnet-magic 1097911063

Fund this payment address using the Testnet Faucet. We can query if it’s funded by

cardano-cli query utxo --address $(cat payment.addr) --testnet-magic 1097911063TxHash                                 TxIx        Amount--------------------------------------------------------------------------------------6c1160302bff7c84b347e6c9c1cf78cbafc8821efc730f6271589fcd848635f7     0        1000000000 lovelace + TxOutDatumHashNone

Note that this UTXO (6c1160302bff7c84b347e6c9c1cf78cbafc8821efc730f6271589fcd848635f7#0) is used as input for minting NFT

Start the nix-shell and build the Haskell program by

cabal build

If successful, we can proceed to run the program

cabal run create-nft-script -- PlutusScriptNFT 6c1160302bff7c84b347e6c9c1cf78cbafc8821efc730f6271589fcd848635f7#0

where 6c1160302bff7c84b347e6c9c1cf78cbafc8821efc730f6271589fcd848635f7#0 is the input UTXO and PlutusScriptNFT is the name of the NFT

the minting script will be generated ./scripts/nft-mint-policy.plutus

Finally, we can send the minting transaction by making use of the script

scripts/mint_nft.sh 6c1160302bff7c84b347e6c9c1cf78cbafc8821efc730f6271589fcd848635f7#0 $(cat ~/payment.addr) ~/payment.skey PlutusScriptNFT

Checking the Minted NFT

Finally, we can check if the NFT is successfully minted by querying the payment address (addr_test1qqtfm03wu070x9lv3vmnfe3q2cxms9ghfgeyk9zq8gv7xtfnp8pp5edacpzucxgsh7hzlvexm9jhettwkljkg5hufm7qq0dm52) on Cardano Scan

The minting TXN
Drill Down the UXTO
Contract (in Bytecode)
The minted token
Metadata recording the properties of the NFT

Challenges Ahead

As you can see above, we can make use of Cardano SC feature to mint an NFT that’s truly unique in nature. NFT minting is just one of the unlimited use cases of SC.

Another typical example is NFT’s Auction. We can send the NFT’s to SC. Bidders can send their ADA to SC and it can determine based on the programmed conditions (e.g highest bid within deadline) to release the NFT to the winner. In this way, both NFT owners and bidders don’t need to trust each other. Instead they only need to trust the SC which can be put on a public place (e.g. Github) to be verified by everybody. An excellent tutorial by Lars can be found here.

Besides, we can build Apps for Decentrailized Finance(Defi), Decentrailized Exchange (DEX), Gaming, Oracle, Stable Coins…, just to name a few.

However, as you may notice, we focus very much on the “on-chain” (validation happening in the blockchain) part of the SC feature, there is also a big “off-chain” part we haven’t focus on. For now, we just make sure of the command line interface (CLI) to create payment addresses & transactions, keep plutus scripts…... It would be to more convenient to have a solution that keeps the wallets, the complied SC and interface to interact with SC. That’s idea of having the Plutus Application Backend (PAB) which is an off-chain, backend service for managing and handling the requirements of the application instance throughout its lifecycle. Further reading can be found here. Certainly, the availability of PAB will speed up the rollout of Cardano Dapps. We will talk more about it when it’s ready for testing.

References

--

--

Edward Tam

Owner of IT companies. Blockchain/Crypto enthusiast. Interested in Cardano, Chainlink, Ethereum, Hyperledger,……