A transaction refers to an action initiated by an account which changes the state of the blockchain. To effectively perform the state change, every transaction is broadcasted to the whole network. Any node can broadcast a request for a transaction to be executed on the blockchain state machine; after this happens, a validator will validate, execute the transaction and propagate the resulting state change to the rest of the network.
To process every transaction, computation resources on the network are consumed. Thus, the concept of "gas" arises as a reference to the computation required to process the transaction by a validator. Users have to pay a fee for this computation, all transactions require an associated fee. This fee is calculated based on the gas required to execute the transaction and the gas price.
Additionally, a transaction needs to be signed using the sender's private key. This proves that the transaction could only have come from the sender and was not sent fraudulently.
In a nutshell, the transaction lifecycle once a signed transaction is submitted to the network is the following:
- A transaction hash is cryptographically generated.
- The transaction is broadcasted to the network and added to a transaction pool consisting of all other pending network transactions.
- A validator must pick your transaction and include it in a block in order to verify the transaction and consider it "successful".
The transaction hash is a unique identifier and can be used to check transaction information, for example, the events emitted, if was successful or not.
Transactions can fail for various reasons. For example, the provided gas or fees may be insufficient. Also, the transaction validation may fail. Each transaction has specific conditions that must fullfil to be considered valid. A widespread validation is that the sender is the transaction signer. In such a case, if you send a transaction where the sender address is different than the signer's address, the transation will fail, even if the fees are sufficient.
Ethereum transactions refer to actions initiated by EOAs (externally-owned accounts, managed by humans), rather than internal smart contract calls. Ethereum transactions transform the state of the EVM and therefore must be broadcasted to the entire network.
Ethereum transactions also require a fee, known as gas. (EIP-1559) (opens in a new tab) introduced the idea of a base fee, along with a priority fee which serves as an incentive for miners to include specific transactions in blocks.
There are several categories of Ethereum transactions:
- regular transactions: transactions from one account to another
- contract deployment transactions: transactions without a to address, where the contract code is sent in the data field
- execution of a contract: transactions that interact with a deployed smart contract, where the to address is the smart contract address
An Ethereum transaction includes the following information:
recipient: receiving address
signature: sender's signature
nonce: counter of tx number from account
value: amount of ETH to transfer (in wei)
data: includes arbitrary data. Used when deploying a smart contract or making a smart contract method call
gasLimit: max amount of gas to be consumed
maxPriorityFeePerGas: max gas to be included as tip to validators
maxFeePerGas: max amount of gas to be paid for the transaction
Areon supports the following Ethereum transactions.
- Dynamic Fee Transactions (EIP-1559 (opens in a new tab))
- Access List Transactions (EIP-2930 (opens in a new tab))
- Legacy Transactions (EIP-2718 (opens in a new tab))
Areon is capable of processing Ethereum transactions by wrapping them on a message. This message encapsulates an Ethereum transaction as an message and contains the necessary transaction data fields.
There are three types of transaction types used from Ethereum Improvement Proposals (EIPs):
LegacyTxType (EIP-155): The LegacyTxType represents the original transaction format that existed before Ethereum Improvement Proposal (EIP) 155. These transactions do not include a chain ID, which makes them vulnerable to replay attacks. EIP-155 was introduced to solve this problem by incorporating a chain ID, which uniquely identifies a specific Ethereum chain to prevent cross-chain replay attacks.
AccessListTxType (EIP-2930): AccessListTxType was introduced with EIP-2930 as part of the Berlin upgrade. This new transaction type allows users to specify an access list – a list of addresses and storage keys that the transaction plans to access. The primary goal of access lists is to mitigate some of the gas cost increases introduced with EIP-2929, which increased gas costs for state access operations to improve denial-of-service (DoS) attack resistance. By specifying an access list, users can avoid paying higher gas costs for subsequent accesses to the same addresses and storage keys within the same transaction.
DynamicFeeTxType (EIP-1559): DynamicFeeTxType was introduced with EIP-1559 as part of the London upgrade. This transaction type brought significant changes to Ethereum's fee market, with the aim of making gas fees more predictable and improving user experience. EIP-1559 transactions include two main components: a base fee and a priority fee (or tip). The base fee is algorithmically determined by the network, while the priority fee is set by users to incentivize miners to include their transaction. The base fee is burned, effectively reducing the overall ETH supply, while the priority fee goes to miners as a reward for their work. DynamicFeeTxType transactions allow for more predictable and efficient gas fee management. A transaction receipt shows data returned by an Ethereum client to represent the result of a particular transaction, including a hash of the transaction, its block number, the amount of gas used, and, in case of deployment of a smart contract, the address of the contract. Additionally, it includes custom information from the events emitted in the smart contract.
These transaction types represent Ethereum's continuous evolution and improvements to its network, helping address challenges related to scalability, security, and user experience.
A receipt contains the following information:
transactionHash: hash of the transaction
transactionIndex: integer of the transactions index position in the block
blockHash: hash of the block where this transaction was in.
blockNumber: block number where this transaction was in.
from: sender address
to: receiver address (
nullwhen its a contract creation transaction)
cumulativeGasUsed: The total amount of gas used when this transaction was executed in the block.
effectiveGasPrice: The sum of the base fee and tip paid per unit of gas.
gasUsed: The amount of gas used by this specific transaction alone.
contractAddress: The contract address created, if the transaction was a contract creation, otherwise
logs: Array of log objects, which this transaction generated
logsBloom: Bloom filter for light clients to quickly retrieve related logs.
type: integer of the transaction type, 0x00 for legacy transactions, 0x01 for access list types, 0x02 for dynamic fees. It also returns either
root: transaction stateroot (pre Byzantium)
status: either 1 (success) or 0 (failure)