solidity – How to Call External Contract Function with Custom Struct Using TypeScript

ethers.jssoliditystruct

I have this basic contrat:

//SPDX-License-Identifier: Unlicense
pragma solidity ^0.8.4;

import "hardhat/console.sol";

contract Greeter {
    struct Greeting {
        uint8 id;
        string text;
    }

    Greeting[] public greetings;

    string private greeting;

    constructor(string memory _greeting) {
        greeting = _greeting;
    }

    function greet() public view returns (string memory) {
        return greeting;
    }

    function setGreeting(string memory _greeting) public {
        greeting = _greeting;
    }

    function setGreetings(Greeting[] calldata _greetings) external {
        for (uint16 i = 0; i < _greetings.length; i++) {
            greetings.push(_greetings[i]);
        }
    }
}

and I try to call setGreetings from ethers.js:

const Greeter = await ethers.getContract("Greeter")
await Greeter.setGreetings([[0, "Hello, Hardhat!"]]);

but I am receiving:

Error: missing argument: passed to contract (count=0, expectedCount=1, code=MISSING_ARGUMENT, version=contracts/5.5.0)

though I do manage to call the setGreeting with a string input:

await Greeter.setGreeting("Hello, Hardhat!");
expect(await Greeter.greet()).to.equal("Hello, Hardhat!");

Best Answer

You can use the following code as a test for setGreetings:

import { BigNumber } from "ethers";
import { ethers } from "hardhat";

describe("Greeter", function () {
  it("Should set greetings", async function () {
    const Greeter = await ethers.getContractFactory("Greeter");
    const greeter = await Greeter.deploy("Hello, world!");
    await greeter.deployed();

    const greetings = {
      id: BigNumber.from(0),
      text: "Hello, Hardhat!",
    }
    const setGreetingsTx = await greeter.setGreetings([greetings]);
    // wait until the transaction is mined
    await setGreetingsTx.wait();
  });
});