Understanding Functions in Solidity

ยท

5 min read

Functions are a core part of any Solidity contract. They let you define logic, work with state variables, and handle interactions from users or other contracts. In this post, weโ€™ll look at how to create functions in Solidity, use them to interact with state variables, and understand visibility specifiers and gas costs.


What Are Functions?

Functions in Solidity are pieces of code designed to execute specific tasks. They are defined using the function keyword and can perform operations such as:

  • Reading or writing state variables.

  • Returning values.

  • Accepting arguments to customize behavior.


Writing a Setter Function

Hereโ€™s an example of a setter function that modifies a state variable:

pragma solidity >=0.7.0 <0.9.0;

contract demo {
    uint public num; // State variable

    // Using with public keyword (specified visibility for function) means this function is available to access from outside //
    function setter(uint _num) public {
        num = _num;
    }
}

Explanation:

  1. State Variable: uint public num is a state variable stored on the blockchain.

  2. Setter Function: setNum accepts a parameter _num and assigns its value to the num state variable.

  3. Visibility Specifier: public ensures the function is accessible externally.


Writing a Getter Function

A getter function retrieves the value of a state variable without modifying it:

// Whenever we are reading a state variable,we write this keyword view since in this getter function //
    // This is a data type of variable returns (uint), that we are going to return from getter() function //
    function getter() public view returns (uint) {
        return num;
}

Key Points:

  1. view Keyword: Indicates the function doesnโ€™t modify the blockchain state.

  2. Returns Statement: Specifies the data type of the returned value.


Automatic Getter Functions for Public State Variables

When you declare a state variable as public, Solidity automatically generates a getter function for it. For example:

uint public num;

This is equivalent to manually creating the following function:

function num() public view returns (uint) {
    return num;
}

You can access the value of num directly without needing a custom getter function.


Visibility Specifiers in Functions

Visibility determines who can call a function. Solidity provides four visibility levels:

  1. public: Accessible externally and internally.

  2. private: Accessible only within the same contract.

  3. internal: Accessible within the contract and derived contracts.

  4. external: Accessible only externally (via transactions or other contracts).

In the above example, we used public for both setter and getter functions.


Gas Costs for Functions

Functions in Solidity can either read or modify the blockchain state:

  • Setter Functions: Modify the state and consume gas. This involves transactions that must be mined.

  • Getter Functions: Only read the state and are gas-free when called externally.

Example:

  1. Calling setNum(100) changes the state of num and costs gas.

  2. Calling getNum() to read num does not incur gas fees.


Default Values in Solidity

Solidity doesnโ€™t support null or uninitialized variables. Instead, each variable type has a default value:

  • uint: 0

  • string: "" (empty string)

  • bool: false

For example:

uint public num; // Default value is 0

Complete Example

// SPDX-License-Identifier: MIT
pragma solidity >=0.7.0 <0.9.0;

contract demo {
    uint public num;

    // Using with public keyword (specified visibility for function) means this function is available to access from outside //
    function setter(uint _num) public {
        num = _num; // passing as an argument to state variable num //
    }

    // Whenever we are reading a state variable,we write this keyword view since in this getter function //
    // This is a data type of variable returns (uint), that we are going to return from getter() function //
    function getter() public view returns (uint) {
        return num;
    }
}

Key Takeaways

  1. Setter functions modify state variables and cost gas.

  2. Getter functions read state variables without incurring gas costs.

  3. Visibility specifiers (public, private, internal, external) control function accessibility.

  4. Solidity creates automatic getter functions for public state variables.

  5. Understanding gas costs and state changes is crucial for writing efficient smart contracts.

By mastering functions, youโ€™ll be well-equipped to design robust and interactive Solidity contracts. Stay tuned as we dive into advanced concepts like view, pure, and payable functions in upcoming posts!

Challenges a create functions

To complete this challenge, you need to create a state variable and initialize it with 10. Then, create a function called returnStateVariable() that returns the value of this state variable.

Similarly, create a local variable and initialize it with 20. Then, create a function called returnLocalVariable() that returns the value of this local variable.

// SPDX-License-Identifier: MIT
pragma solidity >=0.7.0 <0.9.0;

contract Function{
    uint public stateVariable = 10; // state variable initialized with 10
    function returnStateVariable() public view returns (uint) {
        return stateVariable; // function to return the value of state variable
    }

    function returnLocalVariable() public pure returns (uint) {
        uint localVariable = 20; // local variable initialized with 20
        return localVariable; // function to return the value of local variable
    }    
}

Challenges Pass an argument to function

To complete this challenge, follow these steps:

  1. Create a state variable (it doesn't need to be public).

  2. Create a set() function with one argument. Use this argument to set the value of the state variable.

  3. Then, create another function called get() that returns the value of the state variable.

// SPDX-License-Identifier: MIT
pragma solidity 0.8.19;

contract FunctionArgument{
    uint num;
    function set(uint _num) public {
        num = _num;
    }

    function get() public view returns (uint) {
        return num;
    }  
}
ย