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
Initialize npm project
Create a new directory and runnpm init -y
to initialize a new npm project.Install HardHat
npm install --save-dev hardhat
Install hardhat as a dev dependency. Now we can access the hardhat command-line tools with npx hardhat [command]
.
Create empty configuration file
Runnpx 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.
Install required dependencies
To install the other dependencies, run
npm install --save-dev @nomiclabs/hardhat-waffle ethereum-waffle chai @nomiclabs/hardhat-ethers ethers
This command can be found on HardHat's official docs also.
-
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;
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;
}
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,
...
}
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;
}
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];
}
}
Compiling Contract
Once you've saved your contract, it's time to compile it for deployment.
npx hardhat compile
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:
- Private Key of your account from MetaMask. Click on the three-dot menu and go to Account Details > Export Private Key
- 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.
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}`]
}
}
};
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);
})
Final
To finally deploy your token, run
npx hardhat run scripts/deploy.js --network rinkeby
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! 💯
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
Top comments (3)
thank you! If I succeed I'll be thankful
I wish you luck on your journey mate!
Wow awesome