Metapunk Web3 Community

Cover image for How to Create your own Token on the Ethereum Blockchain
Neelansh Mathur
Neelansh Mathur

Posted on • Originally published at dev.to

How to Create your own Token on the Ethereum Blockchain

Learn the basics of Solidity and HardHat while creating your very own transferrable token on the Ethereum Blockchain!

In this article, you will learn how to use HardHat and write a simple Solidity contract to deploy your custom Token.

Before we start, let's look at the basic terms.

  • Smart Contract: A program on the blockchain
  • Solidity: The language to write smart contracts with. If you know JavaScript or similar languages, you'll be very comfortable writing Solidity

Environment for writing Smart Contracts

There are just three basic steps for creating any smart contract:
Write, Compile and Deploy.

We have multiple options to choose from for the environment. The most popular ones are Truffle and HardHat. They both help with writing, compiling, and deploying our smart contracts to the blockchain.

We shall be using HardHat since it is very easy to get started with. Their docs are very concise, so I would recommend giving it a read.

Prerequisites

NodeJS + npm installed. I am using v14.17.6 LTS.

Steps

  1. Initialize npm project

    Create a new directory and run npm init -y to initialize a new npm project.

  2. Install HardHat

npm install --save-dev hardhat
Enter fullscreen mode Exit fullscreen mode

Install hardhat as a dev dependency. Now we can access the hardhat command-line tools with npx hardhat [command].

  1. Create empty configuration file

    Run npx hardhat and select the option to Create an empty hardhat.config.js file.
    The reason for starting with an empty config is that the Hardhat flow is really simple and starting with a boilerplate might leave out valuable insights.
    image.png

  2. Install required dependencies

    To install the other dependencies, run

npm install --save-dev @nomiclabs/hardhat-waffle ethereum-waffle chai @nomiclabs/hardhat-ethers ethers
Enter fullscreen mode Exit fullscreen mode

This command can be found on HardHat's official docs also.

  1. Writing the smart contract Create a directory called contracts, and inside it create a file called Token.sol. Your structure would be /contracts/Token.sol.

HardHat knows to look inside the /contracts directory for your smart contracts. .sol is the file extension for the Solidity programming language.

Open Token.sol in your code editor. If you're using VS Code you will need the solidity extension by Juan Blanco.

Before writing the code (which is short and sweet btw), let's go over the concept of the Token you are about to create:

  • Each token has a name, symbol, total supply and owner.
  • The owner is the account that will initially be used to deploy the contract. This will be your personal MetaMask (Recommended) or other crypto wallets. It will hold all of the fixed supply of tokens which can then be distributed to others.
  • We will need Key-Value pair mappings to store token balances for each address.
  • We will need two basic functions, one to allow transfers between accounts and one to check the balance of an individual account.

Keeping all of these things in mind, let's start by writing the contract itself.

Writing the Token Code

The first line of every solidity file will specify the version of solidity to use for the compiler.

My compiler uses 0.8.7 at the time of this writing, and I'm updating the same in the hardhat config since that has a previous version written by default instead of my compiler's latest version.

// Token.sol
pragma solidity ^0.8.7;
Enter fullscreen mode Exit fullscreen mode

Contract and variables

Next, keeping the conceptual points in mind, we will declare a contract that looks like a JS/TS class declaration and define the variables inside it. Notice how the code is very similar to JavaScript or TypeScript.

pragma solidity ^0.8.7;

contract Token{
    string public name = "Neelansh Manifesto Token";
    string public symbol = "NMT";
    address public owner;
    uint public totalSupply = 1000000;
    mapping(address => uint) balances;
}
Enter fullscreen mode Exit fullscreen mode

You can define your own name and symbol for the token. Don't use special characters like a quotation mark.

The total supply is being defined as 1 million, or 1,000,000.

string and uint data types are self-explanatory. The address data type stores the hexadecimal address of a crypto wallet.

The mapping type is also very simple. It is like an object in JavaScript and maps addresses to their corresponding integer token balances.
It's javascript equivalent would be:

const balances = {
    1: 1000, // Address (assume integer) mapped to token balance
    2: 5000,
    ...
}
Enter fullscreen mode Exit fullscreen mode

Constructor

Every contract once deployed on the blockchain lives in there forever.

So the contract is initialized only once, and that is when the constructor is called. All we need the constructor to do is set the owner of the contract and assign the total supply of coins to the owner.

Since you will be deploying using your personal MetaMask account, your account will be the owner and hold all the tokens.

constructor(){
        owner = msg.sender;
        balances[msg.sender] = totalSupply;
}
Enter fullscreen mode Exit fullscreen mode

