Search code examples
ethereumsoliditysmartcontractsethers.js

How do I send data to Smart Contract via Ethers?


I am able to deposit amount of Ether into my smart contract via the depositFunds function like below:

async function depositFunds() {
  console.log(`Depositing Funds...`);
  if (typeof window.ethereum !== "undefined") {
    const provider = new ethers.providers.Web3Provider(window.ethereum);
    const signer = provider.getSigner();
    const contract = new ethers.Contract(contractAddress, abi, signer);
    const transactionResponse = await contract.depositFunds({
      value: ethers.utils.parseEther("1"),
    });
  }
}

I am now trying to withdraw a portion of the funds (i.e. not all of them), but I cannot figure out how to pass the data to the withdrawFunds function of my contract.

async function withdrawFunds() {
  console.log(`Withdrawing Funds...`);
  if (typeof window.ethereum !== "undefined") {
    const provider = new ethers.providers.Web3Provider(window.ethereum);
    const signer = provider.getSigner();
    const contract = new ethers.Contract(contractAddress, abi, signer);
    const transactionResponse = await contract.withdrawFunds({
      data: "0.5",
    });
  }
}

Below is the ABI for my withdrawFunds function:

{
    inputs: [
      {
        internalType: "uint256",
        name: "_weiToWithdraw",
        type: "uint256",
      },
    ],
    name: "withdrawFunds",
    outputs: [],
    stateMutability: "nonpayable",
    type: "function",
  }

Any ideas on how to approach this? Thanks!


Solution

  • await contract.depositFunds({
      value: ethers.utils.parseEther("1"),
    });
    

    This snippet builds the transaction object in a way that already contains the depositFunds() function selector at the beginning of the data field, followed by 0 arguments.

    The object containing the value property is called the overrides parameter. It allows you to override some other fields of the transaction, such as its value. It does not allow you to override the data field, as that's already build from the function name and arguments.

    The parseEther() function converts an amount of ETH into its corresponding wei amount. In your case, that's 1000000000000000000 wei. So the actual value that you're sending with the transaction is this "1 and 18 zeros".


    The withdrawFunds(uint256) function accepts the number of wei, that you want to withdraw, as an argument. So you need to convert the "0.5 ether" to the amount of wei, and simply pass it as the function argument.

    const transactionResponse = await contract.withdrawFunds(
      // the function argument
      // note that it's not wrapped in curly brackets
      ethers.utils.parseEther("0.5")
    );
    

    You can also optionally specify some overrides, but it's not needed in this case.

    const transactionResponse = await contract.withdrawFunds(
      ethers.utils.parseEther("0.5"),
      {
        // this is the `overrides` object after all function arguments
        gasPrice: "1000000000" // 1 billion wei == 1 Gwei
      }
    );