Mastering Gas and Gas Fees in Ethereum Transactions An In-Depth Academic Exploration
Contents
- 1 Mastering Gas and Gas Fees in Ethereum Transactions An In-Depth Academic Exploration
- 1.1 Chapter 1: Conceptual Framework of Gas in Ethereum
- 1.1.1 The Role of Gas in Network Stability and Security
- 1.1.2 Mechanics of Gas in Ethereum:
- 1.1.3 Impact on Network Security:
- 1.1.4 Enhancing System Fairness:
- 1.1.5 Conclusion of Section 1.1:
- 1.1.6 Economic Implications of Gas Fees
- 1.1.7 Facilitating Resource Allocation:
- 1.1.8 Miner Incentivization and Network Security:
- 1.1.9 Promoting Decentralization:
- 1.1.10 Conclusion of Section 1.2:
- 1.2 Chapter 2: Operational Dynamics of Gas
- 1.2.1 Gas Limit and Transaction Execution
- 1.2.2 Understanding the Gas Limit:
- 1.2.3 Roles and Importance of Gas Limit:
- 1.2.4 Block Gas Limit:
- 1.2.5 Significance of Block Gas Limit:
- 1.2.6 Example of Transaction Execution with Gas Limit:
- 1.2.7 Conclusion of Section 2.1:
- 1.2.8 Strategies for Setting Gas Prices:
- 1.2.9 Introduction to Gas Pricing Dynamics:
- 1.2.10 Determining Optimal Gas Prices:
- 1.2.11 Tools and Indicators:
- 1.2.12 Smart Contract Interactions and Gas Prices:
- 1.2.13 Programming Considerations:
- 1.2.14 Adaptive Strategies for Gas Pricing:
- 1.2.15 Conclusion of Section 2.2:
- 1.3 Chapter 3: Advanced Gas Optimization Techniques
- 1.3.1 Minimizing Gas Consumption through Efficient Coding:
- 1.3.2 Introduction to Gas-Efficient Coding:
- 1.3.3 Fundamental Strategies for Gas-Efficient Code:
- 1.3.4 Solidity Code Practices for Reducing Gas:
- 1.3.5 Example of Gas-Efficient Solidity Code:
- 1.3.6 Advanced Optimization Techniques:
- 1.3.7 Conclusion of Section 3.1:
- 1.3.8 Innovative Contract Design for Gas Efficiency:
- 1.3.9 Introduction to Smart Contract Design Innovations:
- 1.3.10 Architectural Optimization Strategies:
- 1.3.11 Solidity Design Patterns for Gas Efficiency:
- 1.3.12 Example of Gas-Efficient Contract Architecture:
- 1.3.13 Adopting External Libraries and Tools:
- 1.3.14 Conclusion of Section 3.2:
- 1.3.15 Practical Implementation: Gas-Optimized Smart Contract Example:
- 1.3.16 Introduction to Practical Implementation:
- 1.3.17 Smart Contract Scenario: Batch Token Transfer
- 1.3.18 Explanation of Gas Optimization Techniques:
- 1.3.19 Benefits of the Implemented Approach:
- 1.3.20 Conclusion of Section 3.3:
- 1.3.21 Conclusion:
- 1.3.22 Future Work:
- 1.3.23 References
#EnterTheSmartContractSecuritySeries009
Mastering Gas and Gas Fees in Ethereum Transactions An In-Depth Academic Exploration
Abstract:
This thesis delves into the critical elements of gas and gas fees within the Ethereum blockchain, elements that ensure the efficient execution of smart contracts. By providing a granular understanding of gas dynamics, this paper aims to equip developers with the knowledge to optimize the execution and cost-effectiveness of their applications, essential for advancing Ethereum’s technological adoption.
Introduction:
In Ethereum, each transaction and contract execution requires computational resources, quantified as “gas.” This mechanism not only secures and stabilizes the network by preventing abuse but also aligns economic incentives among participants. Understanding gas and its associated fees is fundamental for anyone involved in developing, deploying, or interacting with smart contracts. This thesis presents a systematic exploration of gas mechanics, offering a nuanced understanding that enhances both the efficiency and the strategic deployment of resources within the Ethereum ecosystem.
Chapter 1: Conceptual Framework of Gas in Ethereum
The Role of Gas in Network Stability and Security
Foundational Concept of Gas:
In the Ethereum blockchain, gas serves as a fundamental mechanism designed to execute operations reliably and securely. It functions as both a metering and a limiting factor for computational effort, ensuring that every action taken on the network is accounted for and paid for in terms of computational power.
Mechanics of Gas in Ethereum:
Transaction Validation: Every transaction on Ethereum requires computational resources. Gas measures these resources on a per-operation basis, ensuring that each piece of code executed in the Ethereum Virtual Machine (EVM) is associated with a cost. This prevents inefficient or malicious code from consuming excessive network resources, thereby maintaining stability and preventing Denial of Service (DoS) attacks.
Incentive for Miners: Miners play a crucial role in processing transactions and securing the Ethereum network. Gas fees act as an incentive for miners to include transactions in the blocks they mine. Higher gas fees typically correlate with quicker transaction processing, as they are more lucrative for miners. This incentivization is vital for maintaining the network’s security and ensuring that transactions are processed in a timely manner.
Impact on Network Security:
Preventing Spam Transactions: By requiring that each transaction pays a gas fee, Ethereum inherently discourages spam transactions. Potential attackers or spammers must incur significant costs to execute large volumes of transactions or run operations that consume network resources, making spam and resource depletion attacks economically unfeasible.
Regulating Computational Load: The block gas limit, which caps the total amount of gas that can be consumed in a single block, regulates the computational load on the network. This limit is dynamically adjusted by miners, balancing the desire for quick processing with the need to avoid overwhelming the network. It ensures that the blockchain operates smoothly without facing congestion issues that could lead to network stalls or excessive delays in transaction processing.
Enhancing System Fairness:
Equitable Resource Allocation: Gas fees ensure a fair allocation of network resources among all users. Users who require more computational time or power must compensate the network accordingly, which democratizes the computational and storage resources of the Ethereum network, ensuring that no single participant can monopolize system resources without appropriate compensation.
Adaptation to Network Conditions: Gas prices are not static; they fluctuate based on network demand and miner capacity. This dynamic pricing mechanism allows the network to adapt to changing conditions and user demand, balancing the needs for speed and cost-efficiency. Users can choose how much they are willing to pay for gas, providing flexibility and control over their transaction costs and priorities.
Conclusion of Section 1.1:
Gas is an ingenious tool designed to enhance the stability and security of the Ethereum network. By monetizing computational efforts, it ensures that resources are used judiciously while incentivizing miners to uphold network integrity. Understanding the critical role of gas is essential for anyone involved in Ethereum, whether they are developers, users, or security experts, as it impacts how securely and efficiently the network functions.
Economic Implications of Gas Fees
Introduction to Economic Dynamics of Gas:
Gas fees are a vital economic lever within the Ethereum ecosystem, influencing user behavior, miner incentives, and overall network health. This section explores how these fees integrate into the broader economic framework of Ethereum, impacting everything from transaction throughput to the decentralization of network power.
Facilitating Resource Allocation:
Resource Pricing: Gas fees effectively price the computational and storage resources of the Ethereum network. Each operation in a smart contract—from executing a function to storing information—incurs a cost in gas, which translates to real monetary value when paid in Ether. This mechanism ensures that resources are allocated efficiently based on market principles, where those willing to pay more can prioritize their transactions over others.
Demand-Driven Pricing: Gas prices are dynamically adjusted based on the demand for computational power and the supply of network capacity. During periods of high demand, such as network congestion due to popular decentralized applications (dApps) or token sales, gas prices increase. This serves as a natural regulator, discouraging non-essential transactions and encouraging efficiency.
Miner Incentivization and Network Security:
Rewarding Miners: Miners receive gas fees as a reward for processing transactions and securing the blockchain. These fees incentivize miners to continue investing resources into the network, which is essential for maintaining security and processing capacity.
Economic Security: The cost associated with gas fees also acts as a deterrent against network spam and potential security threats. By requiring significant financial expenditure to perform large-scale or malicious operations, gas fees contribute to the economic security of the Ethereum network.
Impact on Network Congestion and User Experience:
Managing Congestion: Higher gas fees during peak usage times naturally temper the number of transactions, as users evaluate the necessity and timing of their actions based on cost. This self-regulating mechanism helps manage congestion and ensures the network remains functional under varying loads.
User Experience and Strategic Planning: For users and developers, understanding and anticipating gas fee trends are crucial for optimizing interaction costs with the network. Strategic execution of transactions during lower-cost periods can significantly reduce expenses, particularly for operations not time-sensitive.
Promoting Decentralization:
Fair Access: By allowing users to bid for computational resources, gas fees promote a more equitable and decentralized access model. Everyone pays the same rate for computational effort, regardless of the content or context of their transactions, which supports a level playing field.
Decentralized Governance: The mechanism of gas fees and their fluctuation reflect a form of decentralized governance, where changes in network activity and miner actions dynamically adjust economic parameters. This decentralized decision-making process is fundamental to Ethereum’s ethos and operational efficiency.
Conclusion of Section 1.2:
The economic implications of gas fees extend far beyond simple transaction costs. They are an integral part of the economic fabric of Ethereum, influencing user behavior, network performance, and the overarching market dynamics. As Ethereum continues to evolve, especially with the upcoming shift to Ethereum 2.0, the role of gas fees and their economic impact will undoubtedly adapt, reflecting new technological and market realities.
Chapter 2: Operational Dynamics of Gas
Gas Limit and Transaction Execution
Understanding the Gas Limit:
The gas limit is a crucial concept in Ethereum, serving as a control mechanism for the amount of computational work that can be performed by a single transaction. This limit is set by the sender of the transaction and plays several pivotal roles in the Ethereum network’s operation and security.
Roles and Importance of Gas Limit:
Preventing Infinite Loops: One of the primary purposes of the gas limit is to prevent poorly written contracts or malicious actors from executing infinite loops, which could otherwise engage network resources indefinitely and disrupt service.
Controlling Transaction Cost: By setting a gas limit, users can control their maximum expenditure on a transaction. If the transaction requires more gas than the limit allows, it fails, ensuring users do not spend more on gas than they intended.
Ensuring Transaction Completeness: For a transaction to be successful, the gas limit must be high enough to cover all operations involved. Setting it too low can lead to incomplete transactions, which are reverted but still consume gas for the computational work done until the point of failure.
Strategies for Setting the Gas Limit:
Estimation Tools: Most Ethereum interfaces provide tools to estimate the gas needed for a transaction. Users are advised to use these tools to set a realistic gas limit that balances cost-efficiency with successful execution.
Adjusting to Network Conditions: During times of high network congestion, users might increase the gas limit to prioritize their transactions, ensuring they are processed in a timely manner despite increased competition for block space.
Block Gas Limit:
In addition to individual transaction gas limits, Ethereum also employs a block gas limit, which caps the total amount of gas all transactions in the block can consume.
Significance of Block Gas Limit:
Network Throughput and Stability: The block gas limit controls the throughput of the Ethereum blockchain. A higher limit allows more transactions per block but can increase the time it takes to propagate blocks across the network, potentially affecting stability.
Miner Influence and Decentralization: Miners have the authority to vote to increase or decrease the block gas limit, a mechanism that allows the network to adapt to changing conditions and demands. This flexibility supports decentralization, giving miners a stake in managing the network’s operational capacity.
Example of Transaction Execution with Gas Limit:
// Solidity example for understanding gas usage in a transaction
pragma solidity ^0.8.17;
contract GasLimitExample {
uint public count;
function incrementBy(uint value) public {
// This function’s gas usage depends on the input ‘value’
for (uint i = 0; i < value; i++) {
count++;
}
}
}
In this contract, the incrementBy function will have varying gas costs depending on the input value due to the loop. Users need to set an appropriate gas limit to ensure the transaction doesn’t fail if the loop’s iteration is higher than anticipated.
Conclusion of Section 2.1:
The gas limit is an essential safeguard and operational parameter within the Ethereum ecosystem. Proper management of the gas limit, both at the transaction and block level, is critical for ensuring efficient network performance, user cost management, and overall system security. Understanding and effectively setting gas limits are fundamental skills for anyone interacting with Ethereum, whether as a user executing transactions or a developer designing smart contracts.
Strategies for Setting Gas Prices:
Introduction to Gas Pricing Dynamics:
Gas prices in Ethereum are measured in gwei, which is a denomination of Ether (1 gwei = 10^-9 Ether). They play a critical role in determining how quickly a transaction will be processed by the network. Gas prices are not fixed; instead, they fluctuate based on network demand and miner preferences. Understanding how to strategically set gas prices can significantly impact the cost and speed of transaction execution.
Determining Optimal Gas Prices:
Market-Based Pricing: Gas prices are determined by the market conditions of supply (miner capacity) and demand (network congestion). Users must assess the current network activity to decide how much they are willing to pay per unit of gas to have their transaction processed within their desired timeframe.
Transaction Priority: Higher gas prices will prioritize your transaction among miners, as they are incentivized to include transactions with higher fees into the next block for greater rewards. Users who need rapid confirmation should consider setting higher gas prices.
Tools and Indicators:
Gas Price Estimators: Numerous online tools and wallets provide real-time data on gas prices, offering recommendations based on current network conditions. These tools often offer a range of options from slow to fast transaction speeds, corresponding to different price levels.
Historical Gas Price Data: Analyzing past gas price trends during different times of the day or week can help users anticipate periods of lower prices, enabling cost-effective transaction planning.
Smart Contract Interactions and Gas Prices:
Contract Complexity: The complexity of a smart contract can affect the gas used per transaction. Before interacting with a contract, assess the gas requirements and set a gas price that balances cost with the necessity for timely execution.
Batch Processing: When feasible, batching multiple transactions or contract interactions into one can reduce the cumulative gas price impact, as the overhead of transaction initiation is distributed across multiple actions.
Programming Considerations:
pragma solidity ^0.8.17;
contract GasPriceManagement {
function transactWithCustomGasPrice(uint256 _gasPrice) external payable {
require(tx.gasprice <= _gasPrice, “Gas price exceeds limit”);
// Transaction logic here
}
}
This Solidity snippet illustrates a function that allows transactions only if the current gas price is below a user-defined threshold, giving users control over their spending on gas.
Adaptive Strategies for Gas Pricing:
Flexible Strategy: Users should adopt a flexible approach by setting a higher gas price during times of high demand and lowering it when the network is less congested.
Monitoring Tools: Continuously monitor gas prices using blockchain analytics platforms and adjust your strategies accordingly. This proactive approach ensures that you are always optimizing for both cost and speed.
Conclusion of Section 2.2:
Strategically managing gas prices is essential for navigating the Ethereum network efficiently. By understanding market dynamics and utilizing tools and programming techniques, users and developers can optimize their interactions with the network, balancing cost with performance. As Ethereum evolves, staying informed and adaptive to changes in gas pricing strategies will remain a crucial aspect of participating in its ecosystem.
Chapter 3: Advanced Gas Optimization Techniques
Minimizing Gas Consumption through Efficient Coding:
Introduction to Gas-Efficient Coding:
In Ethereum, every operation incurs a cost in gas, so efficient coding is crucial for minimizing these costs, especially for applications expected to perform numerous transactions. Efficient coding not only reduces transaction fees but also enhances the performance and scalability of decentralized applications (dApps).
Fundamental Strategies for Gas-Efficient Code:
Optimize Computational Logic: Simple optimizations, such as reducing the complexity of loops and avoiding unnecessary computations within contract functions, can significantly lower gas costs. Developers should scrutinize their algorithms for efficiency, removing redundant or unnecessary operations.
Minimize State Changes: Writing to or modifying the blockchain state (i.e., updating storage variables) is one of the most expensive operations in Solidity. Therefore, strategies that minimize state changes can lead to substantial gas savings. Developers should aim to aggregate changes locally and update state variables in a single transaction wherever possible.
Solidity Code Practices for Reducing Gas:
Use Memory Instead of Storage: In Solidity, using memory variables—temporary variables that do not write to storage—whenever possible can reduce gas costs. Memory variables are erased at the end of function execution and are cheaper to use than storage variables, which persist on the blockchain.
Efficient Data Structures: Choosing the right data structures is critical. For instance, packing multiple boolean values into a single uint256 can save space and reduce the cost of storage operations.
Example of Gas-Efficient Solidity Code:
pragma solidity ^0.8.17;
contract GasEfficient {
uint256 public count;
// Example of minimizing state writes
function incrementCount(uint256 times) public {
uint256 localCount = count; // Read state once into local variable
for (uint256 i = 0; i < times; i++) {
localCount++; // Increment the local variable
}
count = localCount; // Write back to state once after all increments
}
}
In this example, the incrementCount function minimizes state changes by using a local variable for computation before writing the result back to the state variable. This approach significantly reduces gas costs compared to incrementing the state variable directly within the loop.
Advanced Optimization Techniques:
Gas Profiling and Analysis Tools: Utilizing tools like Remix, Truffle, or other Ethereum development frameworks to profile and analyze gas usage can help identify and eliminate gas-intensive code parts.
Reusing Existing Code: Leveraging built-in functions and well-tested libraries that are optimized for gas efficiency can reduce both the deployment and execution cost of contracts.
Educational and Community Resources for Learning Gas Optimization:
Developers should engage with the broader Ethereum community, participate in forums, and utilize educational resources to stay informed about best practices in gas optimization. Community resources, including open-source projects and Solidity developer forums, provide valuable insights and examples of gas-efficient coding techniques.
Conclusion of Section 3.1:
Efficient coding is not just a technical requirement but a fundamental aspect of developing cost-effective and scalable smart contracts on Ethereum. By adopting and refining the strategies outlined above, developers can significantly reduce the gas costs associated with their contracts, making their applications more accessible and economical for users.
Innovative Contract Design for Gas Efficiency:
Introduction to Smart Contract Design Innovations:
Efficient smart contract design transcends basic coding practices, incorporating architectural decisions that minimize gas consumption. This section explores innovative design patterns and architectural strategies that can significantly enhance gas efficiency in Ethereum smart contracts.
Architectural Optimization Strategies:
Proxy Contracts for Upgradeability: Utilizing proxy patterns (such as the Proxy Delegate pattern) allows for smart contracts to be upgraded without the need to redeploy the entire codebase to the blockchain. This not only saves gas related to deployment but also enables bug fixes and improvements without incurring the substantial cost of deploying new contracts.
State Channels for Off-Chain Interactions: Implementing state channels can drastically reduce the need for on-chain transactions. By moving the majority of interactions off-chain and settling final state on-chain, state channels minimize the gas costs associated with transaction processing.
Solidity Design Patterns for Gas Efficiency:
Lazy Evaluation: This involves delaying computation or state changes until absolutely necessary. For example, in a voting contract, instead of tallying votes with each new vote, tally them only when the result is needed. This can save significant amounts of gas by reducing the frequency of state writes.
Tight Variable Packing: Solidity stores variables in 256-bit slots by default. Efficiently packing smaller data types into a single slot can reduce the amount of storage space required, thus decreasing the gas cost for state updates.
Minimal Anti-pattern: Avoiding the excessive use of loops and large, complex data structures that are costly to update. Instead, opt for breaking down functions and using mappings to access specific elements directly.
Example of Gas-Efficient Contract Architecture:
pragma solidity ^0.8.17;
contract GasEfficientVoting {
mapping(address => uint256) public votes;
uint256 public totalVotes;
bool public finalized;
uint256 public finalResult;
// Vote without immediately updating the final result
function vote(uint256 voteCount) public {
require(!finalized, “Voting has been finalized.”);
votes[msg.sender] += voteCount;
totalVotes += voteCount;
}
// Finalize the result calculation when needed
function finalizeResult() public {
require(!finalized, “Already finalized.”);
uint256 result = 0;
for (uint i = 0; i < voters.length; i++) {
result += votes[voters[i]];
}
finalResult = result;
finalized = true;
}
}
In this voting contract, votes are collected and tallied only when the finalizeResult function is called, instead of updating the running total with each vote. This approach minimizes state changes and saves gas.
Adopting External Libraries and Tools:
Using OpenZeppelin Contracts: Leverage well-tested libraries such as OpenZeppelin, which offer secure, optimized, and reusable contract modules. These libraries are designed with gas efficiency in mind and can significantly reduce the amount of custom code needed.
Utilizing Gas Optimization Tools: Tools like Remix, Truffle, and Hardhat offer features to analyze and optimize gas usage, providing insights into how different contract designs impact gas consumption.
Conclusion of Section 3.2:
Innovative contract design is critical for achieving gas efficiency in Ethereum development. By integrating advanced architectural strategies and adopting efficient design patterns, developers can significantly enhance the performance and cost-effectiveness of their dApps. These practices not only optimize resource usage but also contribute to the scalability and sustainability of the Ethereum network.
Practical Implementation: Gas-Optimized Smart Contract Example:
Introduction to Practical Implementation:
Understanding theoretical optimization strategies is essential, but applying these concepts in practical scenarios is where their true value emerges. This section presents a detailed example of a gas-optimized smart contract, demonstrating efficient coding practices, architectural decisions, and the integration of optimization patterns.
Smart Contract Scenario: Batch Token Transfer
The following Solidity contract exemplifies a gas-efficient approach to performing batch token transfers, a common requirement in applications needing to distribute tokens to multiple recipients efficiently.
Solidity Contract Code:
pragma solidity ^0.8.17;
interface IERC20 {
function transfer(address recipient, uint256 amount) external returns (bool);
}
contract BatchTokenTransfer {
IERC20 public token;
constructor(address _tokenAddress) {
token = IERC20(_tokenAddress);
}
// Gas-optimized batch transfer function
function batchTransfer(address[] calldata recipients, uint256[] calldata amounts) external {
require(recipients.length == amounts.length, “Recipients and amounts must match in length”);
for (uint i = 0; i < recipients.length; i++) {
require(token.transfer(recipients[i], amounts[i]), “Transfer failed”);
}
}
}
Explanation of Gas Optimization Techniques:
Loop Optimization: The batchTransfer function allows for multiple transfers in a single transaction, reducing the overhead associated with transaction initiation. By consolidating transfers into one transaction, gas costs per transfer are minimized.
Interface Usage: The contract uses an interface (IERC20) to interact with an ERC20 token contract, which is a common standard for fungible tokens on Ethereum. This approach is efficient because it reduces the bytecode size of the contract and leverages the already deployed and optimized code of the token contract.
Error Handling: The contract uses require statements to ensure that the array lengths match and that each transfer is successful. This prevents unnecessary gas expenditure on failed transactions or invalid data.
Data Location Optimization: The function uses calldata for the recipients and amounts arrays, which is a cheaper form of memory because it is read-only and does not require additional gas for memory allocation as it would with memory data location.
Benefits of the Implemented Approach:
Reduced Transaction Costs: By executing multiple operations in a single transaction, the batch transfer function significantly cuts down the cumulative transaction fees.
Enhanced Contract Efficiency: The contract is designed to handle bulk operations efficiently, making it highly suitable for applications that require the distribution of tokens to multiple addresses, such as airdrops or payment distributions.
Conclusion of Section 3.3:
This practical example showcases how adopting gas optimization techniques can profoundly impact the efficiency and effectiveness of Ethereum smart contracts. Developers are encouraged to integrate similar strategies in their projects to minimize gas costs and enhance performance, thereby improving the overall user experience and scalability of their applications.
Conclusion:
The mastery of gas and its associated costs is not merely a technical requirement but a strategic competency essential for the effective deployment of blockchain applications. This thesis provides a detailed framework that developers can utilize to enhance their applications’ operational efficiency and economic viability.
Future Work:
Continued advancements in Ethereum, such as the transition to Ethereum 2.0, suggest that the dynamics of gas and fees will evolve. Future research should focus on adapting optimization strategies to these changes, ensuring that developers can maintain efficiency in a shifting technological landscape.
References
- Ethereum Foundation. (n.d.). Solidity Documentation: Gas and Gas Fees. Retrieved from https://docs.soliditylang.org/en/v0.8.0/internals/gas_and_fees.html
- ConsenSys. (2021). Ethereum Gas and Fees. Retrieved from https://consensys.net/knowledge-base/ethereum-101/gas/
- OpenZeppelin. (n.d.). OpenZeppelin Contracts. Retrieved from https://docs.openzeppelin.com/contracts/4.x/
- Trail of Bits. (2019). Smart Contract Security Guidance. Retrieved from https://blog.trailofbits.com/2019/07/09/smart-contract-security-guidance/
- Nomic Foundation. (n.d.). Hardhat: Ethereum Development Environment. Retrieved from https://hardhat.org/
- PeckShield. (2020). The Comprehensive Ethereum Smart Contract Security Best Practices. Retrieved from https://peckshield.medium.com/the-comprehensive-ethereum-smart-contract-security-best-practices-8c173f4eeb0e
- DASP. (n.d.). Decentralized Application Security Project (DASP) Top 10. Retrieved from https://dasp.co/
- Medium. (2020). Understanding Ethereum Gas Fees. Retrieved from https://medium.com/@coinmonks/understanding-ethereum-gas-fees-40c1ee56b7a2