Loading...

What is the difference between external and public functions, and when should you use each?

question solidity blockchain
Ram Patra Published on August 16, 2024

In Solidity, both external and public functions can be called from outside a contract, but there are key differences in how they are used, accessed, and their gas efficiency. Understanding these differences is crucial for writing optimized and secure smart contracts.

Differences Between public and external Functions

1. Visibility and Accessibility:

  • Public Functions:
    • Can be called both externally (from outside the contract) and internally (from within the contract).
    • When called internally, they can be called just like any other function (functionName()).
  • External Functions:
    • Can only be called from outside the contract.
    • If you want to call an external function from within the same contract, you must use this.functionName(), which triggers an external call (which is less gas-efficient).

2. Gas Efficiency:

  • Public Functions:
    • When called externally, public functions copy all arguments to memory, which can be more expensive, especially with large arrays or strings.
  • External Functions:
    • External functions are more gas-efficient when called externally because they read their arguments directly from the calldata, which avoids unnecessary data copying.

3. Usage of msg.data:

  • Public Functions:
    • Can access arguments directly and work with them in memory when called internally.
  • External Functions:
    • Arguments are accessed directly from calldata, which is read-only and generally cheaper in terms of gas.

When to Use public vs. external

Use public when:

  • You need the function to be accessible both internally and externally.
  • You expect the function to be called internally within the contract frequently.
  • The function might modify state variables or interact with other internal functions.

Example:

pragma solidity ^0.8.24;

contract Example {
    uint public data;

    // Public function
    function setData(uint _data) public {
        data = _data;  // Can be called internally and externally
    }

    function internalCall() public {
        setData(100);  // Internal call to a public function
    }
}

Use external when:

  • The function is primarily intended to be called from outside the contract, such as by other contracts or users.
  • You want to optimize gas costs for external calls, especially when passing large arrays or strings.
  • The function doesn’t need to be called internally, or if it does, it will be done rarely, and you are okay with the overhead of using this.functionName().

Example:

pragma solidity ^0.8.24;

contract Example {
    uint public data;

    // External function
    function setData(uint _data) external {
        data = _data;  // Can only be called from outside the contract
    }

    function internalCall() public {
        // This will trigger an external call, which is less gas efficient
        this.setData(100);
    }
}

Summary

  • public:
    • Accessible both internally and externally.
    • Less gas-efficient for external calls due to data copying.
    • Ideal when the function is expected to be called internally frequently.
  • external:
    • Only accessible externally (unless using this.functionName()).
    • More gas-efficient for external calls as it directly accesses calldata.
    • Best for functions that are primarily designed to be called from outside the contract.

By carefully choosing between public and external, you can optimize your contract for both performance and security.

Presentify

Take your presentation to the next level.

FaceScreen

Put your face and name on your screen.

ToDoBar

Your to-dos on your menu bar.

Ram Patra Published on August 16, 2024
Image placeholder

Keep reading

If this article was helpful, others might be too

question solidity ethereum August 18, 2024 Error Handling in Solidity: Assert, Require, Revert, Exceptions, Try/Catch

Error handling in Solidity is a crucial aspect of writing secure and robust smart contracts. Solidity provides various mechanisms to handle errors and exceptions, ensuring that contracts behave predictably even when something goes wrong. The key components of error handling in Solidity include assert, require, revert, try/catch, and built-in error types like Error and Panic.

question solidity blockchain August 16, 2024 Inheritance and Overriding in Solidity

In Solidity, overriding allows a derived (child) contract to modify or extend the behavior of functions defined in a base (parent) contract. This is a key feature in object-oriented programming and enables the implementation of polymorphism, where a child contract can provide a specific implementation of a function defined in the parent contract.

question solidity ethereum August 18, 2024 Different Data Types in Solidity and their default values

Solidity provides various data types, each with a specific purpose and behavior. When a variable is declared in Solidity but not explicitly initialized, it is assigned a default value depending on its type. Below is a comprehensive list of the different data types in Solidity along with their default values.