Skip to content

Create Publication

We are looking for publications that demonstrate building dApps or smart contracts!
See the full list of Gitcoin bounties that are eligible for rewards.

Create an NFT

What are NFTs?

Non-fungible tokens, or NFTs for short, are unique assets represented on the blockchain. Digital art and collectibles are types of NFTs that you may have heard about, but they only scratch the surface of what is possible.

Examples of NFTs

Examples of NFT use cases: Tokenizing the rights to a song to facilitate royalty payments, in-game collectibles, or special edition brand merchandise.

Remember that Alice wants to use blockchain to help her scale and grow her business, because it provides important properties that she cannot achieve otherwise (trust, transparency, efficiency, low costs). The first step for her is to represent her unique art pieces on-chain as NFTs. Let's go ahead and learn how to create an NFT on Algorand.

How to create NFTs

NFTs are created using Algorand Standard Assets (ASAs), which are built into the protocol and activated using a special type of transaction. You do not need to write smart contract code, which may be the case on some other blockchains. You just need to specify a few parameters to identify it as an NFT (e.g. total count of 1) and attach metadata so that potential owners have the information they need to validate the integrity of the asset. The relevant code snippet in each of the SDKs is as follows:

txn = AssetConfigTxn(sender=accounts[1]['pk'],
                     sp=params,
                     total=1,           // NFTs have totalIssuance of exactly 1
                     default_frozen=False,
                     unit_name="ALICEART",
                     asset_name="Alice's [email protected]",
                     manager="",
                     reserve="",
                     freeze="",
                     clawback="",
                     url="https://path/to/my/nft/asset/metadata.json",
                     metadata_hash=json_metadata_hash,
                     decimals=0)        // NFTs have decimals of exactly 0
const creator = alice.addr;
const defaultFrozen = false;    
const unitName = "ALICEART"; 
const assetName = "Alice's [email protected]";
const url = "https://path/to/my/nft/asset/metadata.json";
const managerAddr = undefined; 
const reserveAddr = undefined;  
const freezeAddr = undefined;
const clawbackAddr = undefined;
const total = 1;                // NFTs have totalIssuance of exactly 1
const decimals = 0;             // NFTs have decimals of exactly 0
const txn = algosdk.makeAssetCreateTxnWithSuggestedParamsFromObject({
    creator,
    total,
    decimals,
    assetName,
    unitName,
    assetURL: url,
    assetMetadataHash: metadata,
    defaultFrozen,
    freeze: freezeAddr,
    manager: managerAddr,
    clawback: clawbackAddr,
    reserve: reserveAddr,
    suggestedParams: params,});
    String creator = aliceAccount.getAddress().toString()
    boolean defaultFrozen = false;
    String unitName = "ALICEART";
    String assetName = "Alice's [email protected]";
    String url = "https://path/to/my/nft/asset/metadata.json";
    Address manager = null;  
    Address reserve = null;
    Address freeze = null;
    Address clawback = null;      
    BigInteger assetTotal = BigInteger.valueOf(1);  // NFTs have totalIssuance of exactly 1
    Integer decimals = 0;                           // NFTs have decimals of exactly 0
    Transaction tx = Transaction.AssetCreateTransactionBuilder()
            .sender(creator)
            .assetTotal(assetTotal)
            .assetDecimals(decimals)
            .assetUnitName(unitName)
            .assetName(assetName)
            .url(url)
            .metadataHash(assetMetadataHash)
            .manager(manager)
            .reserve(reserve)
            .freeze(freeze)
            .defaultFrozen(defaultFrozen)
            .clawback(clawback)
            .suggestedParams(params)
            .build();   
creator := account.Address.String()
assetName := "Alice's [email protected]"
unitName := "ALICEART"
assetURL := "https://path/to/my/nft/asset/metadata.json"
assetMetadataHash := metadatHash
totalIssuance := uint64(1)          // NFTs have totalIssuance of exactly 1
decimals := uint32(0)               // NFTs have decimals of exactly 0
manager := ""
reserve := ""
freeze := ""
clawback := ""
defaultFrozen := false
note := []byte(nil)

txn, err := transaction.MakeAssetCreateTxn(
    creator, note, txParams, totalIssuance, decimals,
    defaultFrozen, manager, reserve, freeze, clawback,
    unitName, assetName, assetURL, assetMetadataHash)

Now let's go ahead and create Alice’s NFT. We will use the Algorand Foundation’s proposed ARC-0003 NFT standard. Choose your favorite SDK to run the full code example for creating an NFT on TestNet and watch the step-by-step video guide.

Once created, the asset will have a unique ID on the Algorand blockchain. If you ran the code above, you can use a block explorer to find your newly created NFT on TestNet.

