Functions: Learning how Solidity functions work

Function Visibility

Function visibility refers to how and where a function can be called from. It defines the scope in which a function can be accessed and whether it is accessible from external users, derived contracts, or only within the contract itself.

Four visibility specifiers for functions:

  • Public -> Accessible from both inside the contract and outside (by other contracts or users).
  • Private -> Accessible only within the same contract.
  • Internal -> Accessible within the current contract and derived contracts.
  • External -> Accessible only from outside the contract.

Notes:
External functions can be called via transactions from external users or other contracts, but cannot be called from inside the contract using just the function name. However, they can be called using this.functionName().

Function State Mutability

Function state mutability refers to how a function interacts with the contract’s state and the blockchain. Specifically, it defines whether a function can read from or modify the blockchain state, and whether it can receive Ether.

  • View -> only reads the contract’s state but does not modify it.
  • Pure -> does not read or modify the state of the contract.
  • Payable -> allowed to receive Ether when it is called.
  • No Specifier -> can read and modify the state of the contract.

Notes:
* Gas efficiency: view and pure functions are more gas-efficient, as they do not modify state or require blockchain interactions. External calls to them are free (when executed off-chain).
* Payable functions are essential for contracts that need to receive Ether or handle payments.

FUNctions 🕺

You can’t spell functions without fun! 😆 And you must know the keywords 🔑

contract Example {
  function example1() private pure {
    // private: call me within this contract
    // pure: I cannot read/write to storage
  }
  function example2() internal view {
    // internal: call me within this contract (+ inheritance!)
    // view: I can read from storage, not write
  }
  function example3() public payable {
    // public: call me inside and outside this contract
    // payable: send me some ether!
  }
  function example4() external {
    // external: call me from outside this contract
  }
}

Returning values

contract Example {
  uint public sum;

  constructor(uint x, uint y) {
    sum = add(x, y);
  }

  function add(uint x, uint y) private pure returns(uint) {
    return x + y;
  }
}

Hands-on

learn-solidity-presentations\1c-functions\examples\0-returning-values\src\Example.sol
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.20;

import "forge-std/console.sol";

contract Example {
    uint256 public sum;
    uint256 public product;

    constructor(uint256 x, uint256 y) {
        (sum, product) = math(x, y);
    }

    function math(uint256 x, uint256 y) private pure returns (uint256, uint256) {
        return (x + y, x * y);
    }
}

edo@DESKTOP-4POSOVK:/mnt/e/Programming/Solidity/learn-solidity-presentations/1c-functions/examples/0-returning-values$ forge test -vv
[â ¢] Compiling...
[â °] Compiling 20 files with 0.8.25
[â ‘] Solc 0.8.25 finished in 1.05s
Compiler run successful!

Ran 1 test for test/Example.t.sol:ExampleTest
[PASS] testExample() (gas: 10314)
Suite result: ok. 1 passed; 0 failed; 0 skipped; finished in 12.47ms (135.60µs CPU time)

Learn Solidity. Alchemy University.
Accessed October 15, 2024
https://university.alchemy.com/overview/solidity