Understanding Fungible and Non-Fungible Tokens

Tutorial 2 of 5

1. Introduction

1.1 Brief explanation of the tutorial's goal

This tutorial aims to provide a comprehensive understanding of Fungible and Non-Fungible Tokens, two critical concepts in the realm of cryptocurrencies and blockchain technology. By the end of this tutorial, you'll have a solid grasp of what these tokens are, their unique characteristics, and their typical use cases.

1.2 What the user will learn

In this tutorial, you will learn:

  • The definitions of Fungible and Non-Fungible Tokens.
  • The unique characteristics of each token type.
  • The use cases for Fungible and Non-Fungible Tokens.
  • Examples of both Fungible and Non-Fungible Tokens.

1.3 Prerequisites

While this tutorial is beginner-friendly, a basic understanding of blockchain technology and cryptocurrencies would be beneficial.

2. Step-by-Step Guide

2.1 Fungible Tokens

Fungible tokens are a type of cryptographic token that are interchangeable with each other. This means that each token is identical to every other token; they are all equal in value. An example of a fungible token is Bitcoin. Every single Bitcoin is worth the same as every other Bitcoin.

2.2 Non-Fungible Tokens (NFTs)

Unlike fungible tokens, Non-Fungible Tokens are not interchangeable as they have unique properties. This means each NFT has a different value. An example of a NFT is a ticket to a concert. Each ticket has a different seat number and therefore has a different value.

3. Code Examples

3.1 Fungible Tokens

A common example of fungible tokens is ERC20 tokens on the Ethereum blockchain. Below is a simple implementation of an ERC20 token.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

contract MyToken is ERC20 {
    constructor(uint256 initialSupply) ERC20("MyToken", "MTK") {
        _mint(msg.sender, initialSupply);
    }
}

This code creates a new ERC20 token. The _mint function is used to create new tokens and add them to the balance of msg.sender.

3.2 Non-Fungible Tokens

An example of non-fungible tokens is ERC721 tokens on the Ethereum blockchain. Below is a simple implementation of an ERC721 token.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC721/ERC721.sol";

contract MyNFT is ERC721 {
    uint256 public tokenCounter;

    constructor () public ERC721 ("MyNFT", "MNFT"){
        tokenCounter = 0;
    }

    function createCollectible(string memory tokenURI) public returns (uint256) {
        uint256 newItemId = tokenCounter;
        _mint(msg.sender, newItemId);
        _setTokenURI(newItemId, tokenURI);
        tokenCounter = tokenCounter + 1;
        return newItemId;
    }
}

This code creates a new ERC721 token. The createCollectible function is used to create a new unique token with a unique tokenURI.

4. Summary

Throughout this tutorial, we have learned about fungible and non-fungible tokens, their unique characteristics, and their use cases. We have also seen examples of both fungible and non-fungible tokens implemented on the Ethereum blockchain.

5. Practice Exercises

5.1 Exercise 1: Create your own Fungible Token

Create a fungible token with a total supply of 1000 tokens using the ERC20 standard. Name the token whatever you like.

5.2 Exercise 2: Create your own Non-Fungible Token

Create a non-fungible token using the ERC721 standard. Each token should be unique.

Solutions

Solution to Exercise 1:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

contract MyToken is ERC20 {
    constructor() ERC20("MyToken", "MTK") {
        _mint(msg.sender, 1000);
    }
}

Solution to Exercise 2:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC721/ERC721.sol";

contract MyNFT is ERC721 {
    uint256 public tokenCounter;

    constructor () public ERC721 ("MyNFT", "MNFT"){
        tokenCounter = 0;
    }

    function createCollectible(string memory tokenURI) public returns (uint256) {
        uint256 newItemId = tokenCounter;
        _mint(msg.sender, newItemId);
        _setTokenURI(newItemId, tokenURI);
        tokenCounter = tokenCounter + 1;
        return newItemId;
    }
}

Remember to keep exploring different token implementations to solidify your understanding. Happy coding!