Using variable and function visibility

Solidity state variables and functions should have visibility defined, along with their declaration. This visibility defines how a function and a state variable will be accessible from within the contract, as well as from outside of the contract.

There are four different visibility modifiers, that is, public, external, internal, and private, present in Solidity:

  • public: A function defined as public is accessible from both inside and outside of the contract. Solidity generates a getter function for public state variables, and these are also accessible from outside of the contract via these getter functions.
  • externalA function defined as external is only accessible from outside of the contract. Internally, the function will not be accessible directly. To access an external function within the same contract, you would have to call this.functionName(). For state variables, you cannot use the external keyword.
  • internal: A function or variable defined as internal is only accessible internally within the contract. Also, if Contract X inherits from Contract Y, which has internal functions or variables, Contract X can access all of Contract Y's internal functions and variables. When no visibility is specified, the variable would, by default, take internal visibility.
  • private: A function or variable defined as private is only accessible internally within the same contract. A private variable or function is not accessible in derived contracts.

The following table explains different visibilities and how they apply to state variables and functions:

Visibility Applies To Accessibility
public Both state variables and functions Within the contract and outside of the contract
external Only functions Only from outside of the contract
internal Both state variables and functions Internally, also in derived contracts
private Both state variables and functions Internally, only within the same contract

 

To understand this better, let's look at the following example:

contract SuperContract {
uint internal data;

function multiply(uint _a) private pure returns (uint)
{ return _a * 2;}
function setData(uint _a) internal { data = _a; }
function externalFn() external returns (uint) { /*...*/ }
function publicFn() public returns (uint) { /*...*/ }
}

contract VisibilityExample is SuperContract {
function readData() public {
//Following commented calls: error: not accessible
//uint result = multiply(2);
//externalFn();

//Following calls: Allowed access
data = data * 5; //variable accessible
setData(10); //function accessible
this.externalFn();
publicFn()
;
}
}

//Contract accessing VisibilityExample contract
contract ExternalContract {
VisibilityExample ve = VisibilityExample(0x1);

function accessOtherContract() public {
//Following commented calls: error: not accessible
//ve.setData(10);
//ve.multiply(10);

//Following calls: Allowed access
ve.externalFn();
ve.publicFn();
ve.readData();
}
}

As you can see, ExampleContract can call the externalFn()publicFn(), and readData() functions. 

If you have a public function that accepts an array as an argument, it is better to make that function external, as it is more efficient in terms of gas consumption.

Let's understand the visibility and accessibility by looking at preceding example. The following examples are shown in example code that follows in this chapter:

  • The VisibilityExample contract inherits from SuperContract. Refer to the Contract inheritance section of this chapter for more information.
  • The state variable data present in SuperContract is also accessible in VisibilityExample and can be modified directly.
  • The multiply() function is not accessible in the VisibilityExample contract, as its visibility is private. This function is only accessible inside SuperContract.
  • The externalFn() function is not accessible directly inside the VisibilityExample contract. However, you can access it by using this.externalFn().
  • ExternalContract is deployed separately from the VisibilityExample contract. This means that both of the contracts have different contract addresses. However, ExternalContract can call the functions of the VisibilityExample contract.
A private function or state variable within a contract doesn't mean that no one will be able to see that function. Since the blockchain is public, so is the definition of the contract, and anyone will be able to see the function definition. However, private visibility is only used to restrict other contracts from calling or accessing it.

Next, let's have a look at getter functions for state variables.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.144.255.55