Day 22. hardhat – Deployment –

While Hardhat itself does not provide a deployment feature, plugins like hardhat-deploy can be used to easily create deployment tasks. Here, we will explain actual deployment scripts. We will look at the script for deploying the Funding contract implemented on day17.

目次

Deployment Script

Let’s start by looking at an example of an actual deployment script.

TypeScript
// deploy/01-deploy-funding.ts
import { HardhatRuntimeEnvironment } from "hardhat/types"
import { DeployFunction } from "hardhat-deploy/types"
import { developmentChains } from "../helpder-hardhat-config"
import { networkConfig } from "../helpder-hardhat-config"
import verify from "../scripts/verify"

const deployFunding: DeployFunction = async function (
    hre: HardhatRuntimeEnvironment,
) {
    const { getNamedAccounts, deployments, network } = hre
    const { deploy, log } = deployments
    const { deployer } = await getNamedAccounts()

    log("-----------------------------------------------------")
    log("Deploying Funding and waiting for confirmations...")
    const funding = await deploy("Funding", {
        from: deployer,
        args: [],
        log: true,
        waitConfirmations: networkConfig[network.name].blockConfirmations || 0,
    })
    log(`Funding deployed at ${funding.address}`)
    if (
        !developmentChains.includes(network.name) &&
        process.env.ETHERSCAN_API_KEY
    ) {
        await verify(funding.address, [])
    }
}

export default deployFunding

deployFunding.tags = ["all", "funding"]

This script is deploying a contract named Funding. For the deployment, the deploy function is being used.

hre, getNamedAccounts, deployments, network

The code on line 11, hre (HardhatRuntimeEnvironment), is exported from hardhat/types and represents the execution environment of Hardhat. This variable hre allows access to the functionalities provided by Hardhat’s execution environment. For example, the three variables defined on the left side represent properties (functionalities) defined in hre.

TypeScript
// deploy/01-deploy-funding.ts (excerpt)
    const { getNamedAccounts, deployments, network } = hre
  • getNamedAccounts: A function provided by the hardhat-deploy plugin, it retrieves a list of named accounts from the configuration file (hardhat.config.ts). You can set named accounts for each network, and by using this, you can easily refer to accounts in the script. For example, if you have set an account for deployment as deployer, you can retrieve the account using getNamedAccounts in the form of { deployer }.
  • deployments: An object provided by the hardhat-deploy plugin, it offers methods for deployment-related operations. Specifically, it allows for the deployment of smart contracts (deploy method), retrieval of deployed smart contracts (get method), and retrieval of all deployed smart contracts (all method), among others. It also includes a function, log, for console output during deployment.
  • network: Provides information and functionalities related to the currently selected network and its settings. It includes the network name, config (network settings: RPC URL, chain id, etc. For more details, refer to day21).

With the above in mind, referring to lines 11 and 12, you can see that deploy and deployer are obtained from getNamedAccounts and deployments, respectively. deploy is the function that executes the process for actual deployment, and deployer is the user who executes the deploy (and this account is defined in the configuration file, see the section namedAccounts from line 51 onwards in day 21).

TypeScript
// deploy/01-deploy-funding.ts (excerpt)
    const { deploy, log } = deployments
    const { deployer } = await getNamedAccounts()

deploy function

The actual deployment is carried out in line 16. This is where the previously loaded deploy function is executed.

TypeScript
// deploy/01-deploy-funding.ts (excerpt)
    const funding = await deploy("Funding", {
        from: deployer,
        args: [],
        log: true,
        waitConfirmations: networkConfig[network.name].blockConfirmations || 0,
    })

The deploy function takes arguments as described below.

  • name: The name of the contract to be deployed. This must be unique and is used to refer to a specific contract deployment.
  • from: The address of the account sending the transaction. This account will pay the gas required for the contract deployment.
  • args: An array of arguments to be passed to the contract constructor. In other words, you define arguments according to the specifications of the constructor of the smart contract you developed.
  • log: If set to true, details of the deployment will be logged to the console.
  • waitConfirmations: In blockchain, when a transaction is included in a block and verified by the network, it is considered ‘confirmed’. This setting specifies the number of confirmations (the more confirmations, the less likely the transaction is to be tampered with. However, waiting for many confirmations prolongs the time it takes for the deployment to complete).

