Create and Transfer Your First NFT
Using the Hedera Token Service, you can create non-fungible tokens (NFTs). NFTs are uniquely identifiable. On the Hedera network, the token ID represents a collection of NFTs of the same class, and the serial number of each token uniquely identifies each NFT in the class.
We recommend you complete the following introduction to get a basic understanding of Hedera transactions. This example does not build upon the previous examples.
Use
TokenCreateTransaction()
to configure and set the token properties. At a minimum, this constructor requires setting a name, symbol, and treasury account ID. All other fields are optional, so if they’re not specified then default values are used. For instance, not specifying an admin key, makes a token immutable (can’t change or add properties); not specifying a supply key, makes a token supply fixed (can’t mint new or burn existing tokens); not specifying a token type, makes a token fungible.After submitting the transaction to the Hedera network, you can obtain the new token ID by requesting the receipt. This token ID represents an NFT class.
Java
JavaScript
Go
//Create the NFT
TokenCreateTransaction nftCreate = new TokenCreateTransaction()
.setTokenName("diploma")
.setTokenSymbol("GRAD")
.setTokenType(TokenType.NON_FUNGIBLE_UNIQUE)
.setDecimals(0)
.setInitialSupply(0)
.setTreasuryAccountId(treasuryId)
.setSupplyType(TokenSupplyType.FINITE)
.setMaxSupply(250)
.setSupplyKey(supplyKey)
.freezeWith(client);
//Sign the transaction with the treasury key
TokenCreateTransaction nftCreateTxSign = nftCreate.sign(treasuryKey);
//Submit the transaction to a Hedera network
TransactionResponse nftCreateSubmit = nftCreateTxSign.execute(client);
//Get the transaction receipt
TransactionReceipt nftCreateRx = nftCreateSubmit.getReceipt(client);
//Get the token ID
TokenId tokenId = nftCreateRx.tokenId;
//Log the token ID
System.out.println("Created NFT with token ID " +tokenId);
//Create the NFT
let nftCreate = await new TokenCreateTransaction()
.setTokenName("diploma")
.setTokenSymbol("GRAD")
.setTokenType(TokenType.NonFungibleUnique)
.setDecimals(0)
.setInitialSupply(0)
.setTreasuryAccountId(treasuryId)
.setSupplyType(TokenSupplyType.Finite)
.setMaxSupply(250)
.setSupplyKey(supplyKey)
.freezeWith(client);
//Sign the transaction with the treasury key
let nftCreateTxSign = await nftCreate.sign(treasuryKey);
//Submit the transaction to a Hedera network
let nftCreateSubmit = await nftCreateTxSign.execute(client);
//Get the transaction receipt
let nftCreateRx = await nftCreateSubmit.getReceipt(client);
//Get the token ID
let tokenId = nftCreateRx.tokenId;
//Log the token ID
console.log(`- Created NFT with Token ID: ${tokenId} \n`);
//Create the NFT
nftCreate, err := hedera.NewTokenCreateTransaction().
SetTokenName("diploma").
SetTokenSymbol("GRAD").
SetTokenType(hedera.TokenTypeNonFungibleUnique).
SetDecimals(0).
SetInitialSupply(0).
SetTreasuryAccountID(treasuryAccountId).
SetSupplyType(hedera.TokenSupplyTypeFinite).
SetMaxSupply(250).
SetSupplyKey(supplyKey).
FreezeWith(client)
//Sign the transaction with the treasury key
nftCreateTxSign := nftCreate.Sign(treasuryKey)
//Submit the transaction to a Hedera network
nftCreateSubmit, err := nftCreateTxSign.Execute(client)
//Get the transaction receipt
nftCreateRx, err := nftCreateSubmit.GetReceipt(client)
//Get the token ID
tokenId := *nftCreateRx.TokenID
//Log the token ID
fmt.Println("Created NFT with token ID ", tokenId)
When creating an NFT, the decimals and initial supply must be set to zero. After the token is created, you mint each NFT using the token mint operation. Specifying a supply key during token creation is a requirement to be able to mint and burn tokens. The supply key is required to sign mint and burn transactions.
Both the NFT image and metadata live in the InterPlanetary File System (IPFS), which provides decentralized storage. The file diploma_metadata.json contains the metadata for the NFT. A content identifier (CID) pointing to the metadata file is used during minting of the new NFT. Notice that the metadata file contains a URI pointing to the NFT image.
Java
JavaScript
Go
// IPFS content identifiers for which we will create a NFT
String CID = ("QmTzWcVfk88JRqjTpVwHzBeULRTNzHY7mnBSG42CpwHmPa") ;
// Mint a new NFT
TokenMintTransaction mintTx = new TokenMintTransaction()
.setTokenId(tokenId)
.addMetadata(CID.getBytes())
.freezeWith(client);
//Sign transaction with the supply key
TokenMintTransaction mintTxSign = mintTx.sign(supplyKey);
//Submit the transaction to a Hedera network
TransactionResponse mintTxSubmit = mintTxSign.execute(client);
//Get the transaction receipt
TransactionReceipt mintRx = mintTxSubmit.getReceipt(client);
//Log the serial number
System.out.println("Created NFT " +tokenId + "with serial: " +mintRx.serials);
//IPFS content identifiers for which we will create a NFT
CID = "ipfs://QmTzWcVfk88JRqjTpVwHzBeULRTNzHY7mnBSG42CpwHmPa";
// Mint new NFT
let mintTx = await new TokenMintTransaction()
.setTokenId(tokenId)
.setMetadata([Buffer.from(CID)])
.freezeWith(client);
//Sign the transaction with the supply key
let mintTxSign = await mintTx.sign(supplyKey);
//Submit the transaction to a Hedera network
let mintTxSubmit = await mintTxSign.execute(client);
//Get the transaction receipt
let mintRx = await mintTxSubmit.getReceipt(client);
//Log the serial number
console.log(`- Created NFT ${tokenId} with serial: ${mintRx.serials[0].low} \n`);
//IPFS content identifiers for which we will create a NFT
CID := "QmTzWcVfk88JRqjTpVwHzBeULRTNzHY7mnBSG42CpwHmPa"
//Mint new NFT
mintTx, err := hedera.NewTokenMintTransaction().
SetTokenID(tokenId).
SetMetadata([]byte(CID)).
FreezeWith(client)
//Sign the transaction with the supply key
mintTxSign := mintTx.Sign(supplyKey)
//Submit the transaction to a Hedera network
mintTxSubmit, err := mintTxSign.Execute(client)
//Get the transaction receipt
mintRx, err := mintTxSubmit.GetReceipt(client)
//Log the serial number
fmt.Print("Created NFT ", tokenId, " with serial: ", mintRx.SerialNumbers)o
diploma_metadata.json
{
"name": "Diploma",
"description": "Certificate of Graduation",
"image": "https://ipfs.io/ipfs/QmdTNJDYePd4EUUzYPuhc1GsDELjab6ypgvDQAp4visoM9?filename=diploma.jpg",
"properties": {
"university": "H State University",
"college": "Engineering and Applied Sciences",
"level": "Masters",
"field": "Mechanical Engineering",
"honors": "yes",
"honorsType": "Summa Cum Laude",
"gpa": "3.84",
"student": "Alice",
"date": "2021-03-18"
}
}
Before an account that is not the treasury for a token can receive or send this specific token ID, the account must become “associated” with the token. To associate a token to an account the account owner must sign the associate transaction.
If you have an account with the automatic token association property set you do not need to associate the token before transferring it the receiving account.
Java
JavaScript
Go
//Create the associate transaction and sign with Alice's key
TokenAssociateTransaction associateAliceTx = new TokenAssociateTransaction()
.setAccountId(aliceAccountId)
.setTokenIds(Collections.singletonList(tokenId))
.freezeWith(client)
.sign(aliceKey);
//Submit the transaction to a Hedera network
TransactionResponse associateAliceTxSubmit = associateAliceTx.execute(client);
//Get the transaction receipt
TransactionReceipt associateAliceRx = associateAliceTxSubmit.getReceipt(client);
//Confirm the transaction was successful
System.out.println("NFT association with Alice's account: " +associateAliceRx.status);
//Create the associate transaction and sign with Alice's key
let associateAliceTx = await new TokenAssociateTransaction()
.setAccountId(aliceId)
.setTokenIds([tokenId])
.freezeWith(client)
.sign(aliceKey);
//Submit the transaction to a Hedera network
let associateAliceTxSubmit = await associateAliceTx.execute(client);
//Get the transaction receipt
let associateAliceRx = await associateAliceTxSubmit.getReceipt(client);
//Confirm the transaction was successful
console.log(`- NFT association with Alice's account: ${associateAliceRx.status}\n`);
//Create the associate transaction
associateAliceTx, err := hedera.NewTokenAssociateTransaction().
SetAccountID(aliceAccountId).
SetTokenIDs(tokenId).
FreezeWith(client)
//Sign with Alice's key
signTx := associateAliceTx.Sign(aliceKey)
//Submit the transaction to a Hedera network
associateAliceTxSubmit, err := signTx.Execute(client)//Get the transaction receipt