Smart contract deployment returning undefined address instead of contract location

Issue with Contract Deployment Script

I’m working on a blockchain project and having trouble with my deployment script. When I execute the command npx hardhat run scripts/deploy.js --network localhost, the contract address comes back as undefined instead of showing the actual deployed address.

Expected output:

Deploying contracts with account: [address]
Account balance: [balance]
TOKEN CONTRACT ADDRESS: [actual address]

Actual output:

Deploying contracts with account: 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266
Account balance: 9999992459571303767619n
TOKEN CONTRACT ADDRESS: undefined

My deployment script:

async function deploy() {
    const [signer] = await ethers.getSigners();
  
    console.log("Deploying contracts with account:", signer.address);
    console.log("Account balance:", await signer.provider.getBalance(signer.address));
  
    const TokenFactory = await ethers.getContractFactory("MyToken");
    const token = await TokenFactory.deploy();
    
    console.log("TOKEN CONTRACT ADDRESS", token.address);
    saveContractData(token, "MyToken");
}

function saveContractData(contractInstance, contractName) {
    const fs = require("fs");
    const dataDir = __dirname + "/../../client/contracts";
  
    if (!fs.existsSync(dataDir)) {
      fs.mkdirSync(dataDir);
    }
  
    fs.writeFileSync(
      dataDir + `/${contractName}-address.json`,
      JSON.stringify({ address: contractInstance.address }, undefined, 2)
    );
  
    const artifact = artifacts.readArtifactSync(contractName);
    fs.writeFileSync(
      dataDir + `/${contractName}.json`,
      JSON.stringify(artifact, null, 2)
    );
}
  
deploy()
    .then(() => process.exit(0))
    .catch(err => {
      console.error(err);
      process.exit(1);
    });

I tried adding await token.deployed() but got errors saying that method doesn’t exist. How can I properly get the deployed contract address?

Had the same issue last week. You’re probably using ethers v6 with an older hardhat setup. Try token.target instead of token.address - they changed the property name. Just do console.log("TOKEN CONTRACT ADDRESS", token.target); and it’ll work without the extra waits.

Yeah, this happens all the time when upgrading from Hardhat v1 to v2. The contract instance doesn’t get the address property right away after deployment anymore. You’ve got to wait for the deployment transaction to confirm first.

Here’s how to fix your deployment function:

const TokenFactory = await ethers.getContractFactory("MyToken");
const token = await TokenFactory.deploy();
await token.waitForDeployment(); // Wait for deployment confirmation

const contractAddress = await token.getAddress(); // Get the address
console.log("TOKEN CONTRACT ADDRESS", contractAddress);

Just use waitForDeployment() to make sure the contract’s fully deployed before moving on, then getAddress() to grab the actual address. Works reliably across different Hardhat versions and networks.