Search code examples
ethereumblockchainsoliditysmartcontractshardhat

why doesn't `connect` method work on Hardhat console?


I have a smart contract that is deployed to local network. I am using Hardhat console to interact with it. However, I can't switch to a different wallet/account from the console.


contract PaymentChannel {
    address public sender;
    address public recipient;
    uint public expiration;
    // the total amount in this payment channel
    uint public totalAmount;
    uint public paidAmount;

    constructor(address _recipient, uint duration) payable {
        console.log("constructor", msg.sender, _recipient, duration);
        sender = msg.sender;
        recipient = _recipient;
        expiration = block.timestamp + duration;
        totalAmount = msg.value;
    }
}

After deploy to local Ganache, I connect to this network from Hardhat via npx hardhat console --network ganache. It logs to Hardhat console successfully.

contract = await hre.ethers.getContractAt('PaymentChannel', '0x2b48dcF3AD875416e33D858E34555C13dc555cFc');

then I am able to use contract instance to call any methods from this contract:

> await contract.sender()
'0x763BB3c3C568681383eb04a5272e535c6d268128'
> await contract.totalAmount();
10000000000000000000n

however, when I try to use connect to switch to a different account, it doesn't allow me to call any contract's method:

> recipient = await contract.connect('0x47D20A3Fb51C6Cf3aB847136bC6CedBf86c8BD58')
> await recipient.sender()
Uncaught:
Error: contract runner does not support calling (operation="call", code=UNSUPPORTED_OPERATION, version=6.10.0)
    at REPL89:1:49 {
  code: 'UNSUPPORTED_OPERATION',
  operation: 'call',
  shortMessage: 'contract runner does not support calling'

I can confirm that the same code connect used in unit test works fine. what could be the reason for this error in the console?


Solution

  • I think you are providing wrong parameter type in connect function it does not take a string. You have to provide Signer object instead of string(address).

    To address this, you should first create a Signer instance using the private key of the account(0x47D20A3Fb51C6Cf3aB847136bC6CedBf86c8BD58). You can use the private key to instantiate a Wallet object from the ethers.js library.

    const privateKey = '0x71bE63f3384f5fb98995898A86B02Fb2426c5788'(actual private key)

    const account = new ethers.Wallet(privateKey);

    const recipient = await contract.connect(account);

    await recipient.sender()