The primary distinction between Acala EVM+ and the legacy EVM lies in the usage of encoded
gasLimit, together referred to as "gas parameters".
Acala EVM+ operates on a substrate chain. Consequently, the gas parameters must encode four substrate parameters:
tip. It's crucial to supply precise
gasLimitvalues to ensure accurate decoding into substrate parameters. Arbitrary changes to these parameters could lead to incorrect decoding.
For instance, when a user sends a transaction with the following gas parameters:
gasPrice: 100.004623375 gwei,
These parameters are decoded into substrate parameters as follows:
Despite being inconsistent with the legacy EVM, this aspect is advantageous for Acala EVM+. It utilizes features unavailable in the legacy EVM. For example, the
validUntilparameter prevents transactions from indefinitely lingering in the transaction pool. Additionally, the
storageLimitencourages developers to remove redundant data from the chain, thereby reducing chain bloat.
Users are not required to calculate gas parameters:
- When sending tokens, MetaMask automatically retrieves the correct gas parameters by calling ETH RPC endpoints.
- During transaction signing, dApps provide the correct gas parameters to MetaMask, enabling users to sign a valid transaction.
However, users should avoid arbitrary modification of transaction parameters within MetaMask, as it could lead to transaction failure due to incorrect decoding. We recommend highlighting this warning within your dApp's user interface.
Most tools and libraries (like
truffle) automatically calculate the correct gas parameters when sending a transaction. Developers typically do not need to intervene.
If gas parameters are not auto-computed, developers can calculate them as follows:
const gasPrice = await provider.getGasPrice();
const gasLimit = await contractInstance.estimateGas.functionName(...args);
Assume the Ethereum gasLimit is encoded as
aaaabbbccand gasPrice is encoded as
100yyyyyyyyy. They can be decoded into substrate gas parameters as follows:
validUntil = yyyyyyyyy
gasLimit = 30000 * bbb
storageLimit = 2^min(21, cc)
gasPrice: 100004623375, // 100yyyyyyyyy, where yyyyyyyyy = 004623375
gasLimit: 100106, // aaaabbbcc, where bbb = 001 and cc = 06
will be decoded as
validUntil: 4623375, // yyyyyyyyy
gasLimit: 30000, // 30000 * bbb = 30000 * 1 = 30000
storageLimit: 64, // 2 ^ min(21, cc) = 2 ^ 6 = 64
gasLimitremains unaffected by the tip, as the tip is encoded into
tip = (ab0 / 100 - 1)% of the original cost
gasPrice: 120004623375, // ab0yyyyyyyyy, where ab0 = 120
gasLimit: 100106, // same as above
will be decoded as
validUntil: 4623375, // same as above
gasLimit: 30000, // same as above
storageLimit: 64, // same as above
tip: 20%, // ab0 / 100 - 1 = 120 / 100 - 1 = 20%
Users generally should avoid manually modifying gas parameters to prevent incorrect decoding. dApps should initiate signature requests with valid gas parameters, relieving users of any concern about gas calculation. Nonetheless, knowledgeable users can manually modify the
ab0part of the gasPrice to increase the tip, which can expedite the transaction when the network is busy.
Developers can offer different priority options to users and compute the corresponding
gasPrice, eliminating the need for users to manually modify gas parameters. For instance:
- default priority:
ab0 = 100, in which case gasPrice is calculated automatically by the toolings
- high priority:
ab0 = 120, in which case tip = 20% of the original cost
- super high priority:
ab0 = 200, in which case tip = 100% of the original cost
If developers choose not to offer such options, they can use the default gasPrice directly.
When prompting user signatures, developers should also calculate a valid gasLimit. Most often, the tools should auto-calculate the gasLimit. If not, developers can hardcode a valid gasLimit (a rare occurrence, but if it happens, please report to the Acala team). For example, if an auto-calculated
gasLimit = 100106fails the transaction with an error like
storage limit not enough, it implies the transaction requires more storage than the auto-computed storageLimit =
2 ^ 6 = 64. If the actual storage cost is
100, developers can use
cc = 7, making
gasLimit = 100107.