Hardhat – Get Error When Calling Delegate Contract Function with Hardhat Console

fallback-functionhardhatsolidity

Here is my code

contract SimpleUpgrade {
  address public implementation;
  address public admin;
  string public words;

  constructor(address _implementation) {
    admin = msg.sender;
    implementation = _implementation;
  }

  fallback() external payable {
    (bool success, bytes memory data) = implementation.delegatecall(msg.data);
  }

  function upgrade(address newImplementation) external {
    require(msg.sender == admin);
    implementation = newImplementation;
  }
}

contract Logic1 {
  address public implementation;
  address public admin;
  string public words;

  function overrideWords() public {
    words = 'old';
  }

  function getWords() public view returns (string memory) {
    return words;
  }
}

And after deployed them on bsc testnet, I would like to trigger overrideWords vie hardhat console. Here are my oprations:

> var SimpleTracker = await ethers.getContractFactory('SimpleUpgrade')
undefined
> var st = SimpleTracker.attach('0x910dd384e42BF33463AB1242Cf7189BCe7C3EEBE')  // Logic1 contract address on bsc testnet
undefined

And then I can get the address of Logic1 via

await st.admin()
> '0xec129bBB52925906BF1920a9Be7935C41C768A2C'

but not able to call overrideWords

> await st.overrideWords()
Uncaught TypeError: st.overrideWords is not a function

What should I do?

Best Answer

You can't simply call a function from the implementation interface on the SimpleUpgrade instance because it doesn't know how to handle that method.

If you want to have the same behaviour, I've created a simple script to do that:

const { Signer } = require("ethers");
const { ethers } = require("hardhat");

const overrideWordsABI = [
  {
    inputs: [],
    name: "overrideWords",
    outputs: [],
    stateMutability: "nonpayable",
    type: "function",
  },
];

async function main() {
  const SimpleUpgradeFactory = await ethers.getContractFactory("SimpleUpgrade");
  const SimpleUpgrade = SimpleUpgradeFactory.attach("0x910dd384e42BF33463AB1242Cf7189BCe7C3EEBE");

  const Logic1Address = SimpleUpgrade.implementation();
  const Logic1Factory = await ethers.getContractFactory("Logic1");
  const Logic1 = Logic1Factory.attach(Logic1Address);

  const iface = new ethers.utils.Interface(overrideWordsABI);
  const overrideWordsData = iface.encodeFunctionData("overrideWords");

  const [deployer] = await ethers.getSigners();
  const signer = ethers.provider.getSigner(deployer.address);

  const tx = await signer.sendTransaction({
    to: SimpleUpgrade.address,
    data: overrideWordsData,
    gasLimit: 30000000
  });
  await tx.wait();
 
  words = await SimpleUpgrade.words();
  console.log("words: ", words);
}

main().catch((error) => {
  console.error(error);
  process.exitCode = 1;
});
Related Topic