Control Statements In Solidity And Function Modifiers (My Web3 Journey) part 4
Tags: solidity, blockchain, smartcontract, web3
Published: 2021-12-13 09:37:37

A control statement in programming allows branching in our logic and code. It allows the ability to switch between different logic depending on the condition.

In Solidity, we have two types of control statements which are conditional and looping statement. ( same as Javascript )

## Conditional statement
Solidity supports the if/else conditional branching statement.

```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

contract IfElseExample {
    function oddEven(uint _num) public pure returns (string 
     memory) {
        function oddEven(uint _num) public pure returns (string memory) {
        if (_num % 2 == 0 ) {
            return "Even";
        } else {
            return "Odd";
         }
    }

    function ifElseFoo(uint x) public pure returns (uint) {
        if (x < 13) {
            return 0;
        } else if (x < 30) {
            return 1;
        } else {
            return 2;
        }
    }

    function ternaryOperation(uint _x) public pure returns (uint) {
        // if (_x < 15) {
        //     return 1;
        // }
        // return 2;

        // shorthand way to write if / else statement
        return _x < 15 ? 1 : 2; //Same way Javascript does it
    }
}
```

## Looping statement
Looping is supported in Solidity. Solidity supports for and while loops. If you already know how to loop in Javascript then you know looping in Solidity.

```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

contract LoopingExample {
    function loopForFun() public {
        // for loop
        //declare i as a uint
        for (uint i = 0; i < 10; i++) {
            if (i == 3) {
                // Skip to next iteration with continue
                continue;
            }
            if (i == 5) {
                // Exit loop with break
                break;
            }
        }

        // while loop used to execute a code when a condition holds true
        uint j;
        //you should try to avoid loops that will be infinite. 
        //you should be able to determine the terminal stage 
        //of your loop before looping
        while (j < 10) {
            j++;
        }
    }
```
If your loops makes changes to a lot of storage variable (that is data saved on the blockchain) the execution may fail because the gas cost needed to execute the function may be more than the estimated gas cost for the function.

Loops are there to enable us make decisions in our code based on some inputs or variables.

## Function modifiers
A modifier is a piece of code added to a function to give it extra functionality. For example a modifier could be used to check for the correctness of a value before the function it is attached to can work with that particular value. Lets see a modifier in action

```solidity
  // SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
contract FunctionModifier {
   address public owner;
   mapping(address => uint ) public coinsHeld;
   bool public locked;

  constructor(){
   owner = msg.sender;
  }

  modifier onlyOwner() {
    require(msg.sender == owner, "you are not the owner");
        // Underscore in a modifier means the rest of the code in the function that Solidity will execute. 
  _;
}
 
//a modifier can take an input
 modifier checkWorth(uint amount ){
   require(amount > 45, "Amount too small");
   _;
 }

  modifier noRentry(){
    require(!locked, "No rentry allowed");
    locked = true;
    _;
    locked = false;
  }
  //a function that the modifiers are attached to
  function increasEarnings( uint amount ) public onlyOwner noRentry checkWorth(amount) {
    coinsHeld[msg.sender] = amount;
  }

}


```
The above code defines three modifiers namely `checkWorth`, `noRentry` and `onlyOwner`. The `noRentry` modifier ensures and prevents the running of a function again if it hasn't finish executing while the `onlyOwner` modifier check and make sure that only the owner of the contract can perform some certain functions. 

The owner variable is set in the constructor when the contract is first deployed. A constructor is the first piece of code that is run automatically when a contract is deployed.

The `checkWorth` modifier accepts an input. 

Assuming the modifiers are not present we will have to do the three check manually. Function modifiers makes our code easier to read.

Don't forget the _ in a modifier or else your function will not be executed and the code will not even compile.
 
Until next time, thanks for reading....