# Deciphering Solidity Optimization: Does adding a PAYABLE keyword actually save GAS?

By [Zaryab Afser](https://paragraph.com/@zaryab) · 2022-06-20

---

![](https://storage.googleapis.com/papyrus_images/ac50a7177f195c828d33b20236b4716469fd9f148140c9f72004c9ed739fb273.png)

If you have been developing smart contracts using Solidity lately, chances are you might have come across the **payable** keyword.

This blog is specifically about the same where we decipher all its interesting _and weird_ secrets. 😃

### Quick Intro: Basics of the Payable Keyword

Out of all the wonderful things that a smart contract can do, storing your money(ETH) is one of them. Now in order to take receive ETH in a smart contract, Solidity language has got a specific keyword called **payable.**

**A payable** keyword, in very simpler terms, is a modifier in the solidity language that can be attached to any function. Once attached, this keyword allows the function to receive ether. In other words, while triggering a function with a payable keyword, you can send ether (**_msg.value_**) along with that transaction.

While this is all good, I came across an interesting caveat around the **payable keyword** while [scrolling through Twitter](https://twitter.com/jadler0/status/1475579114841153537) a couple of months ago. It grabbed all my attention and I figured that an interesting (**_but really wired_**) scenario takes place whenever a **payable** modifier is attached to any function 👀.

_Let’s take a quick look at this interestingly wired scenario:_

![A setter function with NO Payable Keyword](https://storage.googleapis.com/papyrus_images/86ae16ba1003d7ffe6880023c207da98615ae15becf02d7b2c4c195bac5d87b0.png)

A setter function with NO Payable Keyword

A setter function with NO Payable Keyword

In the image attached above, we have a very simple setter function that sets the uint256 variable **state** to 100. If you trigger this function, you will find that the transaction gas cost is somewhere around **43300.**

Alright, now let’s look at a 2nd condition.

![A setter function WITH Payable Keyword](https://storage.googleapis.com/papyrus_images/86ae16ba1003d7ffe6880023c207da98615ae15becf02d7b2c4c195bac5d87b0.png)

A setter function WITH Payable Keyword

A setter function WITH Payable Keyword

In the 2nd case, we have the exact same function that executes an exactly similar transaction of setting a state variable. However, the only difference here is an additional **payable modifier** attached to the function.

Quite interestingly if you look at the transaction gas cost for calling this function, it's around **43276** which is lower than the function with _no payable keyword_ mentioned above.

Yes, you got that right.

**_Adding a simple payable keyword just reduced the amount of gas consumption in the function. 😃_**

![](https://storage.googleapis.com/papyrus_images/d8ad4299dfba0ec7139a67d203f457e2ebc834b9be270256086dced81acc9592.png)

The AHA Moment 💡💡
-------------------

**_Alright, now it's time to understand — Why exactly does the payable modifier lower the Gas consumption?_**

A very simple answer to that question is:

> **_Adding a payable keyword lowers the number of opcodes being executed, thus lowering the amount of gas consumption._**

That’s weird, isn’t it? How does adding an extra modifier to a function lower down the number of opcodes instead of increasing it???

Well here’s some technical (_and logical_) explanation for it. 😃

1.  As we already know, for a function to be capable of receiving ether, a **payable modifier** must be attached to it. While a function without any **payable** modifier shall never be able to receive any ether.
    
2.  It must be noted that this is a strict rule in Solidity and therefore if you try to pass Ether while calling a **non-payable** function, it will simply revert.
    
3.  Therefore in the case of **Non-Payable** functions, there are additional opcodes that are executed while calling a **non-payable** function which ensures that the function shall only be executed if the ether (**msg.value**) that is sent along with the transaction is exactly equal to **ZERO.**
    
4.  However, the same is not true for **Payable** function. Payable functions allow users to pass in both non-zero or zero ether values while calling the function.
    
5.  This basically means that even if zero ether (**_msg.value == 0_**) is sent while calling a **payable function,** the transaction is not reverted. Hence, there is no need to explicitly check the **msg.value** in the case of Payable functions.
    

In a Nutshell 🥜
----------------

![](https://storage.googleapis.com/papyrus_images/b4b39011af1ace265aa2bce4ced6d2559ef4bb8c11603fab1dd760912ddbbd28.png)

GAS Difference between PAYABLE and NON-PAYABLE Functions in Solidity

**In case of Non-Payable Functions:**

_a. Additional checks are included to ensure that no ether value is passed while calling the function._

_b. These checks increase the number of opcodes being executed._

_c. The increased number of opcodes ultimately results in higher gas usage._

**In the case of Payable functions:**

_a. No additional checks are required since the function can accept both zero or non-zero values of ether._

_b. No additional checks means no additional opcodes being executed._

_c. Lower opcodes in execution means lower consumption of gas._

My TWO CENTS 🪙🪙
-----------------

**_Does all of the above-mentioned details, mean we should use PAYABLE Functions to save gas?_**

Well, that could be a discussion.

Gas optimization is undoubtedly something that every smart contract wizard dreams of in their contracts.

However, an imperative question is:

![](https://storage.googleapis.com/papyrus_images/2d2af0fe722dbb2970c5cc3bc9baad716531062709d089908b869b918aa3a881.png)

While saving gas is important, it’s not really a good idea to compromise on the intended behavior of the function, minimizing the use of necessary state changes, or using inadequate tactics just to save a few extra amounts of gas. In other words, if a function has nothing to do with receiving ether, then it should not really have any payable keyword attached to it, even if that saves you some gas.

Dropping [John Adler](https://medium.com/u/a005f91be571)’s 2 Cents as well 😇

![](https://storage.googleapis.com/papyrus_images/3c4111b52e72171868f27a94080d74b1d8a9dc9aa2f59cb4b25ef7efbc93c551.png)

Therefore, I firmly believe that adding an unnecessary payable keyword in a function just to save gas is probably a bad decision. The above-mentioned scenario of reduction in gas while adding the payable keyword is just a wired solidity language design that is not at all effective.

* * *

### About myself

#### Who am I? 🙋🏻‍♂️

𝙃𝙞, 𝙄 𝙖𝙢 𝙕𝙖𝙧𝙮𝙖𝙗 👋🏻  I am a proficient Blockchain and Smart Contract Engineer with a vision of Decentralizing and Securing the traditional Web with Web3. Mostly work on Smart Contracts with significant experience in both Development and Smart Contract Security.

#### What I Do 🧑🏼‍💻

*   I write secure and optimized Smart Contracts
    
*   I perform security audits on smart contracts and enhance the overall security of smart contracts on EVM chains
    
*   I write and speak about Web3 and Smart Contracts & contribute my part towards expanding the boundaries for Web3.
    

#### Drop a ‘HI’ and Get in Touch 🤝

[Linkedin](https://www.linkedin.com/in/zaryab-afser-97085b157/). | [Twitter](https://twitter.com/zaryab_eth). | [Github](https://github.com/zaryab2000). | [Invite me for Web3 Events](https://zaryab2000.notion.site/Invite-me-to-your-Next-Web3-Event-78bcd204b866426687e1afbcdc61c5c7)

* * *

---

*Originally published on [Zaryab Afser](https://paragraph.com/@zaryab/deciphering-solidity-optimization-does-adding-a-payable-keyword-actually-save-gas)*
