In Solidity, visibility modifiers determine how functions and state variables can be accessed. The four main visibility types are public, private, internal, and external. Each visibility type has specific rules regarding accessibility, which can affect the security and design of smart contracts.

1. Public

Functions and state variables declared as public can be accessed from within the contract, from derived contracts, and from outside the contract. For state variables, Solidity automatically creates a getter function.

Sample Code for Public


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

contract PublicExample {
uint256 public publicVariable; // Public state variable

function setPublicVariable(uint256 value) public {
publicVariable = value; // Public function to set the variable
}
}

2. Private

Functions and state variables declared as private can only be accessed from within the contract in which they are defined. They cannot be accessed from derived contracts or externally.

Sample Code for Private


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

contract PrivateExample {
uint256 private privateVariable; // Private state variable

function setPrivateVariable(uint256 value) public {
privateVariable = value; // Public function to set the private variable
}

function getPrivateVariable() public view returns (uint256) {
return privateVariable; // Public function to get the private variable
}
}

3. Internal

Functions and state variables declared as internal can be accessed from within the contract and from derived contracts. However, they cannot be accessed externally. This is useful for creating reusable code in derived contracts.

Sample Code for Internal


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

contract InternalExample {
uint256 internal internalVariable; // Internal state variable

function setInternalVariable(uint256 value) internal {
internalVariable = value; // Internal function to set the variable
}
}

contract DerivedContract is InternalExample {
function updateInternalVariable(uint256 value) public {
setInternalVariable(value); // Accessing internal function from derived contract
}

function getInternalVariable() public view returns (uint256) {
return internalVariable; // Accessing internal variable
}
}

4. External

Functions declared as external can only be called from outside the contract. They cannot be called internally (from other functions in the same contract). This type of visibility is often used for functions that are meant to be called by users or other contracts.

Sample Code for External


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

contract ExternalExample {
uint256 public value; // Public state variable

function setValue(uint256 newValue) external {
value = newValue; // External function to set the value
}

// The following function will not work because external functions cannot be called internally
/*
function updateValue() public {
setValue(10); // This line will cause a compilation error
}
*/
}

Conclusion

Understanding visibility modifiers in Solidity is crucial for designing secure and efficient smart contracts. Each visibility type serves a specific purpose, allowing developers to control access to functions and state variables effectively. By using public, private, internal, and external appropriately, developers can enhance the security and maintainability of their contracts.