How to Develop Smart Contracts with Hardhat?

Hardhat is a development environment for smart contracts compatible with the Ethereum Virtual Machine (EVM).

It integrates the necessary tools to manage the complete lifecycle of smart contracts: coding, compiling, debugging, and deploying on the blockchain.

The use of Hardhat centers around the Hardhat Runner component, responsible for executing tasks and allowing plugin integration. Through plugins, it is possible to extend the basic functionalities of Hardhat.

Contracts are natively programmed in Solidity, although there is a plugin available to use Vyper.

There are other alternatives to Hardhat that also allow the development of smart contracts, among which the following stand out:

  • Truffle: the original development environment on Ethereum with a large developer base, almost inextricably linked to Ganache as a local implementation of the Ethereum network. Without delving into comparisons, its major disadvantage currently is that since the end of 2023, it is no longer maintained by the community and is considered an obsolete project. As an alternative for developers accustomed to Truffle, Hardhat is often cited since both largely share the same development philosophy.
  • Foundry: a more modern development environment than Hardhat. Focused on using Solidity as the native language for programming tests, it offers performance improvements in projects that require intensive test suites, though generally at the cost of increased complexity. Its developer base is less extensive than Hardhat’s, so sometimes it is more challenging to find community support.

Complete details about the use of Hardhat and its toolset can be found on the official Hardhat project page.

Installing Hardhat and Deploying a Network Node

The first step to start using Hardhat is to install the basic packages and initialize the project. You can choose between JavaScript or TypeScript as the language for programming the tests and scripts for your project:

yarn add --dev hardhat

yarn hardhat init

When invoking any task, an in memory instance of the Hardhat Network component is created, an ephemeral local Ethereum node tied to the duration of the task, which accepts JSON-RPC and WebSocket requests. By default, 20 Ethereum addresses are created with 10,000 ETH each to allow interactions. The node is configured to mine each transaction into a new block without any delay.

Another option is to run the Hardhat Network as a long running independent process to allow connection from external DApps and wallets: 

yarn hardhat node

The node is exposed at the following URLs:

  • http://127.0.0.1:8545
  • ws://127.0.0.1:8545

To execute Hardhat tasks on that node, you need to specify it explicitly using the –network localhost modifier.

Configuring Hardhat

During the Hardhat project initialization process, a configuration file, “hardhat.config.js“,  will have been created if we chose JavaScript as the language.

It is common to start with a clean file and add our particular configurations.

The general recommendation is to install the “hardhat-toolbox” plugin (along with its dependencies if using yarn as the package manager or an older version of npm) to integrate Hardhat’s basic functions using the “ethers.js” library and add it as a dependency in the “hardhat.config.js” file:

yarn add --dev  @nomicfoundation/hardhat-toolbox
                @nomicfoundation/hardhat-ignition-ethers
                @nomicfoundation/hardhat-ignition
                @nomicfoundation/ignition-core
                @nomicfoundation/hardhat-network-helpers
                @nomicfoundation/hardhat-chai-matchers
                @nomicfoundation/hardhat-ethers
                @nomicfoundation/hardhat-verify
                ethers @nomiclabs/hardhat-etherscan
                chai@4.4.1 hardhat-gas-reporter solidity-coverage
                @typechain/hardhat typechain @typechain/ethers-v6
                @types/mocha ts-node typescript

This way, a basic configuration file could be as follows:

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

module.exports = {    
    solidity: {
      version: "0.8.23"
    },       
    paths: {
      sources: "./contracts",
      tests: "./test",
      cache: "./cache",
      artifacts: "./artifacts"
    }
}

All dependencies loaded in the configuration file are automatically injected into the Hardhat Runtime Environment, an object that contains all the functionality that Hardhat exposes when executing a task, a test, or a script. This significantly simplifies the programming of tests and scripts by implicitly including many of the necessary utilities.

In the example, the default paths used by Hardhat to locate the different types of files associated with smart contracts have been explicitly defined.

For more details about the “hardhat.config.js” file, you can refer to the Hardhat configuration reference.

How to compile smart contracts with Hardhat?

It is highly recommended to explicitly define the “solc” compiler version to be used in the “hardhat.config.js” file to ensure consistent compilation results.

Optionally, other Hardhat compilation parameters specific to the “solc” compiler can be defined within the “settings” section. These are detailed in the JSON description file of the compiler’s input.

While it is generally necessary to enable compiler optimizations for deploying contracts, it is recommended to disable them for test execution to allow full stack trace recording for debugging contracts.

The smart contracts should be programmed in advance using your preferred editor within the folder defined for the “sources” in the “hardhat.config.js” file (the “contracts” directory by default).

The basic compilation tasks are:

  • yarn hardhat compile: compiles only the source files that have changed since the last compilation and places the results in the folder defined for “artifacts” in the “hardhat.config.js” file (the “artifacts” directory by default).
  • yarn hardhat compile –force: forces the recompilation of files even if they have not changed since the last compilation.
  • yarn hardhat clean: clears the cache and results of the previous compilation.

Next steps: programming tests

Hardhat is an integrated development environment for smart contracts, presenting itself as an alternative to other options like Truffle or Foundry.

This article has covered the initial steps for developing smart contracts with Hardhat: environment installation, basic configuration, and contract compilation.

In upcoming articles, other parts of the process will be addressed, such as writing test suites for the contracts.


What is your preferred tool for programming smart contracts? I encourage you to share your experiences by leaving comments. If you need to develop smart contracts, contact me: I can handle the complete lifecycle management. Thank you very much!