Solidity Function – Can Solidity Function Have Optional Parameters?

functionsolidity

buyCoffee function has only 2 parameters. But if I call buyCoffee function with tip parameter in the test script, it does work. I tried to find some references in the ethers.js document but I couldn't. How does it work?

//BuyMeACoffee.sol
function buyCoffee(string memory _name, string memory _message) public payable {
        require(msg.value > 0, "can't buy coffee with 0 eth");
    }
//test script
async function main() {
  //Made test wallet
  const [owner, tipper, tipper1, tipper2] = await hre.ethers.getSigners();

  //Deploy contract
  const BuyMeACoffee = await hre.ethers.getContractFactory("BuyMeACoffee");
  const buyMeACoffee = await BuyMeACoffee.deploy();
  await buyMeACoffee.deployed();
  console.log("contract got deployed bro", buyMeACoffee.address);

  //Buy coffee
  const tip = {value: hre.ethers.utils.parseEther("1")};
  await buyMeACoffee.connect(tipper).buyCoffee("Cathy","You're the best!", tip);
  await buyMeACoffee.connect(tipper1).buyCoffee("Kath","Good Morning :)", tip);
  await buyMeACoffee.connect(tipper2).buyCoffee("Navie","How cool", tip);

}

Best Answer

It's not about Solidity, but how ethersjs abstracts the call to the contract and does some encoding and creates the transaction for you.

Basically, from a js contract instance created with ethersjs, when you are calling a method of the contract, the last argument is the 'options' or 'override' (check the docs here) values that you want your transaction to include. It has nothing to do with the actual contract function in the blockchain. It's just a way to let ethersjs know how to create the transaction that will be sent to the actual smart contract.

Check the docs: https://docs.ethers.io/v5/api/contract/contract/#Contract-functionsCall

And about optional parameters, Solidity does not support optional parameters as of now. Even though you could write a function that declares parameters that don't have variables names, like this:

function updateCounter(uint, uint) {...}

You would still need to encode values for each parameter and send them in your transaction.

In JS you can do something like the following to declare a function with an optional parameter n that is assigned the value 5 if no value is passed:

function myFunction(n = 5) {...}

We don't have something like that in Solidity.

Related Topic