Transaction

A signed message that changes blockchain state, including token transfers, contract interactions, and deployments.

A transaction in Ethereum and EVM-compatible blockchains is a cryptographically signed instruction that modifies the blockchain state. Transactions can transfer native currency (ETH), interact with smart contracts, or deploy new contracts. Every transaction requires gas payment and must be signed by the sender's private key, providing authentication and non-repudiation. Understanding transaction mechanics is essential for building secure dApps and auditing smart contract interactions.

Transaction Structure

Every Ethereum transaction contains:

1{
2 nonce: 42, // Sender's transaction count
3 gasPrice: 20000000000, // Wei per gas unit (legacy)
4 gasLimit: 21000, // Maximum gas to use
5 to: "0x123...abc", // Recipient address
6 value: 1000000000000000000, // Wei to transfer (1 ETH)
7 data: "0x...", // Input data (for contract calls)
8 v: 28, // Recovery id
9 r: "0x...", // ECDSA signature part
10 s: "0x..." // ECDSA signature part
11}

EIP-1559 Transaction (Post-London)

1{
2 type: 2, // EIP-1559 transaction
3 chainId: 1, // Network ID
4 nonce: 42,
5 maxPriorityFeePerGas: 2000000000, // Tip to validator
6 maxFeePerGas: 100000000000, // Max total fee
7 gasLimit: 21000,
8 to: "0x123...abc",
9 value: 1000000000000000000,
10 data: "0x...",
11 accessList: [], // EIP-2930 access list
12 // Signature fields...
13}

Transaction Types

Simple Transfer

Sending ETH between accounts:

1const tx = {
2 to: recipientAddress,
3 value: ethers.parseEther("1.0"),
4 // No data field = simple transfer
5};
6await wallet.sendTransaction(tx);

Gas cost: 21,000 (fixed for simple transfers)

Contract Interaction

Calling a smart contract function:

1const tx = {
2 to: contractAddress,
3 value: 0,
4 data: contract.interface.encodeFunctionData("transfer", [
5 recipient,
6 amount
7 ])
8};
9await wallet.sendTransaction(tx);

Gas cost: 21,000 base + execution cost

Contract Deployment

Creating a new contract:

1const tx = {
2 to: null, // No recipient = deployment
3 data: bytecode + encodedConstructorArgs
4};
5const receipt = await wallet.sendTransaction(tx);
6const contractAddress = receipt.contractAddress;

Gas cost: 21,000 base + 32,000 creation + code storage

Transaction Lifecycle

11. Creation → Build transaction object
22. Signing → Sign with private key
33. Broadcasting → Send to network
44. Mempool → Wait in pending transactions
55. Inclusion → Validator includes in block
66. Execution → EVM processes transaction
77. Confirmation → Additional blocks mined

Nonce Management

The nonce prevents replay attacks and orders transactions:

1// Each account has incrementing nonce
2// Transaction with nonce 5 can't be mined before nonce 4
3
4// Get current nonce
5const nonce = await provider.getTransactionCount(address);
6
7// Send multiple transactions
8await wallet.sendTransaction({ ...tx1, nonce: nonce });
9await wallet.sendTransaction({ ...tx2, nonce: nonce + 1 });
10await wallet.sendTransaction({ ...tx3, nonce: nonce + 2 });

Nonce Issues

Gap: If nonce 5 is pending, nonces 6+ wait forever Duplicate: Same nonce replaces previous (if higher gas)

Transaction Security

Replay Protection

EIP-155 adds chainId to prevent cross-chain replay:

1// Transaction signed for chainId 1 (mainnet)
2// Invalid on chainId 137 (Polygon)

Front-Running

Transactions in mempool are visible; attackers can front-run:

1User submits: swap(tokenA, tokenB, minOut=90)
2Attacker sees in mempool
3Attacker front-runs: swap(tokenA, tokenB) with higher gas
4User's transaction gets worse price
5Attacker back-runs: swap(tokenB, tokenA) for profit

Protection: Use private mempools (Flashbots) or commit-reveal schemes.

Transaction Simulation

Preview outcomes before signing:

1// Simulate without sending
2const result = await provider.call({
3 to: contractAddress,
4 data: encodedFunctionCall
5});
6
7// Or use Tenderly/Alchemy simulation APIs

Transaction in Solidity

Accessing transaction data in contracts:

1contract Example {
2 function whoCalledMe() external view returns (
3 address sender,
4 address origin,
5 uint256 gasPrice,
6 uint256 value
7 ) {
8 sender = msg.sender; // Immediate caller
9 origin = tx.origin; // Original EOA (avoid using!)
10 gasPrice = tx.gasprice; // Gas price of transaction
11 value = msg.value; // ETH sent with call
12 }
13}

tx.origin vs msg.sender

1// DANGEROUS: tx.origin check
2function withdraw() external {
3 require(tx.origin == owner); // Phishable!
4}
5
6// SAFE: msg.sender check
7function withdraw() external {
8 require(msg.sender == owner);
9}

Transaction Fees

Legacy (Pre-EIP-1559)

1Fee = gasUsed × gasPrice

EIP-1559

1Fee = gasUsed × (baseFee + priorityFee)
2Base fee is burned, priority fee goes to validator

Fee Estimation

1// Get current fee data
2const feeData = await provider.getFeeData();
3
4const tx = {
5 maxFeePerGas: feeData.maxFeePerGas,
6 maxPriorityFeePerGas: feeData.maxPriorityFeePerGas,
7 // ...
8};

Failed Transactions

Transactions can fail but still cost gas:

1function riskyOperation() external {
2 require(condition, "Failed"); // If false, reverts
3 // Gas up to this point is consumed
4}

Revert vs Out-of-Gas

Revert: Logic failure, remaining gas refunded Out-of-Gas: All gas consumed, no refund

Audit Considerations

When auditing transaction handling:

  • No reliance on tx.origin for authorization
  • Proper nonce management in batch operations
  • Gas limits appropriate for operations
  • Front-running risks assessed
  • Replay protection where needed
  • Transaction simulation available for users

Transactions are the fundamental unit of blockchain interaction. Understanding their structure, lifecycle, and security implications is essential for building and auditing secure decentralized applications.

Need expert guidance on Transaction?

Our team at Zealynx has deep expertise in blockchain security and DeFi protocols. Whether you need an audit or consultation, we're here to help.

Get a Quote

oog
zealynx

Subscribe to Our Newsletter

Stay updated with our latest security insights and blog posts

© 2024 Zealynx