#Writing scripts with Hardhat
In this guide we will go through the steps of creating a script with Hardhat. For a general overview of using Hardhat refer to the Getting started guide.
You can write your own custom scripts that can use all of Hardhat's functionality. A classic use case is writing a deployment script for your smart contracts.
There are two ways of writing a script that accesses the Hardhat Runtime Environment.
# Running scripts with the Hardhat CLI
You can write scripts that access the Hardhat Runtime Environment's properties as global variables.
These scripts must be run through Hardhat: npx hardhat run script.js
.
This makes it easy to port scripts that were developed for other tools and that inject variables into the global state.
# Standalone scripts: using Hardhat as a library
The second option leverages Hardhat's architecture to allow for more flexibility. Hardhat has been designed as a library, allowing you to get creative and build standalone CLI tools that access your development environment. This means that by simply requiring it:
const hre = require("hardhat");
You can get access to all your tasks and plugins. To run these scripts you simply go through node: node script.js
.
To try this out, let's look at a fresh Hardhat project. Run npx hardhat
and go through the steps to create a JavaScript project. When you're done, your project directory should look like this:
$ ls -l
total 400
drwxr-xr-x 3 fzeoli staff 96 Jul 30 15:27 contracts
-rw-r--r-- 1 fzeoli staff 195 Jul 30 15:27 hardhat.config.js
drwxr-xr-x 502 fzeoli staff 16064 Jul 30 15:31 node_modules
-rw-r--r-- 1 fzeoli staff 194953 Jul 30 15:31 package-lock.json
-rw-r--r-- 1 fzeoli staff 365 Jul 30 15:31 package.json
drwxr-xr-x 3 fzeoli staff 96 Jul 30 15:27 scripts
drwxr-xr-x 3 fzeoli staff 96 Jul 30 15:27 test
Inside scripts/
you will find deploy.js
. Read through its comments to have a better idea of what it does.
// We require the Hardhat Runtime Environment explicitly here. This is optional
// but useful for running the script in a standalone fashion through `node <script>`.
//
// You can also run a script with `npx hardhat run <script>`. If you do that, Hardhat
// will compile your contracts, add the Hardhat Runtime Environment's members to the
// global scope, and execute the script.
const hre = require("hardhat");
async function main() {
const currentTimestampInSeconds = Math.round(Date.now() / 1000);
const unlockTime = currentTimestampInSeconds + 60;
const lockedAmount = hre.ethers.parseEther("0.001");
const Lock = await hre.ethers.getContractFactory("Lock");
const lock = await Lock.deploy(unlockTime, { value: lockedAmount });
await lock.waitForDeployment();
console.log(
`Lock with ${ethers.formatEther(
lockedAmount
)}ETH and unlock timestamp ${unlockTime} deployed to ${lock.target}`
);
}
// We recommend this pattern to be able to use async/await everywhere
// and properly handle errors.
main().catch((error) => {
console.error(error);
process.exitCode = 1;
});
Now run the script:
$ node scripts/deploy.js
Lock with 1 ETH deployed to: 0x5FbDB2315678afecb367f032d93F642f64180aa3
By accessing the Hardhat Runtime Environment at the top, you are allowed to run the script in a standalone fashion.
Hardhat always runs the compile task when it's invoked via npx hardhat run
, but in a standalone fashion you may want to call compile manually to make sure everything is compiled. This can be done by calling hre.run("compile")
. Add the following line at the beginning of the main
function and re-run the script with node:
await hre.run("compile");
$ node scripts/deploy.js
Nothing to compile
Lock with 1 ETH deployed to: 0x5FbDB2315678afecb367f032d93F642f64180aa3
#Hardhat arguments
You can still pass arguments to Hardhat when running a standalone script. This is done by setting environment variables. These are:
-
HARDHAT_NETWORK
: Sets the network to connect to. -
HARDHAT_SHOW_STACK_TRACES
: Enables JavaScript stack traces of expected errors. -
HARDHAT_VERBOSE
: Enables Hardhat verbose logging. -
HARDHAT_MAX_MEMORY
: Sets the maximum amount of memory that Hardhat can use.
For example, instead of doing npx hardhat --network localhost run script.js
, you can do HARDHAT_NETWORK=localhost node script.js
.