Choose Wisely Between Modifiers and Internal Functions
Last Updated on 24. March 2025 by Mario Oettler
If you are not familiar with modifiers read here.
If you are not familiar with internal functions read here.
When you add a modifier to a function, the code of the modifier is added to the function. Using a modifier for more than one function means that the modifier code exists multiple times. Due to this redundancy, the byte code is larger at deployment time. This results in higher gas costs during deployment.
When using an internal function, the function code exists only once. However, the EVM must jump to the beginning of the code and return to the calling function after the internal function has been executed. During deployment, this means lower gas costs as there is no redundancy. But during smart contract execution, the jumps cost additional gas.
This code uses an internal function:
pragma solidity 0.8.29;
contract Internal{
function helper() internal{
require(msg.sender != address(0));
}
function doSomething1() public{
helper();
}
function doSomething2() public{
helper();
}
}
This code uses a modifier:
pragma solidity 0.8.29;
contract Modifier{
modifier helper(){
require(msg.sender != address(0));
_;
}
function doSomething1() helper public{
}
function doSomething2() helper public{
}
}
So, there is a tradeoff between gas saving during deployment with internal functions and gas saving during execution with modifiers.
Deployment | Execution | |
Internal function | 109663 | 24454 |
Modifier | 119606 | 24426 |
Replacing modifiers with internal functions can reduce gas costs at deployment but deteriorate the readability of the code. Besides are modifiers less flexible in use as they are always executed at the start of the function.