# Modifiers

Although we have already covered [functions](/introduction/hello-world/functions.md), there is one aspect of functions that we have yet to explore.&#x20;

To see the current problem with our understanding of functions, consider the *visibility* of functions; by specifying the visibility of a function, we can restrict actors from accessing a function. However, this becomes an issue if we want to allow *some* actors to call a function, while denying permission to others. With our understanding of visibility, we know that this is not possible. Therefore, are we doomed?

It seems as if we could implement permissioned functions if we could *modify* the logic of our function. And indeed, this is what modifiers allow us to do! Below is the general syntax for modifiers:

```solidity
modifier modifierName(P) {
    // Insert logic here
}
```

where `P` are the parameters that the modifier takes in. To see how modifiers are used, assume we have the following contract:

```solidity
contract Bank {

    address owner;
    
    function withdraw() public {
        // Withdraw logic goes here
    }

}
```

As the name intends, `Bank` holds a large sum of money and `withdraw` is a function is which we *only want the owner* to be able to call. For this guarantee to hold true, lets create a modifier `onlyOwner` that, when assigned to a function, only allows for the owner (i.e. deployer) of a contract to be able to call.

{% code lineNumbers="true" %}

```solidity
modifier onlyOwner() {
    require(msg.sender == owner, "You are not the owner!");
    _;
}
```

{% endcode %}

To understand the logic of `onlyOwner`, it is best to examine the modifier line-by-line:

* Line 2: we are *requiring* that the current message sender is the owner of the contract. If this invariant does not hold, the transaction will fail
* Line 3: the underscore implies that we are reverting control back to the function itself

The following code utilizes `onlyOwner`:

{% code lineNumbers="true" %}

```solidity
contract Bank {

    address owner;
    
    modifier onlyOwner() {
        require(msg.sender == owner, "You are not the owner!");
        _;
    }
    
    function withdraw() public onlyOwner {
        // Withdraw logic goes here
    }

}
```

{% endcode %}

In the function header of `withdraw`, we are calling `onlyOwner`; `withdraw` will execute if the owner of `Bank` is the one calling the function.

Although the `_` symbol inside modifiers might imply that we are reverting control back to the calling function for the rest of the execution context, this is actually not the case! Consider the following code:

{% code lineNumbers="true" %}

```solidity
contract Restroom {

    bool isOccupied;
    
    modifier lock() {
        require(!isOccupied, "Bathroom is already occupied!");
        isOccupied = true;
        _;
        isOccupied = false;
    }
    
    function useRestroom() public lock {
        // Logic goes here
    }

}
```

{% endcode %}

The contract represents a restroom where only one person is allowed at a time. Assuming that *anyone can call `useRestroom` at any time*, the `lock` modifier allows us to adhere to this invariant. Examining the modifier line-by-line:

* Line 6: we are checking if the restroom is occupied; if so, our function will revert
* Line 7: we are "locking" the restroom
* Line 8: we delegate control back to `useRestroom`
* Line 9: after `useRestroom` is finished executing, control is delegated back to `lock`, where it "unlocks" the restroom


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://cs4998.cornellblockchain.org/introduction/hello-world-pt.-2/modifiers.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
