I prepare this concise and step-by-step tutorial to supplement Hardhat's official tutorial for beginners in Solidity. The tutorial includes an introduction and the following three sections:
1 . Install and init an (empty) sample project
2 . Write ERC20 token with OpenZeppelin
3 . Write ERC72 NFT token
(updated at 03/2023 forHardhat V2.13.0 andSolidity 0.8.18)
Hardhat is an Ethereum development tool suite which can be used to compile, unit test, debug and deploy smart contracts. Like most Ethereum libraries and tools, Hardhat is written in JavaScript andNode.js
. Btw, you may also be interested to knowfoundry
which is written in Rust.
Let me explain several important features of Hardhat for you before we install Hardhat and use it.
0. Introduction
The main component of Hardhat is currently called Hardhat Runner which is a command line tool.
Hardhat Runner, Tasks and Plugins
According to Hardhat's documents, it is designed around the concepts of Tasks and Plugins.
Tasks: When we run Hardhat from command line, we run a task. Tasks are used for automation. We can check all the built-in and user-created tasks with
yarn hardhat help
.Plugins: Plugins of Hardhat are used for integrating other libraries/tools and extending the built-in functionality. It comes with official plugins such as hardhat-ethers, hardhat-waffle, hardhat-ganache, etc. We can also create our own hardhat plugins.
Hardhat Network, a local ethereum blockchain testnet
Hardhat comes with a local ethereum blockchain with EVM calledHardhat Network. You can run Hardhat Network in two modes:
In-process local blockchain, an ephemeral ethereum network that is created and destroyed with the process;
Stand-alone local blockchain, serving JSON-RPC and WebSocket requests. You can start it by running
yarn hardhat node
.
Instead of Hardhat Network, Hardhat can also be used with Ganache, the most known ethereum local blockchain testnet for developers. The Ethereum Virtual Machines (EVMs) in Hardhat Network, Ganache and Remix IDE are all based on@ethereumjs/vm
EVM implementation.
Hardhat can also fork mainnet which means "copy the state of the Ethereum mainnet into your local testnet including all balances and deployed contracts." Find more information at:https://hardhat.org/hardhat-network/guides/mainnet-forking.html .
Debugging-first:console.log()
The first reason why many developers choose Hardhat over Truffle Suite isconsole.log()
. Hardhat is debugging-first by providing the most-needed JavaScript styleconsole.log()
in Solidity for debugging smart contract. It also provides Solidity stack traces and explicit error messages when transactions fail.
Hardhat's unit test usesMocha
andChai
currently.
Interactive console
Just as Truffle Suite, Hardhat provides an interactive JavaScript console. We can run Hardhat console by runningyarn hardhat console
oryarn hardhat console --network localhost
.
I prefer to interact with my contracts step by step using this console during the development process although I surely write scripts.
1. Install Hardhat and init an (empty) Hardhat Project
In this section, we go through the process of initiating a hardhat project in 6 steps to give you an overall view of how to use Hardhat. Deep explanation of Solidity smart contract and Javascript script is deferred to later sections.
Step 1: Install Node.js and yarn
Hardhat is written in JavaScript using Node.js. To use it, we needNode.js
andyarn
(ornpm
) installed.
If needed, you can download and install them fromhttps://nodejs.org/en/. Once Node.js installed, check its version by running:
node-v//v19.7.0
Step 2: Prepare directory and install Hardhat
We conduct 3 tasks in this step: make a directory; init a Node.js project withyarn
; and install hardhat as devDependencies in this environment.
mkdirhardhat-tut&&cdhardhat-tutyarn init--yesyarn add hardhat
Check the hardhat version:
yarn hardhat--version//2.13.0
Step 3: Init Hardhat project
When Hardhat is installed, we use Hardhat Runner CLI to init a sample project. Run the following command and choose "Create an advanced sample project that uses TypeScript".
yarn hardhat
It will init a project and add some dependencies. In the sample project, there are three sub-directories and a configuration file. Let's check it withtree -I node_modules/ -d -L 1
.├── contracts├── scripts└──test
Sample smart contract is in thecontracts
dir, unit test file is in thetest
dir, and deploy script is inscripts
dir.
Now, you can choose your favorite IDE (VS Code for example) to write smart contracts in Solidity as well as unit test and deploy scripts in Javascript.
Step 4: Compile, Test and Deploy
In the basic sample project, there is already a sample smart contractLock.sol
in contracts directory as well as unit test scriptLock.ts
and deploy scriptdeploy.ts
for it. (You may also
be interested in theGreeter.sol
in the previous version of hardhat/Remix.)
The development circle of smart contract is "Compile, Test and Deploy".
Compile :
yarn hardhat compile
Unit Test :
yarn hardhattest
Deploy:
yarn hardhat run scripts/deploy.ts//Output: Lock with 0.001ETH and unlock timestamp 1679119583 deployed to 0x5FbDB2315678afecb367f032d93F642f64180aa3
Please note that the Lock smart contract is deployed tothe in-process blockchain testnet which is destroyed with the precess.
If you want to deploy it to another network such as localhost, runyarn hardhat run scripts/deploy.ts --network localhost
. Let's continue to configure for the standalone Hardhat local blockchain testnet and deployLock.sol
to it.
Step 5: Config the hardhat project
The config file ishardhat.config.ts
. We can configure our hardhat project in it.
import{HardhatUserConfig}from"hardhat/config";import"@nomicfoundation/hardhat-toolbox";constconfig:HardhatUserConfig={solidity:"0.8.18",};exportdefaultconfig;
By default, hardhat support stand-alonelocalhost
network and in-processhardhat
network. So to use localhost standalone testnet, we don't need to do any modification in the configuration file.
{ localhost: { url: "http://127.0.0.1:8545" }, hardhat: { // See its defaults }}
Let's run a standalone testnet and deploy smart contract to it.
Task ONE: in another terminal, run the testnet:
yarn hardhat node
Output:
Started HTTP and WebSocket JSON-RPC server at http://127.0.0.1:8545/Accounts========Account#0: 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 (10000 ETH)Private Key: 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80...
Task TWO: run deploy script in the localhost:
yarn hardhat run scripts/deploy.ts--network localhost//Lock with 0.001ETH and unlock timestamp 1679119754 deployed to 0x5FbDB2315678afecb367f032d93F642f64180aa3
In the other terminal, we can see output of the testnet:
eth_sendTransaction Contract deployment: Lock Contract address: 0x5fbdb2315678afecb367f032d93f642f64180aa3 Transaction: 0x26b0d85de3bf5fa7530264fef2edfc89bd9eaba89730b9c338d4c5b7583ac11f From: 0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266 Value: 0.001 ETH Gas used: 326016 of 326016 Block #1: 0x24288deb19e27e3ba6aa08dec267d4091c228984ec939ea2a9161cb872dbf905
If you would like to interact with the smart contract from Hardhat console or MetaMask wallet, you need to run a stand-alone local blockchain and deploy the smart contract to it.
Note on mnemonic and default accounts
Thedefault accounts with Hardhat are generated with this mnemonic:
"test test test test test test test test test test test junk"
If you want to use your mnemonic, add it in Hardhat configuration:
hardhat:{accounts:{mnemonic:"your mnemonic"}},
See more about hardhat configuration at:https://hardhat.org/config/
Stand-alone local blockchain testnet serves JSON PRC athttp://127.0.0.1:8545/. If you would like to use the Ethereum mainnet, public testnet Sepolia, sidechain like Polygon/BSC or L2 like Optimism/Arbitrum, you may need a RPC provider likeAlchemy.
For example, if you would like to use Sepolia, you can add this network in config(viahardhat docs):
module.exports = { networks: { sepolia: { url: "https://eth-sepolia.g.alchemy.com/v2/<apikey>", accounts: [privateKey1, privateKey2, ...] } },};
Change the and to your own.
Step 6: Interact with the deployed smart contact from Hardhat console
Hardhat console is an interactive Javascript console.
To open Hardhat console connecting to localhost blockchain athttp://127.0.0.1:8545/ , run:
yarn hardhat console--network localhost
In Hardhat console, you can interact with smart contract usingEthers.js
. What we use here is the plugin version:hardhat-ethers.
constaddress='0x5FbDB2315678afecb367f032d93F642f64180aa3';constcontract=awaitethers.getContractAt("Lock",address);//call withdrawawaitcontract.withdraw()
Response is the transaction receipt:
{ hash: '0x3a0269dc290e47e4001b9a8fd1c0e7a93f4443f6673c62f21d1960e3894fcca2', type: 2, accessList: [], blockHash: '0x24b49f383d7cd24704595ece03abeb9e848b3b0f15fb1484db06c717c73185f3', blockNumber: 2, transactionIndex: 0, confirmations: 1, from: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', gasPrice: BigNumber { value: "768002200" }, maxPriorityFeePerGas: BigNumber { value: "0" }, maxFeePerGas: BigNumber { value: "972002784" }, gasLimit: BigNumber { value: "36493" }, to: '0x5FbDB2315678afecb367f032d93F642f64180aa3', value: BigNumber { value: "0" }, nonce: 1, data: '0x3ccfd60b', r: '0x0ab5399e355a4795535827edb08c55efc63a412176b1fd3977b02923607c4b57', s: '0x528706dd1b049ec0ad6ff85d3746e24a4dfbef4447e2b572b0d053ec0be8f28c', v: 1, creates: null, chainId: 31337, wait: [Function (anonymous)]}
Note on console.log
You can modify the contract and useconsole.log
.
// Uncomment this line to use console.logimport"hardhat/console.sol";functionwithdraw()public{// Uncomment this line, and the import of "hardhat/console.sol", to print a log in your terminalconsole.log("Unlock time is %o and block timestamp is %o",unlockTime,block.timestamp);...}
Run the previous steps again. You may found that there is a console log in the terminal:
console.log: Unlock time is '1679121200' and block timestamp is '1679121264'
Last Step
At the end of this section, let's terminate the localhost blockchain.
I usually clean up the project which means to delete cache files and compiling artifacts by running:
yarn hardhat clean
You can also delete thenode_modules
directory as you can install dependencies by runningyarn
again.
To read the Contract / Unit Test / Deploy files is a good start to understand solidity and hardhat.
.├── contracts│ └── Lock.sol├── package.json├── scripts│ └── deploy.ts├── test│ └── Lock.ts
If needed, you can delete the sample contract as well as test and deploy scripts in the corresponding directories. You now have a blank hardhat project to start with.
This is Part 1 of a 3-section hardhat tutorial "A Concise Hardhat Tutorial". How to write ERC20 and ERC721 smart contract will be covered in Part 2 and Part 3.
Tutorial List:
1. A Concise Hardhat Tutorial(3 parts)
https://dev.to/yakult/a-concise-hardhat-tutorial-part-1-7eo
2. Understanding Blockchain withEthers.js
(5 parts)
https://dev.to/yakult/01-understanding-blockchain-with-ethersjs-4-tasks-of-basics-and-transfer-5d17
3. Tutorial : build your first DAPP with Remix and Etherscan (7 Tasks)
https://dev.to/yakult/tutorial-build-your-first-dapp-with-remix-and-etherscan-52kf
4. Tutorial: build DApp with Hardhat, React and Ethers.js (6 Tasks)
https://dev.to/yakult/a-tutorial-build-dapp-with-hardhat-react-and-ethersjs-1gmi
5. Tutorial: build DAPP with Web3-React and SWR
https://dev.to/yakult/tutorial-build-dapp-with-web3-react-and-swr-1fb0
6. Tutorial: write upgradeable smart contract (proxy) using OpenZeppelin(7 Tasks)
7. Tutorial: Build a NFT marketplace DApp like Opensea(5 Tasks)
https://dev.to/yakult/tutorial-build-a-nft-marketplace-dapp-like-opensea-3ng9
If you find this tutorial helpful, follow me at Twitter@fjun99
Top comments(2)

I'm having a problem when uncommenting the code forconsole.log
. I can't see the log on my terminal. I have tried some solutions like downgrading VSCode Solidity extension, uninstalling this, and installing Solidity+Hardhat extension, etc ... (all kinds of solutions that mentioned hereethereum.stackexchange.com/questio...). Nevertheless, I'm not seeing theconsole.log
when interacting with the smart contract with hardhat console. Maybe, you have any idea on how to solve it? Thanks in advance.
For further actions, you may consider blocking this person and/orreporting abuse