I wondered why OpenZeppelin relies so much on the use of functions when, at first glance, they seem unnecessary for such elementary operations. For example, take the Ownable.sol contract. Why isn't the modifier strictly

modifier onlyOwner() {
    require(_owner == msg.sender, "Ownable: caller is not the owner");

instead of

address private _owner;

modifier onlyOwner() {

function owner() public view virtual returns (address) {
    return _owner;

function _checkOwner() internal view virtual {
    require(owner() == _msgSender(), "Ownable: caller is not the owner");

// This _msgSender() function is taken from Context.sol
function _msgSender() internal view virtual returns (address) {
    return msg.sender;

The way OpenZeppelin has their code written seems to spend more gas, so is security the reason? I get the use of owner() and _checkOwner() because owner is a private variable, but why create functions for such atomic pieces of code like the _msgSender()?

P.S.: The code I've transcribed are snippets of Ownable.sol and Context.sol.

  • You might have better luck getting an answer if you asked this question on the OpenZeppelin forum Commented Sep 8, 2022 at 12:42
  • 4
    As far as I know, the reason why OpenZeppelin complicated their implementations so much is that they wanted to promote the use of GSN. To my knowledge, this hasn't been a successful project. Commented Sep 8, 2022 at 12:43


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.