Search
⌃K

How to Use HardHat

HardHat

Hardhat is a development environment for Ethereum and EVM compatible software. It consists of different components for editing, compiling, debugging and deploying smart contracts and dApps, all of which work together to create a complete development environment.
Everything discussed in this tutorial can be found in the HardHat Tutorial repository.

Install HardHat

Hardhat is used through a local installation in your project. Make sure you have npm/node (v8.9.4 LTS or later) installed on your computer. Steps to install hardhat:
  1. 1.
    Run npm init --yes
  2. 2.
    Run npm install --save-dev hardhat
  3. 3.
    Run npm install --save-dev chai @nomiclabs/hardhat-waffle

Initialize Project

After you install HardHat in the project, you can run npx hardhat to initialize the project
$ npx hardhat
888 888 888 888 888
888 888 888 888 888
888 888 888 888 888
8888888888 8888b. 888d888 .d88888 88888b. 8888b. 888888
888 888 "88b 888P" d88" 888 888 "88b "88b 888
888 888 .d888888 888 888 888 888 888 .d888888 888
888 888 888 888 888 Y88b 888 888 888 888 888 Y88b.
888 888 "Y888888 888 "Y88888 888 888 "Y888888 "Y888
​
👷 Welcome to Hardhat v2.10.1 👷‍
​
? What do you want to do? …
❯ Create a JavaScript project
Create a TypeScript project
Create an empty hardhat.config.js
Quit
Once this project is initialized, you will find the following project structure:
  • Contracts, directory to put solidity smart contracts
  • Scripts, directory to put javascript/typescript scripts
  • Test, directory to put test files
  • hardhat.config.js, configuration file

Config HardHat for Core TestNet

/**
* @type import('hardhat/config').HardhatUserConfig
*/
​
require('@nomiclabs/hardhat-ethers');
require("@nomiclabs/hardhat-waffle");
​
const { PrivateKey } = require('./secret.json');
​
module.exports = {
defaultNetwork: 'testnet',
networks: {
hardhat: {
},
testnet: {
url: 'https://rpc.test.btcs.network',
accounts: [PrivateKey],
chainId: 1115,
}
},
solidity: {
compilers: [
{
version: '0.8.9',
settings: {
optimizer: {
enabled: true,
runs: 200,
},
},
},
],
},
paths: {
sources: './contracts',
cache: './cache',
artifacts: './artifacts',
},
mocha: {
timeout: 20000,
},
};
Note that we need to pass in private keys/mnemonic for Provider. You can create a secret.json to store them. Do not forget to add this file in the .gitignore of your project so that you won't accidentally check in to a public repository. And make sure you keep this file in an absolutely safe place!

Write Smart Contract

For simplicity, we use the 1_Storage.sol file from Remix in this tutorial.
// SPDX-License-Identifier: GPL-3.0
​
pragma solidity >=0.7.0 <0.9.0;
​
/**
* @title Storage
* @dev Store & retrieve value in a variable
*/
contract Storage {
​
uint256 number;
​
/**
* @dev Store value in variable
* @param num value to store
*/
function store(uint256 num) public {
number = num;
}
​
/**
* @dev Return value
* @return value of 'number'
*/
function retrieve() public view returns (uint256){
return number;
}
}

Compile Contract

Run npx hardhat compile to compile the contract.

Test Contract

Create a storage-test.js in Test folder with following code
const { expect } = require("chai")
const { ethers } = require("hardhat")
​
describe("Storage", function () {
let storage;
​
beforeEach(async function(){
Storage = await ethers.getContractFactory("Storage");
[operator] = await ethers.getSigners();
storage = await Storage.connect(operator).deploy();
await storage.deployed()
expect(await storage.retrieve()).to.equal(0n);
})
describe("Test store function", function(){
it("should work properly", async function(){
let tx = await storage.store(100);
await tx.wait();
expect(await storage.retrieve()).to.equal(100n);
})
it("should throw", async function(){
await expect(
storage.store(-1)
).to.be.throws
})
})
})
Then run npx hardhat test --network hardhat to test on the built in hardhat network.
$ npx hardhat test --network hardhat
​
​
Storage
Test store function
✔ should work properly
✔ should throw
​
​
2 passing (1s)

Deploy and Call Contract

It is easy to use the framework built in ethers.js to deploy and call contract. Create a deploy-and-call.js in Scripts folder with following code
// We require the Hardhat Runtime Environment explicitly here. This is optional
// but useful for running the script in a standalone fashion through `node <script>`.
//
// You can also run a script with `npx hardhat run <script>`. If you do that, Hardhat
// will compile your contracts, add the Hardhat Runtime Environment's members to the
// global scope, and execute the script.
const hre = require("hardhat");
​
async function main() {
const Storage = await hre.ethers.getContractFactory("Storage");
const storage = await Storage.deploy();
​
await storage.deployed();
console.log("Storage contract deployed to:", storage.address);
​
console.log("call retrieve():", await storage.retrieve())
​
console.log("call store(), set value to 100")
const tx = await storage.store(100)
await tx.wait()
console.log("call retrieve() again:", await storage.retrieve())
}
​
// We recommend this pattern to be able to use async/await everywhere
// and properly handle errors.
main().catch((error) => {
console.error(error);
process.exitCode = 1;
});
Run npx hardhat run scripts/deploy-and-call.js
$ npx hardhat run scripts/call.js
Storage contract deployed to: 0x65e2F3E4287C0563fBB066134A380e90a48d2D99
call retrieve(): BigNumber { value: "0" }
call store(), set value to 100
call retrieve() again: BigNumber { value: "100" }
You can visit Core Scan and search for the address to verify that the contract was successfully deployed and called.

HardHat Documentation

For detailed instructions on using HardHat and plugins such as ethers.js, please visit HardHat's official website.

References