A weekend’s take on gas optimization

Aug 12, 2018 · 2 min read

Over the last two days, I’ve been optimizing a smart contract library which performs merkle-patricia proof verification for advanced commit-reveal schemes.

By Freepik

Before this project, I was often satisfied with heuristics such as “put storage data in structs” and “never use a for loop” in order to avoid egregious gas expenses. Although these heuristics can go a long way, I wanted to see if I could discover a few other perhaps more subtle heuristics which could save me a gas or two.

Declaring variables to memory.

When writing complex logic in a function, I’ve often found myself repeatedly reading the same storage variable. As it turns out, thats not the best idea.

A variable should be declared to memory if used more than once in a function.

The SLOAD opcode which reads a data word from storage costs 200 gas whereas the MSTORE and MLOAD opcodes which write and read from memory cost only 3 gas each.

The following code demonstrates the heuristic:

Using the right type.

My intuition told me I should always use the smallest possible datatype to prevent reserving space I know I will never use. Yet again, my intuition mislead me.

The most optimized storage type is always 32 bytes / 256 bit long unless struct packing is possible.

Any storage is compiled down to a byte array which is stored in the storage merkle-patricia tree of the contract. Each item in this byte array needs to consist of 32 bytes (256 bit). This means any smaller data is padded with zeros to fill the 32 bytes which requires additional operations from the EVM and costs more gas!

The following code shows the difference between declaring a uint256 and uint128 in storage.

Struct packing subtleties.

I’ve mentioned a couple times already that struct packing is a good heuristic. When I learned this heuristic, I started putting all my storage data in structs. As it turns out, there are some subtleties to address.

Struct packing only works when the combined data is a multiple of 32 bytes.

In the previous heuristic, we mentioned data gets padded to 32 bytes. Inside a struct, it’s possible to place multiple datatypes which add up to 32 bytes yet behave like a single 32 bytes object when stored. However, the following subtleties apply:

Thats it for now!

If you have any heuristics/subtitles to share, give me a shout @thegostep

My friend Hernando Castano shared a great article which covers the details of implementing quicksort in solidity. Worth a read!

Happy optimizing! 😄


Coinmonks is a non-profit Crypto educational publication.

Sign up for Coinmonks

By Coinmonks

A newsletter that brings you week's best crypto and blockchain stories and trending news directly in your inbox, by CoinCodeCap.com Take a look.

By signing up, you will create a Medium account if you don’t already have one. Review our Privacy Policy for more information about our privacy practices.

Check your inbox
Medium sent you an email at to complete your subscription.


Coinmonks is a non-profit Crypto educational publication. Follow us on Twitter @coinmonks Our other project — https://coincodecap.com


Written by




Coinmonks is a non-profit Crypto educational publication. Follow us on Twitter @coinmonks Our other project — https://coincodecap.com

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store