What is the object that gets deconstructed to {getNamedAccounts, devployments, getChainId } on smart contract deployment scripts?

Viewed 286

The following script is from a tutorial by Patrick Collins on creating NFTs. the source of this code is https://github.com/PatrickAlphaC/all-on-chain-generated-nft/blob/main/deploy/02_Deploy_RandomSVG.js

in the scripts that deploy contracts, the author uses a pattern similar to this:

let { networkConfig, getNetworkIdFromName } = require('../helper-hardhat-config')
const fs = require('fs')

module.exports = async ({
    getNamedAccounts,
    deployments,
    getChainId
}) => {
const { deploy, get, log } = deployments
const { deployer } = await getNamedAccounts()
const chainId = await getChainId()
...
...
const VRFCoordinatorMock = await deployments.get('VRFCoordinatorMock')
...
...

I am trying to understand what's going on under the hood with:

{
    getNamedAccounts,
    deployments,
    getChainId
}

It looks like some object is getting unpacked/deconstructed (?). I couldn't find any documentation about what it is, or if I did, its too complex for me to understand.

Can someone please tell me where this async function is getting exported to, and who will be requiring (i.e. calling) this function ?

If the above 3 properties were deconstructed from some object, what is that object? how does it fit in the bigger Hardhat picture?

2 Answers

I've recently been going through Patrick Collins blockchain course on FCC, and I wondered the same thing.

Hardhat is a development environment that allows you to run and create tasks such as yarn hardhat deploy. However, you can also add plugins to Hardhat that extend it's functionality.

In the course, Patrick uses the hardhat-deploy plugin which adds the fields you are trying to find documentation for. You won't find any documentation in regards to these fields on the Hardhat website since it's not baked into Hardhat. Here's a link to the plugin docs :)

The async function is being executed by hardhat-deploy when you run yarn hardhat deploy. The hardhat-deploy plugin will run any deploy scripts that are in /deploy. When these functions are executed Hardhat will automatically pass the hre object into the function as a parameter. hardhat-deploy extends the hre object by adding 4 new fields:

  • getNamedAccounts
  • getUnnamedAccounts
  • getChainId
  • deployments

Documentation for these fields can be found in the documentation I linked above.

In regards to what is object being passed in, this is a summary of it on the Hardhat website: "The Hardhat Runtime Environment, or HRE for short, is an object containing all the functionality that Hardhat exposes when running a task, test or script. In reality, Hardhat is the HRE."

So this part here:

module.exports = async ({
    getNamedAccounts,
    deployments,
    getChainId
}) => {

Is exporting an anonymous asynchronous function, which takes an object as a parameter that has those three keys.

That object could look something like this for example:

{
    getNamedAccounts: async () => { fetch(...) },
    deployments: { get: (name) => { ... } },
    getChainId: async () => { fetch(...) }
}

So lets say that the file where that export lies is named DeploymentCoordinator.js, one way you could use it from, say your index.js is:

var coordinator = require('./DeploymentCoordinator.js');

var someResult = await coordinator({
    getNamedAccounts: async () => { fetch(...) },
    deployments: { get: (name) => { ... } },
    getChainId: async () => { fetch(...) }
});

Furthermore, if you look in here https://github.com/PatrickAlphaC/all-on-chain-generated-nft/blob/main/test/RandomSVG_test.js you can see that at least deployments and getChainId seems to simply come from const { deployments, getChainId } = require('hardhat') at the top.

Related