โ๏ธGas Saving Technique 42: `require` vs`assert`
Introduction
Ethereum smart contracts operate in a gas-limited environment. Every operation, from simple arithmetic to interacting with the contract's storage, consumes a certain amount of gas. Given the cost associated with gas, optimizing its use is paramount. A nuanced understanding of how different statements and functions consume gas is crucial. Among such, the utilization of assert()
and require()
in error handling and conditional checks plays a significant role. This tutorial delves deep into these two functions, focusing on their implications concerning gas usage.
Understanding assert()
and require()
assert()
and require()
assert()
assert()
Usage:
assert()
is used for internal error checking and verifying invariants in a contract.Gas Consumption: When an
assert()
statement fails, it consumes all remaining gas in the transaction.Common Scenarios: Itโs typically used to check conditions that should never fail unless there's a bug in the contract.
require()
require()
Usage:
require()
is primarily used for input validation and pre-condition checks.Gas Consumption: Unlike
assert()
,require()
refunds the remaining gas when a condition is not met.Common Scenarios: Commonly used to validate user inputs and ensure that conditions are met before executing certain logic.
Optimizing Gas with require()
require()
Since require()
refunds unused gas, itโs the more gas-efficient option for error handling in most cases. Developers should lean towards using require()
for condition checks and validations that could fail due to external inputs or incorrect parameters. This approach not only makes debugging easier but also makes the contract more gas-efficient, as users are refunded for the unused gas in case of failure.
Example
In this example, require()
is used to validate the input, ensuring that the storedData
is always a positive number. This is a condition that depends on external input and could commonly fail, making require()
the optimal choice due to its gas refund capability.
Best Practices
Prefer
require()
for Conditions Dependent on External Inputs: Since these conditions are more likely to fail, usingrequire()
will be more gas-efficient due to its refund capability.Use
assert()
for Internal Invariants:assert()
should be used for conditions that are internal invariants, as their failure indicates a bug in the contract.
Conclusion
Understanding the gas implications of assert()
and require()
is fundamental for writing efficient and cost-effective Solidity code. By strategically using these functions based on the likelihood of condition failure and the nature of the checks, developers can optimize gas usage, resulting in more efficient contract execution and a better user experience.
Last updated