verify

The following source is the section where verification is requested on Etherscan. The actual request for verification is done in the verify function, which is used as a separate file placed under scripts named verify.ts.

TypeScript
// deploy/01-deploy-funding.ts (excerpt)
    if (
        !developmentChains.includes(network.name) &&
        process.env.ETHERSCAN_API_KEY
    ) {
        await verify(funding.address, [])
    }
TypeScript
// scripts/verify.ts
import { run } from "hardhat"

const verify = async (contractAddress: string, args: any[]) => {
    console.log("Verifying contract...")
    try {
        await run("verify:verify", {
            address: contractAddress,
            constructorArguments: args,
        })
    } catch (e: any) {
        if (e.message.toLowerCase().includes("already verified")) {
            console.log("Already verified!")
        } else {
            console.log(e)
        }
    }
}

export default verify

The run function on line 7 is provided by hardhat and can execute Hardhat’s tasks. It is a function for programmatically executing Hardhat tasks. Hardhat includes several standard tasks for compilation, testing, deployment, etc., which can be manually executed using the hardhat command-line tool. However, these tasks can also be called directly from within a script, and that’s the role of the run function.

The basic usage format is as follows. In the example above, the verify (verify:verify) task is being executed. The arguments include the address of the deployed contract and the arguments of the contract constructor (the deployed contract is obtained as funding from the deployment result on line 17, and using funding.address, you can obtain the address of the deployed contract).

TypeScript
await hre.run('taskName', taskArguments)

The part where the run function is executed is surrounded by a try-catch block. If the execution of the run function inside the try block does not go well, the error is captured in the catch block, and the error output is made to the console.

export

TypeScript
// deploy/01-deploy-funding.ts (excerpt)
export default deployFunding

deployFunding.tags = ["all", "funding"]

The TypeScript export statement is used to export functions, objects, values, types, etc., from a module. This allows other modules to use the exported entities using the import statement. In the example above, the previously defined deployFunding function is made public and available for use.

Continuing, the next part defines options for executing the deployment. If you specify the option as --tags all, functions tagged with all are executed. If you specify --tags funding, functions tagged with funding are executed (for instance, if the deployment consists of multiple deployment scripts, you can specify whether to execute all or only specific deployment scripts).

Executing the Deployment Script

Next, let’s actually execute a deployment locally.

Zsh
# console
% yarn hardhat deploy --network hardhat --tags all
yarn run v1.22.19
$ /Users/username/code/token-village/funding/node_modules/.bin/hardhat deploy --tags all
Generating typings for: 1 artifacts in dir: typechain-types for target: ethers-v6
Successfully generated 6 typings!
Compiled 1 Solidity file successfully
-----------------------------------------------------
Deploying Funding and waiting for confirmations...
deploying "Funding" (tx: 0xbc444ca6c542123b21a0f1a3515a8d8f2f43b980f8e747417596779369851eda)...: deployed at 0x5FbDB2315678afecb367f032d93F642f64180aa3 with 538126 gas
Funding deployed at 0x5FbDB2315678afecb367f032d93F642f64180aa3
  Done in 6.67s.
%

Deployment can be executed in the following format.

Zsh
% yarn hardhat deploy --network Network-Name [--tags Tag-Name]

For the network option, specify the network (local (hardhat), testnet (such as sepolia), or mainnet (mainnet)). For networks other than mainnet, they must be defined in hardhat.config.ts (see day 21 for configuration details).

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

After joining IBM in 2004, the author gained extensive experience in developing and maintaining distributed systems, primarily web-based, as an engineer and PM. Later, he founded his own company, designing and developing mobile applications and backend services. He is currently leading a Tech team at a venture company specializing in robo-advisory.

コメント

コメントする

CAPTCHA


目次