Hardhat: Get contract address and pass as param to another contract to deploy

hardhathardhat-deploy

gm guys, I have a question about the InheritanceSubmission on the basecamp contract: I performed the following steps to deploy my contracts using Hardhat's Ignition:

  • I deployed the Salesperson and EngineerManager contracts in the same ignition and recorded both contract numbers.
  • I created another ignition module to deploy the InheritanceSubmission, passing the addresses of the previously deployed Salesperson and EngineerManager contracts.
  • I executed the Hardhat ignition command to deploy the InheritanceSubmission contract, but…

Although my InheritanceSubmissionModule only deploys the InheritanceSubmissionModule, it also redeployed the Salesperson and EngineerManager contracts. So, I'm wondering if there's a way to deploy all three contracts in the same ignition module. Ideally, after deploying the Salesperson and EngineerManager contracts, I could get the contract numbers of both and pass these numbers as parameters to the InheritanceSubmission. Alternatively, I want to know how to prevent Hardhat from redeploying my Salesperson and EngineerManager contracts when I try to deploy only the InheritanceSubmission contract.

Here is the link of the excercise in case you want to check

Edit: add ignition scripts:

salesperson and engineermanager contracts:

import { buildModule } from "@nomicfoundation/hardhat-ignition/modules";

const salesPersonHourlyRate = 20;
const salesPersonIdNumber = 55555;
const salesPersonManagerId = 12345;

const emAnnualSalary = 200000;
const emIdNumber = 54321;
const emManagerId = 11111;

const InheritanceModule = buildModule("InheritanceModule", (m) => {
  const hourlyRate = m.getParameter("hourlyRate", salesPersonHourlyRate);
  const managerId = m.getParameter("managerId", salesPersonManagerId);
  const idNumber = m.getParameter("IdNumber", salesPersonIdNumber);

  const annualSalary = m.getParameter("annualSalary", emAnnualSalary);
  const idNumberEm = m.getParameter("IdNumber", emIdNumber);
  const managerIdEm = m.getParameter("managerId", emManagerId);

  const salesPerson = m.contract("Salesperson", [
    idNumber,
    managerId,
    hourlyRate,
  ]);

  const engineerManager = m.contract("EngineeringManager", [
    idNumberEm,
    managerIdEm,
    annualSalary,
  ]);

  return { salesPerson, engineerManager };
});

export default InheritanceModule;

InheritanceSubmitionModule Contract

import { buildModule } from "@nomicfoundation/hardhat-ignition/modules";

const salespersonContract = "0x7E969c14eeCcB542d11f0cAA533dE30A097d82eC";
const enginnerManagerContract = "0xFCb006323675EE6fAfd3f74934DbB6C8E856a883";

const InheritanceSubmitionModule = buildModule(
  "InheritanceSubmitionModule",
  (m) => {
    const salespersonAddress = m.getParameter(
      "salesperson",
      salespersonContract
    );
    const engineerManagerAddress = m.getParameter(
      "engineerManager",
      enginnerManagerContract
    );

    const inheritanceSubmition = m.contract("InheritanceSubmission", [
      salespersonAddress,
      engineerManagerAddress,
    ]);
  }
);

export default InheritanceSubmitionModule;

Best Answer

Hardhat Ignition doesn't seem to provide a way (yet) to retrieve the contract addresses directly after deployment, particularly because it creates Future artifacts corresponding to the contracts during deployment.

However, with a general Hardhat Script, you can achieve the same easily.

You can just create a script folder, and create deploy.js file inside the same. Then, you can simply copy-paste this code in the deploy.js file:

const { ethers } = require("hardhat");
const fs = require('fs');

async function main() {
    // Initialize an empty object to store deployed contract addresses
    let deployedContracts = {};

    // Check if the 'deployed-contracts.json' file exists
    if (fs.existsSync('deployed-contracts.json')) {

        // If the file exists, read its contents and parse the JSON data
        const data = fs.readFileSync('deployed-contracts.json', 'utf8');

        deployedContracts = JSON.parse(data);

        // Get the factory of the 'InheritanceSubmission' contract
        InheritanceSubmission = await ethers.getContractFactory("InheritanceSubmission");
    }
    else {
        // If the file does not exist, deploy 'Salesperson' and 'EngineeringManager' contracts
        let salesPerson, engineeringManager;

        // Deploy the 'Salesperson' contract
        const salesPersonContractFactory = await ethers.getContractFactory("Salesperson");

        const salesPersonContract = await salesPersonContractFactory.deploy(); // Pass constructor params (if any)

        // Get the address of the deployed 'Salesperson' contract
        salesPerson = await salesPersonContract.getAddress()

        // Deploy the 'EngineeringManager' contract
        const engineeringManagerContractFactory = await ethers.getContractFactory("EngineeringManager");

        const engineeringManagerContract = await engineeringManagerContractFactory.deploy(); // Pass constructor params (if any)

        // Get the address of the deployed 'EngineeringManager' contract
        engineeringManager = await engineeringManagerContract.getAddress();

        // Store the addresses of the deployed contracts in 'deployedContracts' object
        deployedContracts = {
            salesPerson: salesPerson,
            engineeringManager: engineeringManager
        }

        // Write the 'deployedContracts' object to 'deployed-contracts.json' file
        fs.writeFileSync('deployed-contracts.json', JSON.stringify(deployedContracts, null, 2));

        console.log("Salesperson and EngineeringManager contracts have been deployed and their contract addresses have been saved to deployed-contracts.json");

    }

    // Deploy the 'InheritanceSubmission' contract with the addresses of 'Salesperson' and 'EngineeringManager' contracts
    const inheritanceSubmissionContractFactory = await ethers.getContractFactory("InheritanceSubmission");

    const inheritanceSubmissionContract = await inheritanceSubmissionContractFactory.deploy(deployedContracts.salesPerson, deployedContracts.engineeringManager);

    // Print the address of the deployed 'InheritanceSubmission' contract
    console.log("InheritanceSubmission contract has been deployed at", await inheritanceSubmissionContract.getAddress());

    // Print the addresses of 'Salesperson' and 'EngineeringManager' contracts stored in 'InheritanceSubmission' contract
    console.log("SalesPerson:", await inheritanceSubmissionContract.salesPerson())

    console.log("EngineeringManager:", await inheritanceSubmissionContract.engineeringManager())
}

main()
    .then(() => process.exit(0))
    .catch(error => {
        console.error(error);
        process.exit(1);
    });

Then, execute the script using this command:

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

P.S. You can change the network from hardhat to any other network as specified in your hardhat.config.js.

Related Topic