How to understand visibility in Solidity.
Tags: web3, solidity, beginners, blockchain
Published: 2022-01-01 12:28:07


In solidity, visibility specifies how a function or state variable in a contract can be accessed by other contracts & external accounts.
There are four(4) levels of visibility in solidity, and they are - private, public, internal, external.

When writing solidity you specify the visibility after the **type** for  state variables(or global variables) and between the function parameters and return types.
```javascript
address public holder; // type - visibility - varaiableName
function getBalance() private view returns(uint)//parameters - visibillity-returns
```

#### PRIVATE
Variables and functions declared as private can only be accessed inside the contract in which they are created. This means that they cannot be accessed from other contracts including sub-contracts.

```javascript
contract _Account {
    address _holder;
    
    constructor() payable {
        _holder = msg.sender;
    }

    function getHolder() private view returns (address) {
        return _holder;
    }
}

contract _Checking is _Account {
    function testGetHolder() public view returns (address) {
    return getHolder(); // DeclarationError: Undeclared identifier
}
```
When we try to access the private function "**getHolder**" from a child contract we get an error. It can only be accessed in the contract where it was created.

#### PUBLIC
When a function is declared as public in a contract, this means it can be accessed from within the contract, by contracts that inherit from it and by external accounts.
```javascript
contract _Account {
    // Function is declared as public
    function checkBalance() public view returns (uint) {
        return address(this).balance;
    }
}

contract _Checking is _Account {
    function testCheckBalance() public view returns (address) {
        return checkBalance(); // We can access it from child contracts.
    }        
}
```
In this case the function is public so we can call this function from within child contracts, or external accounts.

#### INTERNAL
Internal visibility means the variable or function declared as internal can be accessed from within the contract and sub contracts only.
```javascript
contract _Account {
    // Function is declared as internal
    function checkBalance() internal view returns (uint) {
        return address(this).balance;
    }
}

contract _Checking is _Account {
    function testCheckBalance() public view returns (uint) {
        return checkContractBalance(); // We can access it from a child contract!
    }
}

contract TestInternal {
    _Account newAccount = new _Account();
  function testcheckContractBalance() public view returns (uint) {
    return newAccount.checkContractBalance();// TypeError: Member "checkContractBalance" not found or not visible...
  }    
}
```
It is possible to access functions declared as internal from within the contract they are declared and from sub-contracts but we can't access them from external contracts. **Internal** visibility is the default visibility for state variables.

#### EXTERNAL
Functions declared as external are still a part of the contract but they cannot be called from within the contract without using **this** keyword. They however can be called from external accounts and contracts. State variables cannot be declared as external, it won't compile.
```javascript
contract _Account {   
    constructor() payable {}

    function checkContractBalance() external view returns (uint) {
        return address(this).balance;
    }
    function testcheckContractBalance() public view returns (uint) {
        uint contractBalance = this.checkContractBalance();// Using this keyword compiles without error!
        return checkContractBalance();// DeclarationError: Undeclared identifier
    }    
}
```
We are able to access the external function **checkContractBalance** from within the contract using **this** keyword, but we get an error when we remove it.

It is important to note that regardless of the visibility, functions and variables are actually visible to everyone who cares to look, so it is meant to visibility from other contracts and external accounts.