It’s no secret that gas fees are a costly and unavoidable reality on the Ethereum network. It doesn’t matter if you are the end-user of a dapp or a blockchain developer, optimising your gas usage saves you money and frees up resources on the network. However, in order to optimise gas, you need to understand how gas is calculated in the first place. Therefore, this article will show you how to calculate gas costs and give you an understanding of where every single unit of gas comes from.

A lot of the gas fee values used in this article come from the Ethereum Yellow Paper. However, at the time of writing, the paper was not up to date with the London hard fork and its changes made to the gas prices. Hence, this article fills that gap to provide you with the most up-to-date information.

## Gas Formula

Throughout this article, we will use the following transaction to demonstrate how gas can be calculated. You can see on Etherscan that this is a simple ERC20 token transfer of 2,772 USDC between two addresses. If you click “Click to see More“ you will find the total gas used by the transaction in the “Usage by Txn“ row. What you will not be able to find is a breakdown of how the total gas was calculated.

In order to calculate the total gas we can use the formula below by adding the initial fee, input data fee and gas used then subtracting the gas refund. In the following sections we will describe each of these components in more detail.

`Total Gas = Initial Fee + Input Data Fee + Gas Used - Gas Refund`

## Initial Fee

The initial fee is a fixed fee. It is the minimum amount of gas units that must be paid to initiate a transaction. Currently this fee is set to 21,000 units of gas.

You could consider this fee to be a constant and update the formula to the following:

`Total Gas = 21,000 + Input Data Fee + Gas Used - Gas Refund`

## Input Data Fee

The input data fee is the cost associated with the data you send along with your function. If you recall, our example transaction was a USDC transfer which means an address and the value to transfer are required. Therefore our input data will consist of:

- A function selector (indicating we want to execute the transfer function)
- The address
- The value to transfer

In Figure 2 below you can see what the input data looks like on Etherscan for our example transaction.

Input data is commonly the cause when you see the exact same transaction executed twice but with a small difference in gas price. If any of the above inputs change it can change gas cost. So simply changing the value or even the address in our current example could result in small changes to the gas cost.

### Calculating Raw Data Gas

In Figure 3 below, we can see that every zero valued byte of data is worth 4 units of gas and every non-zero valued byte of data is worth 16 units of gas.

Now we can apply these gas units to our input data. In Figure 4 below, you can see an unformatted view of the input data and is what we will use for calculations. You can get it by clicking “View Input As“ then clicking “Original“.

Let’s calculate the gas required for this raw input data.

`Raw Input Data: 0xa9059cbb00000000000000000000000028c6c06298d514db0899340713`

`55e5743bf21d6000000000000000000000000000000000000000000000000000000000a5489b58`

#### Step 1

Drop the 0x in the beginning

#### Step 2

Understand that a single hex value is 4 bits. So two hex values are 8 bits = 1 byte. Then remember that every zero valued byte of data is worth 4 units of gas and every non-zero valued byte of data is worth 16 units of gas.

#### Step 3

Calculate input data fee using this information. Figure 5 above demonstrates how this is done for our example transaction by adding all the zero valued and non-zero valued bytes.

#### Result

After adding all the zero and non-zero bytes together you get a total of 608 units of gas. We can use this value to update our formula as follows:

`Total Gas = 21,000 + 608 + Gas Used - Gas Refund`

## Gas Used

The gas used is the gas units spent to execute the functions within a transaction. This can get very time consuming to calculate as each opcode (or instruction) is assigned gas units. Fortunately we do not have to do too many calculations we can just use the VM tracer tool offered by Etherscan. Here is the VM Trace for our example transaction.

Figure 6 above shows the output from VMTrace. The two columns of interest are Gas and GasCost.

GasCost shows how many units of gas each Opcode uses. This is useful for checking between two transactions what might be differing.

Gas shows how much gas you have left from the initial gas limit you set. The initial gas limit for our example transaction is 97,584 units of gas. If we subtract the gas used so far (97,584 – 21,000 – 608) we get 75,976 units of gas.

To calculate the gas used you can simply take the starting gas and subtract the final gas. Both values you can find in the VM Trace.

In our case the gas used = 75,976 – 49,059 = 26,917 units of gas

Let’s update our formula with the new calculation.

`Total Gas = 21,000 + 608 + 26,917 - Gas Refund`

When executing the same function twice you might notice quite a large change in gas cost. This can come from the opcode SSTORE. SSTORE allows you to change the value of a state variable. If you set a state variable to zero the gas cost is 2,900 units. If you set a state variable to a non-zero value the gas cost is 20,000 units which is significantly more.

## Gas Refund

A gas refund is a reward you get for freeing storage on the blockchain. This is done by setting a value back to zero or its default value. When you do this, you get a fixed refund of 4,800 units of gas.

If we go to our example transaction on Etherscan you can click on the “State” tab then click “Click to see more“ on the USDC row. You will notice that there is a single storage address that is being set to zero (see Figure 7 below). So we are entitled to agas refund of 4,800 units.

Let’s add the final value to our formula:

`Total Gas = 21,000 + 608 + 26,917 - 4,800`

Figure 7. State changes on Etherscan

## The Finale

`Total Gas = Initial Fee + Input Data Fee + Gas Used - Gas Refund`

`Total Gas = 21,000 + 608 + 26,917 - 4,800`

`Total Gas = 43,725`

Now that we have solved for all our variables we can see that our transaction used a total of 43,725 units of gas. This value matches the value Etherscan gave us and now we know exactly where each unit of gas comes from. You will find that this information can help you write more gas efficient code and give you a better understanding of why gas prices can vary even when the exact same function is executed several times.