msg.sender is the address of the contract or wallet that is executing the transaction and is automatically injected in every contract.

Functions

We need to write functions to transfer tokens between accounts and get the balance of an individual account. The functions are again similar to JS/TS except for some differences which are out of scope for this article.

The complete code will look like this:

pragma solidity ^0.8.7;

contract Token{
    string public name = "Neelansh Manifesto Token";
    string public symbol = "NMT";
    address public owner;
    uint public totalSupply = 1000000;
    mapping(address => uint) balances;

    constructor(){
        owner = msg.sender;
        balances[msg.sender] = totalSupply;
    }

    function transfer(address to, uint amount) external {
        require(balances[msg.sender] >= amount, 'Not enough tokens');
        // Deduct from sender, Add to receiver 
        balances[msg.sender] -= amount;
        balances[to] += amount;
    }

    function balanceOf(address account) external view returns (uint) {
        return balances[account];
    }

}
Enter fullscreen mode Exit fullscreen mode

Compiling Contract

Once you've saved your contract, it's time to compile it for deployment.

npx hardhat compile
Enter fullscreen mode Exit fullscreen mode

image.png

Testing

It is almost always required to write JavaScript tests for your contracts, but we'll skip it otherwise this article may as well be a book πŸ“–

Configuration before Deployment

Before you deploy, you need:

  1. Private Key of your account from MetaMask. Click on the three-dot menu and go to Account Details > Export Private Key Screenshot 2021-09-23 at 2.04.20 AM.png
  2. API URL from Infura Create an account on infura.io. Create a new project, go to settings, change the endpoint to Rinkeby and copy the HTTPS endpoint URL.

image.png

Now in your hardhat.config.js file, use the private key and API URL like this:

/**
 * @type import('hardhat/config').HardhatUserConfig
 */

require('@nomiclabs/hardhat-waffle')

const API_URL = "https://rinkeby.infura.io/v3/74685a5d02de4ec9b17b6fee80738970"
const PRIVATE_KEY = "YOUR_PRIVATE_KEY"

module.exports = {
  solidity: "0.8.7",
  networks:{
    rinkeby: {
      url: API_URL,
      accounts: [`0x${PRIVATE_KEY}`]
    }
  }
};
Enter fullscreen mode Exit fullscreen mode

Be sure to replace the API URL and private key with your own.

We are adding 0x before the private key to make it a hexadecimal address. The account you used for the private key will deploy the contract and our constructor will add the token balance to it.

The require for hardhat-waffle injects ethers into our scripts, which is a JS library we need for our deployment script.

Now we are ready to deploy! πŸ₯³

Deploying the Token

We need a short script to help us deploy our contract. Create a file called deploy.js in a new folder called scripts/ and write the following code into it:

async function main(){
    // Not necessary, but just to see the account deploying from
    const [deployer] = await ethers.getSigners()
    console.log("Deploying contracts with the account", deployer.address)

    const balance = await deployer.getBalance()
    console.log("Account balance", balance.toString())

    // Main stuff
    const Token = await ethers.getContractFactory("Token")
    const token = await Token.deploy()

    console.log("Deployment address: ", token.address)
}

main()
.then(() => process.exit(0))
.catch((e) => {
    console.error(e);
    process.exit(1);
})
Enter fullscreen mode Exit fullscreen mode

Final

To finally deploy your token, run

npx hardhat run scripts/deploy.js --network rinkeby
Enter fullscreen mode Exit fullscreen mode

image.png

Our token has been deployed! But hold on, we still need to see it in MetaMask. Copy the deployment address and store it somewhere.

Adding our Token to MetaMask

Go to MetaMask and the assets tab. At the very bottom, click on Add Token.

Paste in the deployment address of your token as the Token Contract Address, it should automatically fetch the symbol of your token! πŸ’―

image.png

image.png

image.png

YAYYY! Your token is deployed and visible in MetaMask! You can send these tokens to your friends and family and have fun with your very own token on the blockchain! πŸŽ‰πŸŽ‰πŸŽ‰πŸŽ‰πŸŽ‰

Conclusion

This was a very simple token. There are standards like the ERC-20 token standard upon which most serious tokens are based upon, so that would be a good topic to learn after this.

I am no blockchain expert, but I am sharing the knowledge I gain as I go along my journey πŸ˜„

If you face any errors let me know either here or on Twitter @mneelansh15

Discussion (3)

Collapse
lee profile image
lee

Nice post!

Collapse
neelansh15 profile image
Neelansh Mathur Author

Thank you!

Collapse
lee profile image
lee

No problem 😎