Skip to main content

Someone wanted to learn this too, so Grasp built them a personal learning path.

You can keep exploring this one or create your own

Setting Up Your Hardhat Project

Welcome back! In our last lesson, you successfully set up a complete local development environment and initialized a basic Hardhat project. You learned about the standard project structure and verified your setup by compiling and testing the sample contract.

Today, we will move from a generic boilerplate to a project configured for our specific needs. The learning outcome for this lesson is to initialize and configure a Hardhat project for compiling and deploying smart contracts. We'll focus on the hardhat.config.js file, which acts as the control center for your entire project. By the end of this lesson, your project will be configured with the correct compiler version and securely connected to the Sepolia testnet, ready for future deployments.

Your experience with backend development will be helpful here. The process of modifying hardhat.config.js is similar to how you would configure a tsconfig.json for a TypeScript project or manage application settings and database connections in other backend frameworks.

Part 1: Anatomy of hardhat.config.js

When you created the sample project, Hardhat generated a hardhat.config.js file. This file is the most important piece of your Hardhat setup. It's where you define how the entire environment behaves.

Let's start by understanding its structure and key components.

Configuration | Ethereum development environment for ...

The official Hardhat documentation provides the best overview of the configuration file. This will give you a solid mental model of what's possible before we start making changes.

Read the introduction and the 'Available config options' section. Don't worry about understanding every single option right now; focus on recognizing the main properties like solidity, networks, and paths.

As you saw, the file exports a configuration object. The two most critical properties for us right now are:

  • solidity: To specify which version of the Solidity compiler to use.
  • networks: To define connections to different Ethereum networks, like your local machine, testnets (Sepolia), or the mainnet.

Part 2: Configuring the Solidity Compiler

Your hardhat.config.js file already has a solidity property.

// hardhat.config.js
module.exports = {
  solidity: "0.8.24", // or a similar version
  // ...
};

This line tells Hardhat to use version 0.8.24 of the Solidity compiler. It's crucial to lock this version because Solidity is a rapidly evolving language, and new versions can introduce breaking changes. Using a specific version ensures that your contract compiles today just as it will tomorrow. For our course, we will stick to a recent, stable version. Let's ensure your config specifies version 0.8.24.

You can also configure more advanced compiler settings, like the optimizer, which can reduce gas costs upon deployment. We will explore these advanced options later in the course.

Configuration | Ethereum development environment for ...

For a more detailed look at the solidity configuration options, refer to the Hardhat documentation once more.

Briefly review the 'Solidity configuration' section to see how you can specify a single version or even multiple compilers for more complex projects. You don't need to memorize this, just be aware of the possibilities.

Part 3: Securely Managing Secrets for Network Deployment

To deploy a contract to a public network like Sepolia, your project needs two pieces of sensitive information:

  1. An RPC URL from a node provider (like Alchemy) to communicate with the network.
  2. Your Private Key to sign and authorize the deployment transaction from your wallet.

Hardcoding this information directly into hardhat.config.js is a critical security vulnerability. If you accidentally commit this file to a public repository (like GitHub), your funds could be stolen instantly.

As a backend developer, you know that the standard solution is to use environment variables. We will do the same here by using a .env file to store our secrets and the dotenv package to load them into our Hardhat configuration.

The following video from Alchemy provides a perfect, step-by-step walkthrough of this entire process.

How to Write, Compile & Deploy a Smart Contract using Hardhat - Alchemy University

This video will guide you through installing dotenv, creating a .env file, and configuring your hardhat.config.js to securely access your RPC URL and private key.

Watch from 04:31 to 10:09. Follow along with the presenter to perform these steps in your own project.

Let's break down the steps from the video to make them crystal clear.

Step 1: Install dotenv
In your project's root directory, run:

npm install dotenv

Step 2: Create .env and add it to .gitignore

  1. Create a new file in your project root named .env.
  2. Crucially, open your .gitignore file and add a new line with .env. This tells Git to never track this file, preventing you from accidentally publishing your secrets.

Step 3: Get Your Secrets

  1. RPC URL: Log in to your Alchemy account (which you set up in Module 1). Navigate to your app, click "View Key", and copy the HTTPS URL for the Sepolia network.
  2. Private Key: Open your MetaMask wallet, ensure you are on an account you use for testing (NOT your main account with real funds). Click the three dots, go to "Account details", and then "Show private key". Copy this key. Never share this key with anyone.

Step 4: Populate Your .env File
Add your copied keys to the .env file. Your file should look like this:

SEPOLIA_RPC_URL="https://eth-sepolia.g.alchemy.com/v2/YOUR_API_KEY"
PRIVATE_KEY="YOUR_METAMASK_PRIVATE_KEY"

Step 5: Update hardhat.config.js
Now, modify your hardhat.config.js to load and use these variables. Your final config file should look like this:

require("@nomicfoundation/hardhat-toolbox");
require("dotenv").config(); // Loads environment variables from .env

/** @type import('hardhat/config').HardhatUserConfig */
module.exports = {
  solidity: "0.8.24",
  networks: {
    sepolia: {
      url: process.env.SEPOLIA_RPC_URL || "",
      accounts:
        process.env.PRIVATE_KEY !== undefined ? [process.env.PRIVATE_KEY] : [],
    },
  },
};

Let's analyze the changes:

  • require("dotenv").config();: This line, placed at the top, reads your .env file and makes the variables available under process.env.
  • networks: { ... }: We've added the networks object.
  • sepolia: { ... }: Inside networks, we define our connection to the Sepolia testnet.
    • url: It reads the RPC URL from your environment variables.
    • accounts: It expects an array of private keys. We create an array containing the single private key from your environment variables. The checks for undefined are a good practice to prevent errors if the variables aren't set.

Part 4: Verifying Your Configuration

Your project is now fully configured. The final step is to verify that everything works. The compile command will read your configuration file, including the Solidity version you specified.

In your terminal, run:

npx hardhat compile

If the command completes successfully with a message like "Compiled 1 Solidity file successfully", your configuration is correct! Hardhat was able to read the solidity version from your config file and compile the sample Lock.sol contract.

Test your understanding!

A colleague asks you to add support for deploying to another testnet, "Amoy" (a Polygon testnet). They give you the Amoy RPC URL. Based on what you've learned, what are the two files you would need to modify to add and configure this new network?

Show answer
  1. .env: You would add a new line for the Amoy RPC URL (e.g., AMOY_RPC_URL=...). You would use the same PRIVATE_KEY.
  2. hardhat.config.js: You would add a new entry for amoy inside the networks object, similar to the sepolia configuration, which reads the new RPC URL from process.env.

Conclusion

Excellent work! You've taken a significant step in professionalizing your development workflow. You now have a Hardhat project that is not only ready for local development but is also securely configured to interact with a live public testnet.

Key Takeaways:

  • The hardhat.config.js file is the central control panel for your Ethereum project.
  • You must explicitly define the solidity compiler version to ensure consistent, predictable builds.
  • The networks object is where you configure connections to various Ethereum networks for testing and deployment.
  • Never hardcode secrets like private keys or API keys. Always use a .env file (added to .gitignore) and the dotenv package to manage them securely.

Preview of the Next Lesson:
With our environment fully configured, it's time to start building. In the next lesson, we will write a basic smart contract using the correct Solidity pragma and structure. You will write your very first lines of Solidity code, learning about the basic building blocks of a smart contract.

Can't find a good explanation? Sign up and we'll make it for you

Sign up