When sending Ether to a smart contract, understanding the transaction details displayed on a blockchain explorer can be challenging. This guide breaks down each field, explaining how gas fees are calculated and why certain values appear as they do.
What Are Gas Fees in Ethereum?
Gas fees represent the computational effort required to execute operations on the Ethereum blockchain. Every transaction or smart contract interaction consumes gas, and users pay for this gas in Ether (ETH). The structure of gas fees has evolved, especially since the London upgrade, which introduced a base fee and priority fee mechanism.
Components of Gas Fees
Modern Ethereum transactions include three primary components that determine the total cost:
- Base Fee: A mandatory fee calculated algorithmically based on network congestion. This amount is burned (removed from circulation) to reduce ETH inflation.
- Max Priority Fee: An optional tip paid to validators (miners in PoW, validators in PoS) to prioritize transaction processing. Higher tips generally lead to faster inclusion in blocks.
- Max Fee: The maximum amount a user is willing to pay per unit of gas. This cap ensures that even if base fees rise during periods of congestion, the total cost won’t exceed this limit.
The actual gas price per unit is calculated as: Gas Price = min(Base Fee + Max Priority Fee, Max Fee)
Transaction Execution and Gas Calculation
When you send ETH to a contract, the transaction isn’t just a simple transfer—it often triggers code execution in the contract’s receive or fallback function. This additional processing increases gas usage beyond the standard 21,000 gas for simple ETH transfers.
For example, a transaction sending 1 wei to a contract might consume 21,055 gas units due to extra operations like memory storage (MSTORE) and initialization steps. Each opcode in the Ethereum Virtual Machine (EVM) has a associated gas cost, which can be referenced in the EVM opcode gas list.
Analyzing a Transaction on Etherscan
Let’s examine a real transaction on the Goerli testnet: 0xf836049be423723eba16b00b84ecfbfde4c98e10a57c153426bd8834a7136a43
Key Fields and Their Meanings
- Input Data: Empty in this case, indicating a pure ETH transfer without additional contract calls.
- Gas Price:
1.000000111 Gwei = Base Fee (0.000000111 Gwei) + Max Priority Fee (1 Gwei) - Gas Limit & Usage by Txn:
The gas limit was set higher, but the actual usage was 21,055 units. - Transaction Fee:
0.000021055002337105 ETH = Gas Used (21,055) × Gas Price (1.000000111 Gwei) - Burnt Fee:
0.000000000002337105 ETH = Base Fee (0.000000111 Gwei) × Gas Used (21,055)
This portion was burned to reduce ETH supply. - Txn Savings Fee:
0.000010527497662895 ETH = (Max Fee - Actual Gas Price) × Gas Used
Represents the savings from setting a higher max fee than needed. - Value:
The amount sent—1 wei in this transaction.
Why Was Extra Gas Consumed?
A common question is why this transaction used 21,055 gas instead of the standard 21,000 for ETH transfers. The answer lies in the recipient contract’s receive function:
receive() external payable {
// Additional operations here consume extra gas
}Using Remix’s debugger or examining the opcodes, we see initialization steps and memory operations (like MSTORE) that add 55 gas units. Memory expansion costs are detailed in the EVM memory expansion gas documentation.
Querying Transaction Data with Ethers.js
Developers can programmatically retrieve transaction details using libraries like Ethers.js. Here’s an example script for querying the same transaction:
(async () => {
const ALCHEMY_GOERLI_URL = 'https://eth-goerli.alchemyapi.io/v2/your-api-key';
const goerliProvider = new ethers.JsonRpcProvider(ALCHEMY_GOERLI_URL);
const block = await goerliProvider.getBlock(8871803, false);
console.log(`8871803 block baseFeePerGas: ${block.baseFeePerGas}`);
const tx = await goerliProvider.getTransaction('0xf836049be423723eba16b00b84ecfbfde4c98e10a57c153426bd8834a7136a43');
console.log(`8871803 block tx.maxPriorityFeePerGas: ${tx.maxPriorityFeePerGas}`);
console.log(`8871803 block tx.maxFeePerGas: ${tx.maxFeePerGas}`);
})();Output:
8871803 block baseFeePerGas: 111
8871803 block tx.maxPriorityFeePerGas: 1000000000
8871803 block tx.maxFeePerGas: 1500000000These values align with the Etherscan data, confirming the gas calculation.
Frequently Asked Questions
What is the difference between gas limit and gas price?
The gas limit is the maximum units of gas you’re willing to consume for a transaction, while gas price is the amount of ETH you pay per unit. The total fee is the product of gas used and gas price.
Why are base fees burned?
Burning base fees reduces ETH inflation and makes the cryptocurrency more deflationary over time. It also ensures that validators prioritize transactions based on priority fees rather than base fees.
How can I estimate gas costs accurately?
Use tools like Etherscan’s gas tracker, or simulate transactions locally with Hardhat or Foundry. For real-time metrics, consider viewing real-time tools that provide network stats.
What happens if my max fee is too low?
If the base fee exceeds your max fee during congestion, your transaction may remain pending or eventually fail. Always set a reasonable max fee based on current network conditions.
Why do contract interactions cost more gas than simple transfers?
Contracts execute code, which requires additional computational resources. Simple transfers only involve updating account balances, while contract calls may run complex functions.
How does EIP-1559 impact gas fees?
EIP-1559 introduced the base fee mechanism, making gas prices more predictable. Users now set a max fee and priority fee, improving the fee market efficiency.
Conclusion
Understanding gas fees is essential for efficient Ethereum transactions. By analyzing fields like base fee, priority fee, and gas usage, users can optimize costs and avoid overpaying. Always consider network conditions and contract complexity when setting gas parameters, and use tools like Etherscan and Ethers.js to verify transaction details.