What I see in several smart contracts, written with solidity, is that a public function is written whose job is just calling another function, which is private or internal. Here is an example from erc20burnable.sol
In this function _burn is internal, but burn is public.
`
function burn(uint256 amount) public virtual {
_burn(_msgSender(), amount);
}
`
or here is another one in erc1155.sol `
function safeBatchTransferFrom(
address from,
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) public virtual override {
require(
from == _msgSender() || isApprovedForAll(from, _msgSender()),
"ERC1155: caller is not token owner or approved"
);
_safeBatchTransferFrom(from, to, ids, amounts, data);
}
`
What is the benefit of this structure? why it is common in smart contracts? Thanks.
One reason for this, I guess, is this way we will be able to override parents, or add modifiers, etc.
It's a common practice used in other OOP languages as well.
One of the reasons is code reusability. If the same snippet (e.g. decrease balance of one address, increase balance of other address, and emit an event) is used in multiple methods (e.g. both transfer()
and transferFrom()
), you can bundle them into one private
function (e.g. _transfer()
). And then call this private
function from both public
functions. When you need to make a change in the code logic, you'll be able to make it in just one place instead of having to search for multiple places and leaving some out by mistake.
Other common reason - you already answered it yourself. This approach allows you to allow the user to specify only some params - for example the amount
. But the user cannot specify from which address are the tokens going to be burned - it's always from their address. Even though the private
function _burn()
allows to specify the burner, the user is not allowed to specify it.