GAS SAVING (SOLIDITY)

0xWeiss
5 min readJun 7, 2022

Gas fees are based on the amount of work that the node has to do in order to deal with our transaction. You don’t have endless gas, so whenever you are doing a transaction, the maximum amount of wei permitted it’s 30 million for each block.

Gas is a transaction fee, that is only paid when you want to modify data on the blockchain, not to view data. This means that the view and pure functions do not cost gas.

The sender of the transaction is who pays the gas and the miners are the ones that receive gas once the transaction is included in the blockchain.

First of all, let’s get to some basics:

We normally use 2 units to represent gas:

  • Wei 1*10^-18 eth
  • Gwei 1*10^-9 eth

How is gas cost calculated:

  • gas Cost(ether) = gas Price * gas Cost(gas).

Gas Price = how much ether you are willing to pay for each unit of gas, set by the sender of the transaction.

“SAVING GAS”

· Cast all the storage variables into memory inside functions.

· When using require, the longer the error message is, the more gas you use.

· Storage, memory, calldata, stack.

//Data locations that go from the most expensive, to the cheapest one.

· Fixed-size variables are always cheaper than dynamic ones. Define the length of an array if you know it. (uint [12] monthlyTransfers);

· Normally working with mappings is cheaper than working with arrays.

· Initializing a variable wastes gas if you are not going to use that value. Better to do: (uint256 pasta); than (uint256 pasta = 0);

· If we are adding message strings to require statements, we can make it cheaper by limiting the string to 32 bytes.

· Ethereum gives us a gas refund when we delete variables. That’s an incentive to save space in the blockchain.

· Deleting a variable, refunds 15k gas up to a maximum of half the gas cost of the transaction. Deleting with the delete keyword is equivalent to assigning the initial value for the data type, such as 0 for integers.

· Storing data in events can be done to save gas, even though is not recommended in most cases because events are not made for data storage.

· Using the indexed keyword in an event increases the price of the transaction.

· Minimize the on-chain data. Basically, when you code a smart contract, you have part of your logic on the smart contract, but usually, you also have part of your system on a centralized server. How to decide? Any critical data must go inside your smart contract such as all the economy. All the non-critical data such as the metadata can go to a centralized server.

· Use libraries if you are going to use different smart contracts for similar functionalities. Then you are going to deploy this library just once and all the smart contracts will point to this library to share the functionality.

There are two types of libraries, the embedded library, and the deployed library. But you just want the deployed library, for that, you need to make sure that all the functions in your library are external.

· Use ERC1167 if you need to deploy the same smart contract many times. It uses a proxy system of smart contracts, where you just have to deploy the actual code of the smart contract once. The following deployments are only going to point to the already deployed code logic, but still, each smart contract will have its own data on the blockchain

· Turn on the solidity optimizer in REMIX. It will help you to produce a more efficient bytecode that will help you to produce less gas, in Truffle you can activate it very easily using truffle-config.js.

The best thing is to turn it on when where are going to deploy the contract, because the problem that it has it’s that it takes more time to compile the code, therefore, it's not that efficient for development.

· Use events. If you have some data that only needs to be created once but after it doesn’t have to be updated or read from the smart contract, definitely this is a great option, events consume less gas than a normal state solidity variable.

Events are saved in a different place than storage variables, they are saved in some logs that allow you to print them. These logs or data structures are not accessible to smart contracts that’s why events are cheaper and spend less gas. On the transaction details in the window logs, you can find in the data window, a hash made up of all the parameters that were not indexed

· Use literal values instead of computed ones. If you know that a value will be stored in the blockchain don’t compute it from 0, if you know that you will store a specific hash compute it outside the smart contract, and directly from a static string you instantiate the variable with the final hash.

· Avoid copying arrays in memory. If you have some arrays that are stored in the stored location in the smart contract, the best thing is to create a storage pointer to that storage array in the smart contract and don’t need to copy that array at all

· Avoid creating for-loop over dynamic ranges. You have your smart contract where inside a function you have a for loop that iterates for a value that is dynamic.

· Optimize the order of your variable declaration, The EVM store the data of a smart contract of memory slot of 256bits. So uint256 can fit in one single slot, but for other types such as bytes, it expands several slots. But if you have several types of data that can fit in a 256 slot, solidity will actually do some optimization and put these two variables in a single slot. For example, 2 uint128 variables can fit in a single256 slot. In order for solidity to do this, your variables need to be declared next to each other

Uint128 a;

Uint128 b;

Uint256 c;

· Use an npm package named eth-gas-reporter and it will show your gas consumption of all of your functions every time you test your smart contract.

--

--