Does Solidity optimizer avoid changing storage variables?
Tags: solidity, blockchain, ethereum, web3
Published: 2022-02-14 03:12:35

[The original Post is here in Japanese
](https://blog.tumf.dev/posts/diary/2022/2/2022-2-14/)

In developing smart contracts on the blockchain, it is important to reduce the cost of execution, which is the cost of gas. [There are several famous tricks to reduce Gas consumption](https://mudit.blog/solidity-gas-optimization-tips/), one of which is "Avoid changing storage data". storage data".

For example, the UniswapV2 smart contract has the `gas savings` trick all over it like this.

![Uniswap/v2-core](https://i.imgur.com/Ylb0DKg.png)

I'm always careful about this when I write or review smart contracts, but the other day I suddenly thought, "_This is such a classic trick, isn't it already solved by Solidity's optimizer?_" So I tested it with the latest Solidity compiler `0.8.11`.



## Tested Smart Contracts

I created a Hardhat project and wrote the following smart contract. [complete source code](https://github.com/tumf/solidity-gas-saving-study)

{%gist https://gist.github.com/tumf/5bce3d0abad122aeb67185cd0f7c8b4c %}

`counter1()` is the non-gas-optimized code, `counter2()` is the gas-optimized code. The difference is that the Storage variable `counter` is copied to the local variable (memory) `j` and the result of counting in `j` is returned to `counter`.

## Test code

The code for gas consumption measurement is as follows:

{%gist https://gist.github.com/tumf/d01cf66c2c8b7842fb74c133a80bdba0 %}

## Measure the gas consumption

I use the useful Hardhat plugin [hardhat-gas-reporter](https://www.npmjs.com/package/hardhat-gas-reporter) to measure the gas bill.

Installation is as follows:

```shell=
$ yarn add --dev hardhat-gas-reporter
```

Add `require("hardhat-gas-reporter");` to the beginning of `hardhat.confg.js` as

For configuration, add `gasReporter` to `hardhat.confg.js`. If you set the API key of [Coinmarketcap](https://coinmarketcap.com/) to the environment variable `CMC_API_KEY` here, the cost in USD will be reported.

```javascript
module.exports = {
    ....
	gasReporter: {
		currency: "USD",
		gasPrice: 100,
		coinmarketcap: process.env.CMC_API_KEY,
	},
};
```

## Verification

Now that we're ready, let's get started with the verification. First, let's run it without using Solidity's optimizer.

```shell
$ npx hardhat test
```

![Solidity optimizer off](https://i.imgur.com/V6IVyo2.png)

The result looks like this:

```
disable Solidity optimizer
without code optimization (counter1): 630,118
with code optimization (counter2): 407,289 (-25%)
```

It seems that gas is reduced by about 25%, which is almost as expected.

Next, let's turn on Solidity's optimizer (runs:1,000).

![Solidity optimizer on](https://i.imgur.com/zCtspMM.png)

The result is as follows:

```
enable Solidity optimizer
without code optimization (counter1): 439,118
with code optimization (counter2): 218,271 (-50%)
```

Both with and without Solidity's optimizer, there is a large gas saving, but the effect of code optimization is still significant.

## Conclusion

It turns out that the gas saving trick of "avoid changing storage variables" still works even with the latest Solidity optimizer enabled. We should continue to be careful about changing storage variables.