[Ethereum] why there is two function “_transfer” and “transfer” in solidity erc20

erc-20solidity

in almost all erc20 contract "_transfer" and "transfer" there are two functions and "transfer" calls internal "_transfer" why? Is there any security benefit of it ? in another words I have seen this approach not only with this particular function but with many functions call is being un necessary forwarded to some internal separate function for example just for checking who is msg.sender like below

modifier onlyOwner() {
    require(isOwner(), "Ownable: caller is not the owner");
    _;
}

function isOwner() public view returns (bool) {
    return _msgSender() == _owner;
}

function _msgSender() internal view returns (address payable) {
    return msg.sender;
}

why this modifier is extended to isOwner() and _msgSender() why not the same check done inside modifier itself ? Is there any security angle behind it ?

Best Answer

Usually this is because of modular design. So the contract itself is meant to be used as-is without modifications but you should inherit from it and, if needed, modify functionality in that new contract.

So if you want to change the functionality of _transfer you override it in the inheriting contract and (probably) also call the inherited contract's _transfer. In theory the same could be done for the transfer function but it's cleaner if there is only one entry point with the name transfer.

The logic of _msgSender refers (at least in the case of OpenZeppelin) to Gas Station Network meta transactions (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/GSN/Context.sol). I'm not sure exactly how it is supposed to be used but I guess you'd simply inherit from GSN and implement the required functionality. If you simply used msg.sender in your contracts there would be no way to modify that value based on conditions.

Related Topic