Solidity Quick Tip: Use Modifiers To Abstract Common Logic Away

Solidity Quick Tip: Use Modifiers To Abstract Common Logic Away

Have you ever seen the need arise to apply certain assertions over and over again? Something like below, for example, when instances of contracts have certain owners?

// SPDX-License-Identifier: MIT
pragma solidity >=0.7.0 <0.9.0;
contract MyContract {
  address private _owner;
  constructor() {
    _owner = msg.sender;
  }
  function ownerOnlyAccess() public pure returns (uint8) {
    require(msg.sender == _owner, "Access only for owner");
    return 0;
  }
}

This is a lot of code to establish a foundation to make the check actually required. Doing this over and over again costs even more code and thus also gas.

Gladly, Solidity gives you ways to abstract all this away and even move assertions out of your functions’ bodies.



Enter Modifiers

Modifiers modify the behavior of functions. They are added to the functions’ prototypes and are applied under certain circumstances.

Modifiers make the most sense when implemented in a base contract that other contracts can derive from.

// SPDX-License-Identifier: MIT
pragma solidity >=0.7.0 <0.9.0;
contract Ownable {
  address private _owner;
  constructor() {
    _owner = msg.sender;
  }
  // the 'modifier' keyword marks this function as a modifier.
  modifier onlyOwner() {
    require(msg.sender == _owner, "Access only for owner");
    // the underscore is actually a special character that tells
    // the Solidity compiler to inline the body of the function
    // this modifier is applied to.
    _;
  }
}

You can use this base class and its modifier like this then:

// SPDX-License-Identifier: MIT
pragma solidity >=0.7.0 <0.9.0;
import "@yourLib/Ownable.sol";
// 'is' tells the Solidity compiler that MyContract inherits from Ownable.
contract MyContract is Ownable {
  constructor() {
  }
  // pay attention to the modifier 'onlyOwner' in the function
  // prototype. 
  // This enables the modifier for this function.
  function ownerOnlyAccess() public view onlyOwner returns (uint8) {
    // whenever this function is called, onlyOwner will run first,
    // and then the code within this function.
    return 0;
  }
}

You can apply the modifier to as many or as few functions as you want to. It saves you from repeating code over and over again. It also frees your functions’ bodies from many calls that have nothing to do with the actual business logic.


The Whole Tip As An Image

If you like visual content more, or if you want to store it for later, I put all this into one single image for you. I hope you like it!

A picture showcasing the above

Before You Leave

If you would love to read even more content like this, feel free to visit me on Twitter or LinkedIn.

I’d love to count you as my ever-growing group of awesome friends!

Oliver Jumpertz

Contact

Feel free to contact me

Contact Me

Connect

Subscribe

Join the Newsletter

You will regularly be informed about new content, special offers, and interesting information about software development.

Your data might be transferred to servers located in the USA. By subscribing, you agree to the data transfer. You can revoke your approval at any time by unsubscribing. For more information, please visit the privacy policy.

    We won't send you spam. Unsubscribe at any time.