Blockchain 101 — Understanding Gas Fees

How gas fees work on blockchain networks and why they are important (with examples)

On blockchain networks each node is incentivized to provide the processing power to add a new block to the chain by the promise of earning a reward. One such reward is a gas fee. A gas fee is paid per transaction in the network’s native currency by the blockchain address wishing to execute the transaction. Before we begin, I want to point out that as blockchain networks enter the mainstream it is easy to start viewing gas fees as a nuisance. We must keep in mind that they serve a very important purpose. First, gas fees help to pay for network security by rewarding the people keeping track of what is going on across the network. Without them, these people would be supporting the network at their own financial cost which would be unsustainable. Second, they incentivize people using the network to send transactions back and forth with purpose. If there was no personal investment in a transaction, it would be easy for anyone to spam the network with meaningless transactions threatening the stability of the network.

While the significance of gas fees should now be understood, the concept and how they work can seem convoluted especially when a transaction involves tokens that are not the native currency, e.g. ERC-20 tokens. To understand gas fees better, let’s look at some concrete examples.

We start by looking at gas fees for a transaction that directly interacts with the blockchain network. In this example, the blockchain will be Ethereum and the transaction is to deploy a smart contract containing a slimmed down ERC-20 token. To get a copy of this smart contract and to follow along, you can find the source code on my GitHub.

Our smart contract is written in the Solidity programming language, so we need to install a Solidity compiler to compile the file down into the necessary formats for deployment and execution.

To get the smart contract into a format readable by an Ethereum Virtual Machine (EVM), we first compile it down to bytecode which produces a .bin file. Next, so that other applications can interface with it, we compile the contract down to a binary interface which produces a .abi file.

We are ready to deploy our smart contract to the Ethereum blockchain. For the purposes of this example, we won’t deploy to the public blockchain. Instead, we spin up a local instance of Ethereum by opening up a terminal window then installing and launching a handy tool called Ganache. This will return a list of Ethereum addresses that we will use to send transactions.

Next, we need a way to interact with our local Ethereum blockchain. As I am most comfortable in a Node.js environment I chose to install and use the web3 library. Let’s open a new terminal window and launch a Node.js environment.

Now we are ready to deploy our smart contract. This deployment involves sending a transaction to the blockchain from an Ethereum address. Let’s use the address for which we got the balance in the previous step above.

The result of the deployment is a transaction being added to the mempool to eventually be included in a new block that will be added to the blockchain. Since we are using a local Ethereum blockchain, this new block will be added immediately. Back in the terminal window where Ganache is running, we can see this new block and the address of our freshly deployed smart contract.

Back in the terminal running our Node.js environment, we see that the gas fee has been deducted from the address that sent the transaction.

In the deployment of our smart contract, we proposed a gasPrice of 30000000000000 Wei (0.00003 ETH) for the transaction. So we paid 0.00003 ETH per unit of gas and, as we can see in Ganache, the transaction used 168511 units of gas so the total price for the transaction was 5055330000000000000 Wei (5.05533 ETH) which was deducted for our sending address which is why we now see a balance of 94944670000000000000 Wei (94.94467 ETH) at that address.

Alright so we have seen how gas fees work for a transaction that directly interacts with the blockchain network. Next, we look at a transaction that interacts indirectly, e.g. when transacting with ERC-20 tokens like UNI, USDT, USDC, SUSHI, AAVE, OMG, ZRX, MKR, REP, GNT, LINK, LRC, etc. At their core, all ERC-20 tokens are smart contracts running on the Ethereum network; the 0x network has a good ERC-20 template to understand how these tokens function.

So let’s say that I am Basecoin: an exchange for the purchase and sale of tokens. I have a user named Alice holding 100 USDC at Basecoin. Alice now wants to transfer 10 USDC to her account at Trinance, another exchange, perhaps because they can offer her a higher annual percentage yield (APY) for holding small amounts of USDC. When Alice issues that transfer, she will be charged ETH. Why is this so?

Under the covers, Alice has two addresses on the Ethereum network: 0x9382422Ebc565CBdC9ec1f5A8e57147c114B3b5f is her address at Basecoin and 0x52427A871d651741469c1B54E7897cea42a0a83F is her address at Trinance. Because USDC is an ERC-20 token managed by a smart contract, when we call the smart contract to retrieve the balance it recognizes that at address 0x9382422Ebc565CBdC9ec1f5A8e57147c114B3b5f there is a balance of 100 USDC. When Alice makes the transfer, she is sending a transaction to the Ethereum network calling that smart contract to deduct 10 USDC from her balance at her Basecoin address and to add 10 USDC to her Trinance address. Because this transaction will need to be included in a new block, it requires payment in ETH to perform which, as we saw above, is deducted from the ETH balance of the sending address. The price of that transaction is determined by how high a gas fee the caller contract is willing to pay (a higher gas fee results in quicker processing of the transaction, e.g. at time of writing ETH Gas Station recommends 0.000000079 ETH to process a transaction in less than 2 minutes and 0.000000064 ETH to process it in under 30 minutes).

We can see this in action by returning to our deployed contract for our slimmed down ERC-20 token. As our smart contract is representative of the smart contract governing the USDC token, we’ll refer to this token as “pseudo-USDC”.

As discussed above, this transaction to change the balance at these two addresses adds a new block to the blockchain.

Let’s observe how this affected our ETH balance at Alice’s Basecoin address and her pseudo-USDC balances at her Basecoin and Trinance addresses.

As we can see, 1125960000000000000 Wei (1.12596 ETH) was deducted from Alice’s address at Basecoin such that her ETH balance at that address is now 98874040000000000000 Wei (98.87404 ETH). That amount was determined as a calculation of the 37532 units of gas that was used and the 30000000000000 Wei (0.00003 ETH) gasPrice that we were willing to pay which resulted in a total gas fee of 1125960000000000000 Wei (1.12596 ETH). In addition, her pseudo-USDC balance at that address has been deducted 10 pseudo-USDC and her balance at her address at Trinance has increased by 10 pseudo-USDC.

Having worked through this exercise, we should now understand more about the importance of gas fees for the security, sustainability, and validity of a blockchain network and how they are manifested by the network. We saw that gas fees are used to pay nodes to include our transactions in new blocks on the chain. These transactions may be direct interactions with the blockchain, e.g. deploying a smart contract, or indirect interactions, e.g. calling a smart contract to transfer tokens between addresses. In either case, the transaction is usually paid in the native currency of the blockchain, e.g. ETH on Ethereum, and the fee is deducted from the address sending the transaction.

Problem solver wielding JavaScript and Python as my tools. Builder of RESTful web services and progressive web applications. Scholar of the newly possible.