The Real User Flow: Registration to Withdrawal
A developer-level walkthrough of what happens at every step when a user interacts with a centralized exchange — from database writes to blockchain transactions.
In this guide
Step 1: Registration
What the user does: Enters email, password, and optionally a referral code.
What happens server-side:
1. Validate input, normalize email to lowercase.
2. Hash password with bcrypt (12 rounds).
3. Generate a random email verification token.
4. Generate a unique referral code for the new user.
5. Insert row into auth_users (is_verified=false).
6. If a referral code was provided, look up the referrer and insert into referrals table.
7. Send verification email with a clickable link.
Database state after registration:
- 1 row in auth_users (is_verified = false)
- 0 rows in balances (created on first deposit)
- 1 row in audit_log (action: 'register')
Binance: Requires phone number verification in addition to email. Runs device fingerprinting to detect bot accounts.
Coinbase: Creates a Coinbase Wallet (custodial) immediately upon registration, pre-generating deposit addresses for major assets.
Step 2: Login and Session Creation
What the user does: Enters email + password. If 2FA is enabled, enters TOTP code.
Server-side flow:
1. Lookup user by email in auth_users.
2. Verify password via bcrypt.compare().
3. If password fails → log login_failed in audit_log with IP and user-agent.
4. If 2FA is enabled → validate TOTP code (RFC 6238, 30-second window).
5. Issue a JWT access token (stateless session).
6. Insert row into login_sessions with IP, user-agent, parsed device/OS/browser.
7. Insert row into audit_log (action: 'login').
8. Check if IP is new for this user → if yes, send security notification.
Binance behavior: Sends email notification for every login. New IP/device triggers a verification email that must be confirmed within 10 minutes. Withdrawals are locked 24 hours from a new device.
Coinbase behavior: Uses device trust scoring combining fingerprint, IP reputation, and behavioral biometrics. Low-trust logins trigger additional verification (email, CAPTCHA, or support ticket).
Step 3: KYC Verification
What the user does: Uploads government ID (passport, driver's license) and sometimes a selfie.
Server-side flow:
1. Document image uploaded to encrypted blob storage (AWS S3 with SSE-KMS).
2. Row created in kyc_documents with status='pending'.
3. Document sent to a KYC provider API:
- Jumio (Binance) — OCR + facial recognition + liveness detection
- Onfido (Coinbase) — document verification + biometric check
- Sumsub — popular alternative for mid-tier exchanges
4. Provider returns verification result (approved/rejected with confidence score).
5. kyc_documents status updated; if approved, auth_users.kyc_level incremented.
KYC levels (Binance model): - Level 0 — No KYC. Can browse markets but cannot trade. - Level 1 — Basic verification (ID). Withdrawal limit: 2 BTC/day. - Level 2 — Advanced (ID + address proof). Limit: 100 BTC/day.
Storage requirements (GDPR): KYC documents are PII — encrypted at rest (AES-256), encrypted in transit (TLS 1.3), accessible only to authorized compliance personnel. Retention for AML compliance may override deletion requests for 5 years after account closure.
Step 4: Deposit
What the user does: Navigates to "Deposit BTC" and sees a QR code / address.
Server-side:
1. Exchange generates (or retrieves) a unique deposit address for this user+asset using an HD wallet (BIP-32/BIP-44).
2. Address is stored in deposit_addresses(user_id, asset, address, derivation_path).
3. User sends BTC from their external wallet.
On-chain: A real Bitcoin transaction is broadcast, publicly visible on any block explorer.
Exchange blockchain monitor flow:
``
Full node detects incoming TX to exchange address
→ Lookup deposit_addresses → find user_id
→ INSERT INTO deposits (status='pending')
→ Wait for 3 confirmations (BTC)
→ UPDATE deposits SET status='completed'
→ INSERT INTO ledger_entries (entry_type='deposit', amount=0.5)
→ UPDATE balances SET available = available + 0.5
→ INSERT INTO notifications (title='Deposit confirmed')
``
Fiat deposits (Coinbase): For ACH/SEPA, Coinbase uses banking partners (Cross River Bank). The transfer arrives in 1-3 business days. For instant deposits, Coinbase provides credit against the incoming transfer (up to $35K) at their risk.
Step 5: Trading
What the user does: Places a limit buy for 0.5 BTC at $65,000.
Matching engine flow:
``
1. ORDER RECEIVED: BUY 0.5 BTC @ $65,000 (limit)
2. VALIDATION: User has >= 32,500 USDT available → OK
3. BALANCE LOCK:
UPDATE balances SET available -= 32500, locked += 32500
INSERT ledger_entry (type='order_lock', amount=-32500)
4. INSERT INTO orders (status='open', remaining=0.5)
5. MATCHING: Scan sell side for price <= 65000
Found: SELL 0.3 BTC @ $64,800 from User Y
6. TRADE: INSERT INTO trades (price=64800, amount=0.3)
Credit buyer: +0.3 BTC (minus 0.1% fee)
Debit buyer: -19,440 USDT
Credit seller: +19,440 USDT (minus 0.1% fee)
Debit seller: -0.3 BTC
7. UPDATE orders SET filled=0.3, remaining=0.2,
status='partially_filled'
Remaining 0.2 stays on order book
``
None of this is on-chain. It is all in-memory matching + database persistence.
Binance: Java/C++ matching engine, up to 1.4M orders/sec. Price-time priority. Runs on dedicated bare-metal servers with nanosecond timestamps.
Coinbase: PostgreSQL-backed limit order book with FIFO matching. Simpler but highly reliable.
Step 6: Withdrawal
What the user does: Requests withdrawal of 0.3 BTC to an external address.
Server-side flow:
``
1. VALIDATION:
- balance >= 0.3 BTC, KYC level allows amount,
daily limit not exceeded, address on whitelist,
2FA code valid
2. RISK ENGINE:
- Score: amount, frequency, destination analysis
- Low risk → auto-approve
- High risk → queue for manual review
3. BALANCE LOCK:
- Debit: -0.3 BTC - 0.0005 BTC (fee)
- INSERT ledger_entry (type='withdrawal')
- INSERT withdrawals (status='pending')
4. HOT WALLET SIGNING:
- HSM or secure enclave signs the Bitcoin TX
- Transaction broadcast to blockchain
- UPDATE withdrawals SET tx_hash = 'abc123...'
5. BLOCKCHAIN CONFIRMATION:
- Monitor waits for confirmations
- UPDATE withdrawals SET status = 'completed'
- INSERT audit_log + notification
``
Binance signing: Multi-signature cold wallet with threshold signatures. Large withdrawals require M-of-N approval from signers in different physical locations. Keys stored in HSMs in geographically distributed secure facilities.
Coinbase Vault: Withdrawals require a 48-hour waiting period and multi-email approval. Institutional clients use Coinbase Custody with SOC 2 Type II compliance and $320M insurance.
Practice in a risk-free environment
Apply the concepts using virtual funds and live market data. NexChange is an educational simulation, not a real-money exchange.
Continue learning
Related guides
How Crypto Exchanges Store Every Operation
A deep technical dive into the database architecture of real crypto exchanges — how Binance and Coinbase track every deposit, trade, withdrawal, and audit event per user.
How Exchanges Track Login Sessions
Technical breakdown of how Binance and Coinbase record every login — IP address, device fingerprint, geolocation, and session lifecycle management.
On-Chain vs Off-Chain: Where Your Data Actually Lives
The critical difference between blockchain data and exchange database data — what is public, what is private, and how exchanges reconcile both worlds.