Learning Objectives – after this chapter you will be able to:
  • Write functions with parameters and single, multiple or named return values.
  • Choose the correct visibility: public, external, internal or private.
  • Choose the correct state mutability: view, pure, payable or the default.
  • Explain function overloading and internal vs external calls.
What are Functions?

Functions are blocks of code that perform a specific task for given inputs, so the same lines do not need to be repeated. For example, an add function takes two numbers and returns their sum wherever it is needed.

function <name>(<parameters>) <visibility> [<mutability>] [<modifiers>] [returns (<return types>)] {
    // statements
}
function add(uint a, uint b) public pure returns (uint) {
    return a + b;
}
Solidity Function Visibility Specifiers

Visibility decides who can call a function. Every function must state its visibility.

SpecifierCallable fromTypical use
publicEverywhere: inside the contract, derived contracts, other contracts and users.General API functions
externalOnly from outside (users and other contracts). Inside the contract it can be called only as this.f(), which is an external call.Entry points; parameters can use cheap calldata
internalThe current contract and contracts derived from it.Shared helper logic
privateOnly the current contract (not derived contracts).Implementation details
Solidity Function State Mutability

State mutability tells the compiler (and users) how a function interacts with blockchain data:

KeywordReads state?Changes state?Notes
viewYesNoFree when called off-chain
pureNoNoWorks only with its inputs and local variables
payableYesYesCan receive Ether (msg.value)
(default, non-payable)YesYesRejects any Ether sent to it

The compiler checks these rules: a pure function that reads a state variable, or a view function that writes one, will not compile.

Return Values and Overloading
  • A function can return several values: returns (uint, bool) and return (x, true);. The caller can unpack them: (uint a, bool ok) = f();
  • Named return variables (returns (uint sum)) are local variables that are returned automatically at the end.
  • Overloading: several functions can share a name if their parameter types differ, e.g. area(uint side) and area(uint l, uint w).
  • A public state variable automatically creates a getter function.
Example : Functions in Practice
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

contract FunctionsDemo {
    uint public total;                          // getter total() is generated

    function add(uint a, uint b) public pure returns (uint) {      // pure
        return a + b;
    }

    function addToTotal(uint x) external {                         // changes state
        total = _double(x) + total;
    }

    function getTotal() public view returns (uint) {               // view
        return total;
    }

    function divide(uint a, uint b) public pure returns (uint quotient, uint remainder) {
        quotient = a / b;                       // named returns
        remainder = a % b;
    }

    function area(uint side) public pure returns (uint) {          // overloading
        return side * side;
    }

    function area(uint length, uint width) public pure returns (uint) {
        return length * width;
    }

    function donate() external payable {}                          // accepts Ether

    function _double(uint x) internal pure returns (uint) {        // internal helper
        return x * 2;
    }

    function useDivide() external pure returns (uint) {
        (uint q, ) = divide(17, 5);             // unpack, ignore second value
        return q;                               // 3
    }
}
Key Takeaways
  • Visibility: public (everyone), external (outside only), internal (contract + children), private (contract only).
  • Mutability: view reads, pure neither reads nor writes, payable accepts Ether.
  • Functions can return multiple or named values and can be overloaded by parameter types.
Download | Print      E-Notes

The PDF E-Notes are the earlier printable version of this chapter. The notes on this page are the latest, revised version.

Video : Functions in Solidity
Resource Files
Question / Answer (15 questions)

Answer : A function is a named block of code that performs a task, optionally taking parameters and returning values. Functions define a contract’s behaviour and are called by users or other contracts.

Answer : function name(parameters) visibility [mutability] [modifiers] [returns (types)] { ... }, e.g. function add(uint a, uint b) public pure returns (uint) { return a + b; }.

Answer : public, external, internal and private.

Answer : Internal functions can be called inside the current contract and in contracts that inherit from it. Private functions can be called only inside the contract that defines them, not in derived contracts.

Answer : Public functions can be called both internally and externally. External functions can only be called from outside (or internally via this.f(), which is an external call); their parameters can be calldata, which can save gas.

Answer : A view function may read state but not modify it. A pure function neither reads nor modifies state and works only with its inputs and local variables. Both are free when called off-chain.

Answer : A function marked payable can receive Ether with the call; the amount is available in msg.value. A function without payable rejects any Ether sent to it.

Answer : Yes. function divide(uint a, uint b) public pure returns (uint q, uint r) { q = a / b; r = a % b; } returns both the quotient and remainder.

Answer : Return values given names in the returns clause. They act as local variables initialised to default values and are returned automatically when the function ends.

Answer : Defining several functions with the same name but different parameter types or counts, such as area(uint) and area(uint, uint). The compiler chooses the correct one from the arguments.

Answer : The compiler reports an error, because pure functions are not allowed to read or modify state.

Answer : It is a common naming convention (used by many libraries) that signals the function is not part of the public interface; it has no effect on behaviour.

Answer : Non-payable: it can read and modify state but rejects Ether. There is no keyword for it – it applies when view, pure or payable is not written.

Answer : Leave its position empty when destructuring, e.g. (uint q, ) = divide(17, 5);.

Answer : Not when called off-chain via eth_call. If a view function is called from inside a transaction (by another function), its execution gas is part of that transaction’s cost.
MCQ Test : Check Your Understanding (5 questions)

Select an option and press Check Answer, or answer all questions and press Submit Test to see your score. Each answer comes with an explanation.

Q1. A function that reads state but does not modify it should be marked:

Show Answer

Correct Answer : B. view
view allows reading but not writing state.

Q2. Which visibility allows calls ONLY from the same contract (not children)?

Show Answer

Correct Answer : D. private
private functions are not inherited.

Q3. Which function can receive Ether?

Show Answer

Correct Answer : A. function pay() external payable {}
Only payable functions accept Ether.

Q4. Two functions named area with different parameter lists is an example of:

Show Answer

Correct Answer : C. Overloading
Same name, different parameters = overloading.

Q5. In the example, useDivide() returns:

Show Answer

Correct Answer : B. 3
17 / 5 = 3 (remainder 2 is ignored).

Bibliography/References

The notes, questions and MCQs on this page are original explanations written for this course. The works listed below were consulted and are cited for attribution and further reading. Product names, logos and trademarks belong to their respective owners. Short quotations, where used, are marked and attributed.

  1. Solidity Team. (n.d.). Contracts (creating contracts, visibility and getters, function modifiers, constant and immutable, functions, events, custom errors, inheritance, abstract contracts, interfaces, libraries). Solidity Documentation. https://docs.soliditylang.org/en/latest/contracts.html
  2. Solidity Team. (n.d.). Expressions and Control Structures (if/else, loops, checked arithmetic, error handling, try/catch). Solidity Documentation. https://docs.soliditylang.org/en/latest/control-structures.html
  3. Solidity Team. (n.d.). Style Guide. Solidity Documentation. https://docs.soliditylang.org/en/latest/style-guide.html
  4. codedamn. (n.d.). Solidity functions. https://codedamn.com/news/solidity/solidity-functions
  5. Modi, R. (2018). Solidity Programming Essentials: A beginner’s guide to build smart contracts for Ethereum and blockchain. Packt Publishing. ISBN 978-1-78883-138-3.