Skip to content

Latest commit

 

History

History
 
 

07-hardhat

中文 / English

Hardhat

Hardhat is a development environment for ethereum application to compile, deploy, test and debug.

It could help developer to manage , automate build smart contracts and some inherently repetitive tasks in dApps.The core of hardhat is compiling, running and testing smart contracts. It has a build-in Hardhat test network, which is designed for local ethereum network.Its main functions includes Solidity debugging, tracking invoked stack, console.log() and explicit error tips in failed transaction.

Hardhat Runner is a CLI interacted with Hardhat and a extensible task runner. It was designed by the concept of tasks and plugins. When you run Hardhat by CLI, you will run a task, such as npx hardhat compile. It will run the build-in compiling task. The task will trigger other tasks, which can give the complicated work flow. Users and plugins could cover all tasks now to customize and extend the work flow.

Preparation

Before learning hardhat, you need to understand some Knowledge points as follows:

  • dotenv place private key in .env files, which could prevent exposure on cloud server, formatted with "PRIVATE_KEY=xxxx". It will be read by code automaticily. Refer to dotenv
  • The main problem npx want to resolve is to invoke modules installed internally in the project. Refer to npx Tutorials
  • Compared to web3.js, the interfaces of ethers.js and ethereum network library is easily used(note the interface difference between v5 and v4) ethers.js v5 document
  • mocha.js test framework is used to write the solution for contracts Interaction. mochajs document
  • chai.js assert framework is used to help to write testing scripts, refer to ethereum-waffle chai document
  • infura is a node internet service provider to connect to block chain, which allow some free use amounts. It is enough to develop and debug. infura offical site

Project structure and configuration hardhat

cd    07-hardhat                // move to folder
npm install --save-dev hardhat  // install hardhat
npx hardhat                     // initialize hardhat

Finished in inputing npx hardhat, it will show in the terminal:

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.21.0 👷‍

? What do you want to do? … 
❯ Create a JavaScript project
  Create a TypeScript project
  Create a TypeScript project (with Viem)
  Create an empty hardhat.config.js
  Quit

We select 'Create a JavaScript project' options to initialize a basic project, click enter directly in the next 2 steps.

Project stucture

A standard project build in hardhat is as follow:

contracts/
scripts/
test/
hardhat.config.js
  • palce fileds write in solidity in contracts
  • palce scripts files such as deploying contracts in scripts
  • palce testing scripts named with contractName.test.js in test
  • hardhat.config.js is config file of hardhat

Configuration of hardhat

hardhat.config.js config file example

require('@nomiclabs/hardhat-waffle');
require('dotenv').config();

module.exports = {
  networks: {
    // hardhat build-in testing network (optional)
    hardhat: {
      // a fixed gasPrice could be set, it will be useful when testing gas consumption
      gasPrice: 1000000000,
    },
    // you could config arbitrary network
    // goerli testing network
    sepolia: {
      // place INFURA_ID to yours
      // url: 'https://sepolia.infura.io/v3/{INFURA_ID}',
      url: 'https://sepolia.infura.io/v3/' + process.env.INFURA_ID, //<---- 在.env文件中配置自己的INFURA_ID

      //  place multiple privateKeyX to yours
      accounts: [process.env.PRIVATE_KEY, ...]
    }
  },
  solidity: {
    version: "0.8.0", // version of compiling contract, required
    settings: { // setting of compile, optional
      optimizer: {  // setting of optimizing
        enabled: true,
        runs: 200
      }
    }
  },

  // config project paths, any path could be specified, The following is a common template
  // files in sources, test, scripts will be executed one by one
  paths: {
    sources: "./contracts", // directory of contracts
    tests: "./test",  // directory of test files
    cache: "./cache", // cache directory, generated by hardhat
    artifacts: "./artifacts" // directory of compiling result, generated by hardhat
  },
  // setting of testing framework
  mocha: {
    timeout: 20000  // max waiting time of running unit test
  }
}

Build-in hardhat network

