This article traces the journey of a DAI transaction from initiation to confirmation, examining how wallets construct transaction data, set gas fees, sign transactions, and how nodes validate and execute the corresponding Solidity bytecode.
Author: tincho
Translation: Chainlink Translation Team
Proofreading: Tiny Bear
Transaction Construction
When you send 1 DAI to Vitalik's address (0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045) via MetaMask, your wallet constructs a transaction object:
{
"to": "0x6b175474e89094c44da98b954eedeac495271d0f", // DAI contract address
"amount": 0,
"chainId": 1, // Mainnet
"nonce": 0,
"data": "0xa9059cbb000000000000000000000000d8da6bf26964af9d7eed9e03e53415d37aa960450000000000000000000000000000000000000000000000000de0b6b3a7640000"
}Key Components:
- Recipient Address: The DAI smart contract (not Vitalik's address directly)
- Value: 0 ETH (since we're sending ERC-20 tokens)
Data Field: ABI-encoded
transfer(address,uint256)call with:- Recipient: Vitalik's address
- Amount: 1 DAI (1000000000000000000 wei)
Gas Fee Calculation
Wallets determine optimal gas fees by:
- Querying nodes via JSON-RPC (
eth_feeHistory) - Using third-party services like Infura/Alchemy
- Simulating transactions via
eth_estimateGas
The finalized transaction includes:
{
"maxPriorityFeePerGas": 2 Gwei,
"maxFeePerGas": 120 Gwei,
"gasLimit": 40000
}Transaction Signing
Using ECDSA with your private key, the wallet:
- Computes the transaction hash
- Generates signature values (v, r, s)
- Serializes the signed transaction via RLP encoding
Node Processing
Upon receiving the transaction via eth_sendRawTransaction, nodes:
- Deserialize and validate the transaction
- Verify ECDSA signatures
- Check gas fees against network conditions
- Add to mempool (if valid)
Execution Phase
When mined, the EVM:
- Initializes execution environment
- Validates calldata (minimum 4 bytes for function selector)
- Matches the function selector (
0xa9059cbb) to DAI'stransferfunction Executes in stages:
- Verifies sender balance
- Updates sender/receiver balances via
SSTORE - Emits
Transferevent (LOG3 opcode) - Returns success status
Key EVM Operations
| Opcode | Purpose |
|---|---|
CALLDATALOAD | Read calldata |
SLOAD | Read storage |
SSTORE | Update balances |
LOG3 | Emit event |
RETURN | End execution |
Transaction Receipt
Successful execution produces a receipt with:
{
"status": 1,
"gasUsed": 34706,
"logs": [{
"topics": [
"0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"0x000000000000000000000000[YOUR_ADDRESS]",
"0x000000000000000000000000[VITALIK_ADDRESS]"
],
"data": "0x0000000000000000000000000000000000000000000000000de0b6b3a7640000"
}]
}FAQs
Why does the transaction target the DAI contract instead of Vitalik's address?
ERC-20 transfers require interacting with the token contract to update internal balance mappings.
How is 1 DAI represented in the data field?
As 1000000000000000000 wei (18 decimal places), encoded as 0x0de0b6b3a7640000.
What prevents transaction replay attacks?
The chainId and nonce fields ensure transactions are only valid on specified networks and in sequence.
Why do wallets estimate gas before sending?
To prevent failed transactions and calculate appropriate fees based on network congestion.
For deeper exploration of EVM mechanics, check out EVM opcode references.
๐ Understanding Ethereum Gas Fees
๐ ERC-20 Token Standards Explained
This concludes our 5,000+ word journey through the technical stack powering a simple DAI transfer. The Ethereum blockchain combines cryptography, economics, and distributed systems to enable secure value transfer without intermediaries.