> ## 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.

# Decode Contract Logs

> Parse and decode ERC-20 Transfer and Approval events

Parse and decode ERC-20 Transfer and Approval events from raw log data.

```typescript theme={null}
import { Abi } from '@tevm/voltaire/Abi';
import { Hex } from '@tevm/voltaire/Hex';
import { EventLog } from '@tevm/voltaire/EventLog';

// Define ERC-20 event ABI
const erc20Abi = Abi([
  {
    type: "event",
    name: "Transfer",
    inputs: [
      { type: "address", name: "from", indexed: true },
      { type: "address", name: "to", indexed: true },
      { type: "uint256", name: "value", indexed: false }
    ]
  },
  {
    type: "event",
    name: "Approval",
    inputs: [
      { type: "address", name: "owner", indexed: true },
      { type: "address", name: "spender", indexed: true },
      { type: "uint256", name: "value", indexed: false }
    ]
  }
]);

// Raw log from eth_getLogs
// Transfer event: 100 tokens from 0x742d... to 0xa1b2...
const rawLog = {
  data: "0x0000000000000000000000000000000000000000000000000000000000000064",
  topics: [
    // topic0: keccak256("Transfer(address,address,uint256)")
    "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
    // topic1: indexed 'from' address (padded to 32 bytes)
    "0x000000000000000000000000742d35cc6634c0532925a3b844bc9e7595f251e3",
    // topic2: indexed 'to' address (padded to 32 bytes)
    "0x000000000000000000000000a1b2c3d4e5f6789012345678901234567890abcd"
  ]
};

// Decode the log using the ABI
const decoded = Abi.parseLogs(erc20Abi, [rawLog]);

// Result: [{ event: "Transfer", params: { from, to, value: 100n } }]
const { event, params } = decoded[0];
const { from, to, value } = params;
```

## How Event Logs Work

* **topic0**: Event signature hash (keccak256 of event signature)
* **topic1-3**: Indexed parameters (max 3, each 32 bytes)
* **data**: Non-indexed parameters (ABI encoded)

```typescript theme={null}
// Get event selector (topic0)
const transferEvent = erc20Abi.getEvent("Transfer");
const selector = Abi.Event.getSelector(transferEvent);
// 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef

// Match logs by comparing topic0
function isTransferLog(log) {
  const topic0 = Hex.toBytes(log.topics[0]);
  for (let i = 0; i < 32; i++) {
    if (topic0[i] !== selector[i]) return false;
  }
  return true;
}
```

<Tip>
  This is a fully executable example. View the complete source with test assertions at [`examples/contracts/decode-logs.ts`](https://github.com/evmts/voltaire/blob/main/examples/contracts/decode-logs.ts).
</Tip>

## Related

* [API Reference](/primitives)
* [More Examples](/examples)