hardhat has a special, secure and build-in testing network, named hardhat, you don't need a special configuration for it. The network will follow the mechanism in real block chain network, and it will generate 10 test accounts for you (just like truffle).

Install dependencies

  1. install nodejs (ignore)

    Node version v20.11.0

  2. install project dependencies:

npm install


or use yarn to intall (yarn installed firstly)

```sh
yarn
  1. config private key and network:

    create .env file in the directory of project, add private key and infura node to the file

    PRIVATE_KEY = xxxxxxxxxxxxxxxx; // place your private key
    INFURA_ID = yyyyyyyy; // place infura node
     APIKEY=zzzzzz; //replace etherscan apikey,will introduce below

Usage

useage of hardhat

Compile

Run the command, hardhat will compile all contracts file in directory of sources, the default path is ./contracts

npx hardhat compile

Test

Run the command, hardhat will compile all test files in directory of tests, the default path is ./test

npx hardhat test
#test network no need assign --network <network name>

you could also specify some test files to run it

npx hardhat test ./test/Greeter.test.js

Run

Run the specified script. If you are not, it will run on hardhat's build-in network by default(Hardhat Network).

npx hardhat run ./scripts/deploy.js

Run the specified network, such as the contract deployed on goerli test network(make sure that the wallet could pay the gas)

npx hardhat run ./scripts/deploy.js --network sepolia


#Please remember the "deploy address" returned after running here, which will be used by verify in Sepolia network verification below

Verify

Verify the smart contract, here is an example of goerli.

Add the following configuration to hardhat.config.js:

  etherscan: {
   apiKey: "<etherscan的api key>", //Use process.env.APIKEY Get Variables
 }

https://etherscan.io/myapikey Create an account on the official website. After logging in, go to My Account (the actual name of the account you created) ->API Key

Ensure configuration in hardhat.config.js

Run script:

npx hardhat verify --contract "contracts/SimpleToken.sol:SimpleToken" --constructor-args ./arguments_SimpleToken.js  --network sepolia <contract address>

##The data in arguments SimpleToken.js are the parameters set during the construction of the SimpleToken contract when running the deploy. js script on line 207

Task

hardhat preset some task itself, such as compiling contract, running testing scripts. Those are build-in hardhat tasks.

Actually you could also customize some tasks, such as printing status of the current network's account

// hardhat.config.js
...

task('accounts', 'Prints the list of accounts', async () => {
  const accounts = await ethers.getSigners();

  for (const account of accounts) {
    console.log(account.address);
  }
});

...

run task

npx hardhat accounts

terminal will print 10 addresses of testing account

0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266
...

Console

The console mode of hardhat could interact with chain in real-time, where the hardhat build-in network is started by default.

npx hardhat console

we can directly use build-in ethers and web3 library, no need to import.

// hardhat console mode:
// directly use async/await
> await ethers.provider.getBlockNumber()  // 0

console.log debug

hardhat provide the console.log() method to print logs, debug and test when running the contract . Only valid in hardhat build-int network

you can use is by importing hardhat/console.sol in your contract

import "hardhat/console.sol";

contract Greeter {
  ...

  function setGreeting(string memory _greeting) public {
    console.log("Changing greeting from '%s' to '%s'", greeting, _greeting);
    greeting = _greeting;
  }

}

When running test scripts, you can check logs:

Changing greeting from 'Hello, world!' to 'hello Dapp-Learning!'

Steps

Compile and test

  1. compile the contract

    npx hardhat compile
  2. batch run test scripts

    npx hardhat test
  3. deploy to test network

    npx hardhat run scripts/deploy.js --network <network-name>

    network-name should be replaced with your networks, sepolia is a choice which exists in the config file.

  4. Verify smart contract

     npx hardhat verify --contract "contracts/SimpleToken.sol:SimpleToken" --constructor-args ./arguments_SimpleToken.js  --network <network-name>  <contract-address>

    network-name : the name of the network you specify, here you can replace it with sepolia, which corresponds to the network name in the configuration file.

    contract-address : The address of the contract deployed in the previous step.

Reference