-
Notifications
You must be signed in to change notification settings - Fork 30
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Refs #454 -- Added modifierAndInternal to general/build/smart-contrac…
…ts/gas-optimization (#601) * added modifierAndInternal to gas-optimization * updated modifierAndInternel
- Loading branch information
Showing
1 changed file
with
90 additions
and
0 deletions.
There are no files selected for viewing
90 changes: 90 additions & 0 deletions
90
docs/general/build/smart-contracts/gas-optimization/modifierAndInternal.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
--- | ||
displayed_sidebar: generalSidebar | ||
--- | ||
|
||
# Modifiers vs Internal Functions | ||
|
||
In Solidity, the choice between using modifiers and internal functions can impact the gas costs associated with contract operations. This article explores the differences in gas usage between **modifiers** and **internal functions** when performing typical operations. Understanding these differences can help developers optimize their smart contracts for both functionality and cost. | ||
|
||
**Modifiers** inject their implementation bytecode directly where they are used, which can reduce runtime gas costs but increase the deployment size due to code repetition. **Internal functions** involve a jump to the function's implementation, which can reduce deployment size but slightly increase runtime gas costs. | ||
|
||
Below are two contracts demonstrating typical uses of modifiers and internal functions. These examples illustrate the operational gas costs associated with each. | ||
|
||
```solidity | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.19; | ||
// Deployment gas cost: 195,435 | ||
contract UsingModifiers { | ||
address owner; | ||
uint256 value; | ||
constructor() { | ||
owner = msg.sender; | ||
} | ||
modifier onlyOwner() { | ||
require(msg.sender == owner, "Not the owner"); | ||
_; | ||
} | ||
// gas: 28,367 | ||
function restrictedAction1() external onlyOwner { | ||
value = 1; | ||
} | ||
// gas: 28,377 | ||
function restrictedAction2() external onlyOwner { | ||
value = 2; | ||
} | ||
// gas: 28,411 | ||
function restrictedAction3() external onlyOwner { | ||
value = 3; | ||
} | ||
} | ||
// Deployment gas cost: 159,309 | ||
contract UsingInternalFunctions { | ||
address owner; | ||
uint256 value; | ||
constructor() { | ||
owner = msg.sender; | ||
} | ||
function onlyOwner() internal view { | ||
require(msg.sender == owner, "Not the owner"); | ||
} | ||
// gas: 28,391 | ||
function restrictedAction1() external { | ||
onlyOwner(); | ||
value = 1; | ||
} | ||
// gas: 28,401 | ||
function restrictedAction2() external { | ||
onlyOwner(); | ||
value = 2; | ||
} | ||
// gas: 28,435 | ||
function restrictedAction3() external { | ||
onlyOwner(); | ||
value = 3; | ||
} | ||
} | ||
``` | ||
|
||
From the above example, we can see that: | ||
|
||
- The contract using modifiers incurs higher deployment gas costs (195,435) compared to the contract using internal functions (159,309) due to repetition of the `onlyOwner` functionality in three functions. | ||
- During runtime, each function using modifiers costs a fixed 24 gas units less than the functions using internal functions. | ||
|
||
**Recommendations for Gas Optimization:** | ||
|
||
🌟 If runtime gas cost is your primary concern, and you are okay with the increase in deployment size, modifiers are a good choice. They reduce the gas cost during function calls by avoiding the jump to internal functions. | ||
|
||
🌟 If minimizing deployment gas cost and reducing the size of the creation code is more important, internal functions are preferable. They offer greater flexibility since they can be called at any point in a function, not just at the start or end. |