Many times I see this type of architecture within a smart contract:

function mint(uint256 amount) external {
    require(msg.sender == owner, "Only owner can mint tokens");

function _mint(uint256 amount) internal {
    //minting logic

Why not just making the _mint() function external and move the require() line into that function?

1 Answer 1


Making things easier to read. Here is the example from the contract I wrote:

function unstake(uint256 _cid, uint256 _id) external {
        _unstake(msg.sender, _cid, _id);
function _unstake(
        address _user,
        uint256 _cid,
        uint256 _id
    ) internal {
        UserInfo storage user = userInfo[_user];
        CollectionInfo storage collection = collectionInfo[_cid];

            tokenOwners[collection.collectionAddress][_id] == _user,
            "Masterdemon._unstake: Sender doesn't owns this token"


        if (user.stakedTokens[collection.collectionAddress].length == 0) {
            collection.amountOfStakers -= 1;

        delete tokenOwners[collection.collectionAddress][_id];

        user.timeStaked[collection.collectionAddress] = block.timestamp;
        user.amountStaked -= 1;

        if (user.amountStaked == 0) {
            delete userInfo[_user];


Wrote this way to kinda classify the "frontend, external" function and "backend, internal" function. Makes code easier to read IMHO. Just the way I prefer to write I guess, other than that, I don't see any other reason to split function that way. Perhaps there are some very, very specific cases, but I can't recall any of that ATM.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.