Axiomatic
Privacy & Confidential Transfers

Scan Tags

Efficient note filtering for recipient scanning

Scan Tags

Scan tags are 4-byte fingerprints that enable efficient server-side scanning of shielded notes without trial decryption.

Derivation

recipientX25519Pub (32 bytes)
  → keccak256(recipientX25519Pub)
  → first 4 bytes
  → scanTag (e.g., "0x1a2b3c4d")

On-Chain Usage

The NoteCreated event includes scanTag as an indexed parameter:

event NoteCreated(
    uint256 indexed commitment,
    uint256 leafIndex,
    bytes4 indexed scanTag,
    bytes32 ephemeralPubKey,
    bytes encryptedNote
);

This allows the Goldsky indexer to filter events by scan tag at the database level, and the scanning cron to query confidential_events with a simple WHERE clause.

Privacy Trade-off

AspectDetail
LinkabilityAll notes to the same recipient share the same scan tag
IdentityScan tags do not reveal the recipient's identity or public key
Collision~1 in 4 billion chance of two recipients sharing a tag
ReversibilityCannot derive the X25519 public key from a scan tag

The linkability trade-off is acceptable because the confidential ledger already associates notes with stealth addresses, which are per-recipient.

Server-Side Scanning

The scanning cron (/api/cron/scan-incoming-notes) uses scan tags to filter events:

SELECT * FROM confidential_events
WHERE scan_tag = $1
  AND id > $2  -- cursor
ORDER BY id ASC

This reduces the scanning workload from O(total_notes × wallets) to O(notes_per_wallet).

On this page