Alice creates an NFT

Alice tokenizes her art piece as an NFT on Algorand.

Composability

ASAs can be composed with other features on Algorand (like smart contracts) and with applications built on top of Algorand. What makes this possible is the combination of the standard representation of an NFT on the Algorand blockchain, both as an ASA and specifically as a unique ASA, and the openness and permissionless nature of the Algorand blockchain. The fact that you can immediately look up the asset you created on TestNet on any block explorer is a small example of composability in action.

Fractional NFTS

A fractional NFT is a unique asset that has been divided into multiple, equal shares. When NFTs are selling for millions of dollars, this may be one way to lower the bar for entry and reach more potential buyers who would not have been able to invest in the whole NFT. The other side of the coin (pun intended) is that by increasing your pool of potential buyers, you may see the value of your NFT increase. Need a compelling example? In September 2021, the owner of a meme Doge NFT who paid 4 million dollars for it, fractionalized it and then auctioned off a portion of those fractional shares at a price that revalued their asset at 225 million USD1.

Maybe Alice should think about fractionalizing her artwork for her next auction!

To create a fractional NFT, the total units must be a power of 10, greater than 1, and the number of decimals must be equal to the logarithm in base 10 of the total number of units. The fractional NFT standard is defined as part of ARC-0003.

const from = alice.addr;
const defaultFrozen = false;    
const unitName = "FRACTION"; 
const assetName = "[email protected]";
const url = "https://path/to/my/nft/asset/metadata.json";
const managerAddr = undefined; 
const reserveAddr = undefined;  
const freezeAddr = undefined;
const clawbackAddr = undefined;
const total = 10;        // Total MUST be a power of 10 larger than 1: 10, 100, 1000, ...(total) * .1(each) = 1.0 
const decimals = 1;      // Decimals MUST be equal to the logarithm in base 10 of total number of units: 10
const txn = algosdk.makeAssetCreateTxnWithSuggestedParamsFromObject({
    creator,
    total,
    decimals,
    assetName,
    unitName,
    assetURL: url,
    assetMetadataHash: metadata,
    defaultFrozen,
    freeze: freezeAddr,
    manager: managerAddr,
    clawback: clawbackAddr,
    reserve: reserveAddr,
    suggestedParams: params,});    
txn = AssetConfigTxn(sender=accounts[1]['pk'],
                     sp=params,
                     total=10,       // Total MUST be a power of 10 larger than 1: 10, 100, 1000, ...
                     default_frozen=False,
                     unit_name="ALICEART",
                     asset_name="Alice's [email protected]",
                     manager="",
                     reserve="",
                     freeze="",
                     clawback="",
                     url="https://path/to/my/fractional/asset/metadata.json",
                     metadata_hash=json_metadata_hash,
                     decimals=1)        // Decimals MUST be equal to the logarithm in base 10 of total number of units
    String creator = aliceAccount.getAddress().toString()
    boolean defaultFrozen = false;
    String unitName = "ALICEART";
    String assetName = "Alice's [email protected]";
    String url = "https://path/to/my/fractional/asset/metadata.json";
    Address manager = null;  
    Address reserve = null;
    Address freeze = null;
    Address clawback = null;      
    BigInteger assetTotal = BigInteger.valueOf(10); // Total MUST be a power of 10 larger than 1: 10, 100, 1000, ...
    Integer decimals = 1;                           // Decimals MUST be equal to the logarithm in base 10 of total number of units
    Transaction tx = Transaction.AssetCreateTransactionBuilder()
            .sender(creator)
            .assetTotal(assetTotal)
            .assetDecimals(decimals)
            .assetUnitName(unitName)
            .assetName(assetName)
            .url(url)
            .metadataHash(assetMetadataHash)
            .manager(manager)
            .reserve(reserve)
            .freeze(freeze)
            .defaultFrozen(defaultFrozen)
            .clawback(clawback)
            .suggestedParams(params)
            .build();   
creator := account.Address.String()
assetName := "Alice's [email protected]"
unitName := "ALICEART"
assetURL := "https://path/to/my/fractional/asset/metadata.json"
assetMetadataHash := metadataHash
totalIssuance := uint64(10)      // Total MUST be a power of 10 larger than 1: 10, 100, 1000, ...
decimals := uint32(1)            // Decimals MUST be equal to the logarithm in base 10 of total number of units
manager := ""
reserve := ""
freeze := ""
clawback := ""
defaultFrozen := false
note := []byte(nil)

txn, err := transaction.MakeAssetCreateTxn(
    creator, note, txParams, totalIssuance, decimals,
    defaultFrozen, manager, reserve, freeze, clawback,
    unitName, assetName, assetURL, assetMetadataHash)

More NFT Resources