Solidity

Solidity Visibility and Getters

Solidity Visibility and Getters Main Tips

  • Solidity provides two types of function calls: internal ones and external ones, which create an EVM call.
  • Additionally, there are four types of visibility for the functions and state variables.
  • Every public state variable has a getter function created for it by the compiler.
  • A getter function is used to access the value of a specific variable.

Solidity Visibility and Getters

Given that there are two kinds of function calls in Solidity – internal ones, which call a function inside the same contract and external ones, which call functions from other contracts, thus needing to create an EVM call, also referred to as a “message call”)

Additionally, for functions and state variables, there are four types of visibility.

In Solidity, you can specify functions as externalpublicinternal or private, the default being public. As for state variables, external cannot be used, and by default they are internal.

external:
As a part of the contract interface, external functions can be called from other contracts and by transactions. If function f  is external, calling it internally is impossible (for example, f() will not work, however, this.f() works). When receiving large arrays of data, external functions may prove to actually be more efficient.

public:
Functions that are public, being a part of the contract interface, can be called both by message calls and internally. In the case of public state variables, they have an automatic getter function generated for them.

internal:
Internal functions and state variables are only accessible internally, that is, from the contract they in, without using this.
private:
Functions and state variables, that are private, will only be visible for the contract that they are declared in only, and not even in derived contracts.

Specifier of visibility is provided after the type of state variables, and also between return parameter list for functions and parameter list.

Example

pragma solidity ^0.4.0;

contract cont {
    function func(uint x) private returns (uint y) { return x + 1; }
    function setData(uint x) internal { data = x; }
    uint public data;
}

 

Try on Remix Try live on Hosting

Inside the example below, cont2, can call z.dataGet() for retrieving the value of data from state storage, however, it cannot call f . Contract cont3 derives from C, thus being able to call compute.

Example

// This code does not compile properly

pragma solidity ^0.4.0;

contract cont1 {
    uint private data;

    function func(uint x) private returns(uint y) { return x + 1; }
    function dataSet(uint x) { data = x; }
    function dataGet() public returns(uint) { return data; }
    function compute(uint x, uint y) internal returns (uint) { return x+y; }
}

contract cont2 {
    function dataRead() {
        cont1 z = new cont1();
        uint local = z.func(7); // error: member "func" is not visible
        z.dataSet(3);
        local = z.dataGet();
        local = z.compute(3, 5); // error: member "compute" is not visible
    }
}

contract cont3 is cont1 {
    function g() {
        cont1 z = new cont1();
        uint val = compute(3, 5); // access to internal member (from derived to parent contract)
    }
}

 

Try on Remix Try live on Hosting

Note: Contents of a contract are normally visible to any external observer. When something is made private, it will only prevent other contracts from being able to access and modify the data, however, anyone outside of the blockchain will still be able to see it.


Solidity Visibility and Getters Functions

Additionally, the compiler will automatically create a getter function for every public state variable available. In the code example below, the compiler generates a function called data which takes no arguments and then returns a uint with the value of the state variable data. State variables can be initialized at declaration.

Example

pragma solidity ^0.4.0;

contract cont1 {
    uint public data = 42;
}

contract contractCaller {
    cont1 c = new cont1();
    function func() {
        uint local = c.data();
    }
}

 

Try on Remix Try live on Hosting

The getter functions normally have external visibility. If the symbol gets accessed internally (that is, without the keyword this. ), it is evaluated as a state variable. If externally accessed (using the keyword this. , for example ), it gets evaluated as a function.

Example

pragma solidity ^0.4.0;

contract cont1 {
    uint public littleNumber;
    function func() {
        littleNumber = 3; // internal access
        uint val = this.littleNumber(); // external access
    }
}

 

Try on Remix Try live on Hosting

However, the following example gets a bit more complicated:

Example

pragma solidity ^0.4.0;

contract ContractComplex {
    struct Data {
        uint x;
        bytes3 y;
        mapping (uint => uint) map;
    }
    mapping (uint => mapping(bool => Data[])) public data;
}

 

Try on Remix Try live on Hosting

Therefore, as a result, a function in the following form is generated:

Example

function data(uint a1, bool a2, uint a3) returns (uint x, bytes3 y) {
    x = data[a1][a2][a3].x;
    y = data[a1][a2][a3].y;
}

 

Try on Remix Try live on Hosting

Note: The struct’s mapping is omitted as there is no proper way of providing the key for it.

Read previous post:
Solidity Contract Creation Basics

Solidity Contract Creation Basics Main Tips Solidity's contracts are very similar to classes in other object-oriented programming languages. Contracts contain state variables,...

Close