Skip to content

DApp Development: Hardhat

Ananthan edited this page May 25, 2024 · 5 revisions

Introduction to Hardhat

Before integrating Hardhat with our project, let us understand the framework itself.

Now, HardHat is the framework that can be used to compile, test, and deploy the Solidity smart contract to the Ethereum ecosystem. It is a complete smart contract life cycle management framework.

The community's initial development framework was Truffle (managed by ConsenSys). Lately, however, after the sunset of the Truffle suite, Hardhat has been gaining favour in the community due to its ease of use and testing features.

We are using Hardhat for the same reasons.

Installation

Hardhat needs to be installed locally inside a Node project. So, let's create a new directory and switch to it.

mkdir hardhat && cd hardhat

Next, we initialize a Node project. To do so execute the following command.

npm init

Now we can install Hardhat, using npm.

npm i -D hardhat

That's it for installing Hardhat. Next, we will see how to set up a basic Hardhat project.

Working with Hardhat

Now that we know how to install the Hardhat framework let's start using it. First, we need to initialize a Hardhat project. To do so, execute the following command.

npx hardhat init

Hardhat has some prebuilt templates for us to work with, but we will build the project from scratch. So here, select 'Create an empty hardhat.config' option.

Before starting with the Hardhat project setup, let's install a plugin provided by Hardhat that will help us compile and deploy. Execute the following command to install it.

npm install -D @nomicfoundation/hardhat-toolbox

Let's enable this plugin by importing it into the 'hardhat.config.js' file.

require("@nomicfoundation/hardhat-toolbox");

/** @type import('hardhat/config').HardhatUserConfig */
module.exports = {
  solidity: "0.8.20",
};

Note: Make sure the Solidity version specified in the 'hardhat.config.js' is same as that of the smart contract. If it's not, then change it to the same version.

In the 'hardhat.config.js' file, we can also specify the version of the Solidity language that we will code in. Let us choose the version from our contract, 0.8.20.

Create a new directory named 'contracts' to store our Solidity smart contracts.

mkdir contracts

Let's copy our certificate issuing contract named 'Cert.sol' inside the folder.

// SPDX-License-Identifier: MIT
pragma solidity 0.8.20;

contract Cert {
    
  address admin;
  
  constructor() {
    admin = msg.sender;    
  }
  
  modifier onlyAdmin {
      require(msg.sender == admin, "Access Denied");
      _;
  }
  
  struct Certificate {
      string name;
      string course;
      string grade;
      string date;
  }
  
  mapping (uint256 => Certificate) public Certificates;
  
  function issue (
      uint256 _id,
      string memory _name,
      string memory _course,
      string memory _grade,
      string memory _date) public onlyAdmin {
          Certificates[_id] = Certificate(_name, _course, _grade, _date);
      }
}

Next, let's compile the contract.

npx hardhat compile

Now that the code is compiled and error-free, let us go ahead and deploy it to the blockchain ecosystem. Hardhat also has a node simulation with which we can interact. Open a new terminal and execute the following.

npx hardhat node

This will spring up a simulated node with 20 prefunded accounts and corresponding private keys. Next, we will write a script to deploy our contract to the node. Before doing so, let's configure our hardhat project to connect to the newly run node when we perform a deployment operation.

Open the 'hardhat.config.js' file.

Now the configuration can be specified using the network object.

{
    localhost: {
      url: "http://127.0.0.1:8545"
    },
    hardhat: {
      
    }
}

localhost connects to any client running on the specified url (useful when running geth or other simulations). hardhat connects to the hardhat node. We also specify which network to use by default whenever we want to start a connection with the node from Hardhat.

defaultNetwork: "localhost",

The full code is given below.

require("@nomicfoundation/hardhat-toolbox");

/** @type import('hardhat/config').HardhatUserConfig */
module.exports = {
  defaultNetwork: "localhost",
  networks: {
    localhost: {
      url: "http://127.0.0.1:8545"
    },
    hardhat: {
      // See its defaults
    }
  },
  solidity: "0.8.20",
};

Now, to deploy the contract to the node, create a folder named 'ignition/modules' inside the main directory and a file named 'Cert.js'.

First, we will import buildModule from the @nomicfoundation/hardhat-ignition/modules.

const { buildModule } = require("@nomicfoundation/hardhat-ignition/modules");

Hardhat Ignition is a declarative system for deploying smart contracts on Ethereum. It enables you to define smart contract instances and any operations you want to run on them. By taking over the deployment and execution, Hardhat Ignition lets you focus on your project instead of getting caught up in the deployment details.

Now, we need to create a module to deploy our smart contract. The first aspect is that modules are created by calling the buildModule function, which requires a module ID and a callback function. The callback function is where the module definition happens. The m parameter being passed into the callback is an instance of a ModuleBuilder, which is an object with methods to define and configure your smart contract instances. Also, we want Hardhat to access our module, so we have to export it.

module.exports = buildModule("CertModule", (m) => {
    const cert = m.contract("Cert");
    return { cert };
});

Now let's deploy the contract. This will deploy the contract to the specified defaultNetwork.

npx hardhat ignition deploy ignition/modules/Cert.js

Or if you want to deploy to any other network defined in your 'hardhat.config.js', use --network.

npx hardhat ignition deploy ignition/modules/Cert.js --network localhost

If everything is good, what we get in response is something like this.

Hardhat Ignition

Deploying [ CertModule ]

Batch #1

  Executed CertModule#Cert

[ CertModule ] successfully deployed 🚀

Deployed Addresses

CertModule#Cert - 0x5FbDB2315678afecb367f032d93F642f64180aa3

For further communication with the smart contract, we can use the abi from the 'CertModule#Cert.json' file inside the 'ignition/deployments/chain-ID/artifacts' folder. The contract address is displayed on the console. If we want, we can use the 'deployed_addresses.json' file inside the 'ignition/deployments/chain-ID' folder.



Clone this wiki locally