Robert's Homepage

How to Setup Hardhat Network Default Accounts

#ethereum #hardhat #development

NOTE: This tutorial is for hardhat version ^2.4.1

By default, Hardhat has a local network called the hardhat network with chainId 31337 that runs on localhost:8545. This is network that developers create by executing:

npx hardhat node 

You can configure any JSON-RPC Network (i.e. Rinkeby, Kovan, Main Net, et cetera) via the hardhat.config.js , however, to keep things simple we will just look at the hardhat network in this tutorial.

Below is an example hardhat.config.js .

require("@nomiclabs/hardhat-ethers");
require("@nomiclabs/hardhat-waffle");

const HH_NETWORK_ID = 31337

// -- Snipped for brevity --

module.exports = {
	solidity: "0.8.4",
	networks: {
		hardhat: {
			accounts: {
				path: "m/44'/60'/0'/0",
				// NOTE: This field is for your 12 word mnemonic
				mnemonic: "your mnemonic phrase goes here",
				initialIndex: 0,
				count: 5,
				passphrase: "",
				// The default accountsBalance is 1000 ETH 
				// NOTE: this field is in Wei
				accountsBalance: "100000000000000000000"
			}
		}
	},
};

Inside module.exports the network property is defined which contains each network configuration. Here the hardhat network is defined and using the accounts property you can set the desired HD wallet and account balances Hardhat should seed the network with.

As an alternative, you can provide an array of private keys and balances like the snippet below, however, using an HD wallet provides better developer ergonomics as you can directly import this into your wallet development tool (i.e. Metamask, Coinbase Wallet, et cetera).

accounts: [
	{
      address: "0xdeadbeef", 
      privateKey: "0xfeebdaed",
      balance: "10000000000000000000000"
	}, 
]
❗️ WARN

Be sure to IGNORE or REMOVE these values from your version control software.

An easy way to do this is by copying/pasting these values into a separate file in the project root called hardhatAccounts.json (for example), and explicitly ignoring this via .gitignore then requiring it at the top of the hardhat.config.js file.

For example:

// hardhatAccounts.json
{
	"accounts": [
		{
			"address": "0xdeadbeef", 
			"privateKey": "0xfeebdaed",
			"balance": "10000000000000000000000"
		}, 
	]
}
// hardhat.config.js
const hardhatAccounts = require("./hardhatAccounts")

// snipped for brevity 

module.exports = {
  // snipept for brevity 
  hardhat: {
	accounts: hardhatAccounts.accounts
  }
}

Make sure that if you follow this technique, that the data in the .json file is actually valid JSON (i.e. uses quotations for the fields). This can be a common gotcha causing the require statement to fail and default to the empty JSON object {}. Unfortunately, Hardhat will NOT tell you that this failed and simple provide default values as if no accounts were specific. This can cause confusion when cross referencing your Metamask addresses from the imported mnemonic to the accounts on the Hardhat network and finding that they don’t match.

NOTE

Metamask and Coinbase Wallet DO NOT apply the passphrase to the seed generation but Hardhat DOES. This means that you need to leave the passphrase blank.