Skip to content

Commit

Permalink
Refs #454 -- Added modifierAndInternal to general/build/smart-contrac…
Browse files Browse the repository at this point in the history
…ts/gas-optimization (#601)

* added modifierAndInternal to gas-optimization

* updated modifierAndInternel
  • Loading branch information
jackleeio authored Jun 6, 2024
1 parent 100b0f8 commit 32355c6
Showing 1 changed file with 90 additions and 0 deletions.
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.

0 comments on commit 32355c6

Please sign in to comment.