Function visibility in solidity contract Programming

Photo by Andrew Neel on Unsplash

Function visibility in solidity contract Programming

In smart contract programming with solidity, the language allows developers to tell who can call their function based on some restriction.

Calling Function in Smart Contract

There are three ways of calling a function in the smart contract.

  • The main contract itself

  • Derive contract

  • Outside contract

- The main contract itself

contract MainContract{
    string Name;

    function main(string memory _name) external {
        storeName(_name);
    }

    function storeName(string memory _name) public {
        Name = _name;
    }
}

As you can see here, the MainContract is calling its function with the name storeName in another function with the name main

-Derived Function

//SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;

contract MainContract{
    string Name;

    uint256 disNumber;

    function main(string memory _name) external {
        storeName(_name);
    }

    function storeName(string memory _name) public {
        Name = _name;
    }

    function storeNumber(uint256 _number) public {
        disNumber = _number;
    }
}

contract DerivedContract is MainContract {
    function saveNumber (uint256 _num) public {
        storeNumber(_num);
    }
}

Syntax of derived contract, which is using a function from a mainContract.

-Outside contract

contract OutsideContract {
      function functionOutside(address mainContractAddress) external {
            // here we send a message call to main contract 
            MainContract(mainContractAddress).storeNumber(15);
      }
}

Function Visibility

Functions are the backbone of solidity contract programming, by default we use these functions to either request a change on the EVM or read its state.

Solidity requires us to define the visibility status of a function at the point of definition which set its accessibility

By default, if we do not define the visibility of a function, solidity gives it public.

There are four types of visibility we can assign to a solidity function

  • Public

When we define a function with a visibility status of public, this mean, anyone with an Ethereum account can call the function,

The public function can be accessed by all three types of calling contract functions as explained above.

function storeName(string memory name) public { Name = name; }
  • External

Third-party contracts are only allowed to access functions with this visibility definition, A contract that can call this function must be independent of the main contract where the function is defined.

contract myContract {
      string myName;

      function setName(string memory _name) external {
          myName = _name;
      } 

}

interface ImyContract {
    function setName(string memory _name) external;
}
// interface abbove is where we define the function we want to call with it's visibity status
contract CallingMyContract {
            function externalFunctionCall(address addr, string memory _name) external {
    ImyContract(addr).setName(_name);
          }
}

// externalFunctionCall, we pass in the address of the contract we want to call as argument 
// and call the function

CallingMyContract is independent of the myContract,

  • Internal

Function with internal visibility means the main contract that creates the function can call it and any derived contract can call it also.

contract Example{
    string myMovie;
    function saveMovie(string memory _movie) internal {
        myMovie = _movie;
    }

    function setMyDefaultMovie() public {
        myMovie = "Scandal";
        saveMovie(myMovie);
    }
}
  • Private

The private contract can only be called in the main contract where it is defined.


contract Example{
    string myMovie;
    function saveMovie(string memory _movie) internal {
        myMovie = _movie;
    }

    function setMyDefaultMovie(string memory _movie) private {
        myMovie = _movie;
    }

    function SaveMyDefaultMovie(string memory _movie) private {
        setMyDefaultMovie("Scandal");
    }
}

Inside the main contract, SaveMyDefaultMovie function is calling a private function with the name called "setMyDefaultMovie",

Conclusion

There you have it, when we define a function with the right visibility, we control who can call our function thus improving the security of our smart contract.