Skip to main content

Try it Live

Run Transaction examples in the interactive playground

EIP-4844 Transactions

Blob transactions for L2 data availability, introduced in Dencun hard fork.

Overview

EIP-4844 transactions (Type 3) attach large data blobs for L2 rollup data availability. Blobs are pruned after ~18 days but provide cheaper data storage than calldata.

Type Definition

type EIP4844 = {
  type: Type.EIP4844      // 0x03
  chainId: bigint
  nonce: bigint
  maxPriorityFeePerGas: bigint
  maxFeePerGas: bigint
  gasLimit: bigint
  to: AddressType      // Cannot be null
  value: bigint
  data: Uint8Array
  accessList: AccessList
  maxFeePerBlobGas: bigint        // Max fee per blob gas
  blobVersionedHashes: readonly VersionedHash[]  // KZG commitments
  yParity: number
  r: Uint8Array
  s: Uint8Array
}
Source: types.ts:111-130

Creating EIP-4844 Transactions

import * as Transaction from 'tevm/Transaction'

const tx: Transaction.EIP4844 = {
  type: Transaction.Type.EIP4844,
  chainId: 1n,
  nonce: 0n,
  maxPriorityFeePerGas: 1000000000n,
  maxFeePerGas: 20000000000n,
  gasLimit: 100000n,
  to: contractAddress,  // Cannot be null
  value: 0n,
  data: new Uint8Array(),
  accessList: [],
  maxFeePerBlobGas: 2000000000n,  // 2 gwei per blob gas
  blobVersionedHashes: [hash1, hash2],  // 2 blobs
  yParity: 0,
  r: signatureR,
  s: signatureS,
}

Blob Basics

Blob Size

  • Each blob: 128 KB (131,072 bytes)
  • Maximum: 6 blobs per transaction
  • Blob data stored separately from transaction

Blob Gas

  • Fixed: 131,072 gas per blob
  • Total blob gas = blob_count × 131,072

Versioned Hashes

Blob commitments using KZG (Kate-Zaverucha-Goldberg):
type VersionedHash = HashType  // 32 bytes

// Format: version_byte || commitment_hash
// Currently: 0x01 || sha256(kzg_commitment)[1:]

getBlobGasCost

Calculate total blob gas cost.
function getBlobGasCost(
  tx: BrandedTransactionEIP4844,
  blobBaseFee: bigint
): bigint

Usage

import { EIP4844 } from 'tevm/Transaction'

const tx: Transaction.EIP4844 = {
  blobVersionedHashes: [hash1, hash2, hash3],  // 3 blobs
  // ...
}

const blobBaseFee = 1n  // From block header
const blobCost = EIP4844.getBlobGasCost(tx, blobBaseFee)
// 3 * 131072 * 1 = 393216
Formula:
blobGasCost = blobCount × 131072 × blobBaseFee
Source: EIP4844/getBlobGasCost.js:13-18

Total Cost

// Execution gas cost
const executionCost = effectiveGasPrice × gasUsed

// Blob gas cost
const blobCost = blobCount × 131072 × blobBaseFee

// Total
const totalCost = executionCost + blobCost + value
Example:
const tx: Transaction.EIP4844 = {
  maxFeePerGas: 20n,
  maxPriorityFeePerGas: 2n,
  gasLimit: 100000n,
  maxFeePerBlobGas: 10n,
  blobVersionedHashes: [hash1, hash2],  // 2 blobs
  value: 0n,
  // ...
}

// Assume
const baseFee = 15n
const blobBaseFee = 5n
const gasUsed = 80000n

// Execution cost
const effectiveGasPrice = 15n + 2n  // baseFee + priority
const executionCost = 17n × 80000n  // 1,360,000

// Blob cost
const blobCost = 2 × 131072n × 5n  // 1,310,720

// Total
const total = 1360000n + 1310720n + 0n  // 2,670,720

Blob Base Fee

Blob base fee adjusts independently from execution base fee:
// Separate fee markets
executionBaseFee  // For regular gas (EIP-1559)
blobBaseFee       // For blob gas (EIP-4844)

// Each adjusts based on its own usage
Target: 3 blobs per block
  • < 3 blobs: blob base fee decreases
  • > 3 blobs: blob base fee increases

getEffectiveGasPrice

EIP-4844 uses same execution gas pricing as EIP-1559:
import { EIP4844 } from 'tevm/Transaction'

const executionPrice = EIP4844.getEffectiveGasPrice(tx, baseFee)
// Same calculation as EIP1559.getEffectiveGasPrice

Methods

import { EIP4844 } from 'tevm/Transaction'

// Serialization
const bytes = EIP4844.serialize(eip4844Tx)
const decoded = EIP4844.deserialize(bytes)

// Hashing
const txHash = EIP4844.hash(eip4844Tx)
const signingHash = EIP4844.getSigningHash(eip4844Tx)

// Signing
const sender = EIP4844.getSender(eip4844Tx)
const isValid = EIP4844.verifySignature(eip4844Tx)

// Gas calculations
const executionPrice = EIP4844.getEffectiveGasPrice(eip4844Tx, baseFee)
const blobCost = EIP4844.getBlobGasCost(eip4844Tx, blobBaseFee)

Blob Data

Blob data is NOT included in transaction:
// Transaction contains only commitments
{
  type: 0x03,
  // ...
  blobVersionedHashes: [hash1, hash2],  // KZG commitments
  // ...
}

// Actual blob data transmitted separately
// Network format: TransactionPayloadBody
// {
//   blobs: [blob1, blob2],
//   commitments: [commitment1, commitment2],
//   proofs: [proof1, proof2]
// }

RLP Encoding

0x03 || rlp([chainId, nonce, maxPriorityFeePerGas, maxFeePerGas, gasLimit, to, value, data, accessList, maxFeePerBlobGas, blobVersionedHashes, yParity, r, s])
Blob data transmitted separately in network layer.

Use Cases

  1. L2 Rollups - Post transaction data for data availability
  2. Data availability - Cheaper than calldata
  3. Temporary storage - Data pruned after ~18 days

Limitations

  1. No contract creation - to cannot be null
  2. Pruning - Blobs deleted after ~18 days
  3. Size limit - Maximum 6 blobs (768 KB)
  4. Network support - Requires Dencun hard fork

Cost Comparison

MethodCost (per byte)PersistentUse Case
calldata~16 gasForeverPermanent data
Blobs~1 gas~18 daysL2 rollup data
Storage~20,000 gasForeverContract state
Blobs are ~16x cheaper than calldata for temporary data.

When to Use

Use EIP-4844 for:
  • L2 rollup data availability
  • Temporary large data (< 768 KB)
  • Cost optimization for data posting
Use calldata for:
  • Permanent data needed
  • Data < 10 KB
  • Pre-Dencun networks

EIP Reference