> ## Documentation Index
> Fetch the complete documentation index at: https://voltaire.tevm.sh/llms.txt
> Use this file to discover all available pages before exploring further.

# Transaction.getAccessList

> Extract access list from transaction

<Card title="Try it Live" icon="play" href="https://playground.tevm.sh?example=primitives/transaction.ts">
  Run Transaction examples in the interactive playground
</Card>

# getAccessList

Extract access list from transaction.

## Access List Structure

```typescript theme={null}
type AccessList = readonly Item[]

type Item = {
  address: AddressType       // 20-byte contract address
  storageKeys: readonly Hash[]  // 32-byte storage slot keys
}
```

## Transaction Types

| Type            | Access List Support     |
| --------------- | ----------------------- |
| Legacy (0x00)   | Returns `[]`            |
| EIP-2930 (0x01) | Returns `tx.accessList` |
| EIP-1559 (0x02) | Returns `tx.accessList` |
| EIP-4844 (0x03) | Returns `tx.accessList` |
| EIP-7702 (0x04) | Returns `tx.accessList` |

## Usage Patterns

### Pre-warming Storage

```typescript theme={null}
import { getAccessList } from 'tevm/Transaction'

async function prewarmStorage(tx: Transaction.Any) {
  const accessList = getAccessList(tx)

  for (const item of accessList) {
    // Mark address as warm (2600 gas vs 100 gas)
    await markAddressWarm(item.address)

    // Mark storage slots as warm (2100 gas vs 100 gas)
    for (const key of item.storageKeys) {
      await markStorageWarm(item.address, key)
    }
  }
}
```

### Gas Cost Calculation

```typescript theme={null}
import { getAccessList } from 'tevm/Transaction'

function calculateAccessListGasCost(tx: Transaction.Any): bigint {
  const accessList = getAccessList(tx)

  let cost = 0n

  for (const item of accessList) {
    cost += 2400n  // Per address (TU_DATA + TU_ACCESS_LIST_ADDRESS_COST)

    for (const _ of item.storageKeys) {
      cost += 1900n  // Per storage key (TU_ACCESS_LIST_STORAGE_KEY_COST)
    }
  }

  return cost
}

// Usage
const accessListCost = calculateAccessListGasCost(tx)
console.log(`Access list adds ${accessListCost} gas`)
```

### Access List Analysis

```typescript theme={null}
import { getAccessList } from 'tevm/Transaction'

function analyzeAccessList(tx: Transaction.Any) {
  const accessList = getAccessList(tx)

  const uniqueAddresses = new Set(
    accessList.map(item => Address.toHex(item.address))
  )

  const totalStorageKeys = accessList.reduce(
    (sum, item) => sum + item.storageKeys.length,
    0
  )

  return {
    addressCount: uniqueAddresses.size,
    storageKeyCount: totalStorageKeys,
    isEmpty: accessList.length === 0,
    gasCost: calculateAccessListGasCost(tx)
  }
}
```

### Merging Access Lists

```typescript theme={null}
import { getAccessList } from 'tevm/Transaction'
import * as AccessList from 'tevm/AccessList'

function mergeTransactionAccessLists(
  transactions: Transaction.Any[]
): AccessList.AccessList {
  const lists = transactions.map(getAccessList)
  return AccessList.merge(...lists)
}

// Usage
const merged = mergeTransactionAccessLists([tx1, tx2, tx3])
```

### Validation

```typescript theme={null}
import { getAccessList } from 'tevm/Transaction'

function validateAccessList(tx: Transaction.Any): boolean {
  const accessList = getAccessList(tx)

  for (const item of accessList) {
    // Check address is valid
    if (item.address.length !== 20) {
      return false
    }

    // Check storage keys are valid
    for (const key of item.storageKeys) {
      if (key.length !== 32) {
        return false
      }
    }

    // Check for duplicates
    const uniqueKeys = new Set(item.storageKeys.map(k => Hash.toHex(k)))
    if (uniqueKeys.size !== item.storageKeys.length) {
      return false  // Duplicate storage keys
    }
  }

  return true
}
```

### Building Access Lists

```typescript theme={null}
import { getAccessList } from 'tevm/Transaction'
import * as AccessList from 'tevm/AccessList'

function buildOptimalAccessList(
  existingTx: Transaction.Any,
  additionalAddresses: AddressType[]
): AccessList.AccessList {
  // Start with existing access list
  let list = getAccessList(existingTx)

  // Add additional addresses
  for (const addr of additionalAddresses) {
    list = AccessList.withAddress(list, addr)
  }

  // Remove duplicates and optimize
  return AccessList.deduplicate(list)
}
```

## Gas Savings

Access lists pre-declare storage access to save gas:

```typescript theme={null}
// Without access list
const coldAddressAccess = 2600n  // COLD_ACCOUNT_ACCESS_COST
const coldStorageAccess = 2100n  // COLD_SLOAD_COST

// With access list
const accessListAddress = 2400n      // Per address in list
const accessListStorage = 1900n      // Per storage key in list
const warmAddressAccess = 100n       // WARM_STORAGE_READ_COST
const warmStorageAccess = 100n       // WARM_STORAGE_READ_COST

// Net savings per access (if accessed multiple times)
const addressSavings = coldAddressAccess - (accessListAddress + warmAddressAccess)
// = 2600 - (2400 + 100) = 100 gas

const storageSavings = coldStorageAccess - (accessListStorage + warmStorageAccess)
// = 2100 - (1900 + 100) = 100 gas
```

Access lists are beneficial when addresses/slots accessed 2+ times.

## See Also

* [hasAccessList](/primitives/transaction/has-access-list) - Check if transaction has access list
* [AccessList](/primitives/accesslist) - Access list primitive and utilities
* [GasConstants](/primitives/gasconstants) - Gas cost constants
* [EIP-2930](/primitives/transaction/eip2930) - Access list transaction type

## References

* [EIP-2930: Optional access lists](https://eips.ethereum.org/EIPS/eip-2930)
* [EIP-2929: Gas cost increases for state access opcodes](https://eips.ethereum.org/EIPS/eip-2929)
* [Ethereum Yellow Paper](https://ethereum.github.io/yellowpaper/paper.pdf) - Gas costs
