Explain it simply
Twelve questions a committee might ask — with crisp, honest answers. Read them aloud until they feel natural.
1What is this project, in one sentence?tap to revealhide
A demo cryptocurrency exchange where users create wallets in the browser, receive test coins from a faucet, send them over a small proof-of-stake blockchain, and trade them on an order book — all powered by a single Rust backend and a PostgreSQL database.
2Why did you build your own blockchain instead of using one?tap to revealhide
The goal was to learn the cryptography and consensus mechanics from first principles. Building a minimal chain (blocks, hashes, Merkle roots, stake-weighted proposers) makes every concept concrete. We reuse standard crypto libraries (ed25519, SHA-256) but implement the chain logic ourselves.
3What is proof of stake, and how is it implemented here?tap to revealhide
Proof of stake ties block-production rights to the coins you lock up. Here it's a deterministic lottery: sha256('proposer' + height + total stake) is turned into a number, and validators are chosen in proportion to their stake. Every node computes the same proposer for the same height, so there's no voting.
4How does signing in work without a password?tap to revealhide
Sign-in-with-wallet. The browser owns an ed25519 keypair. To log in, the server issues a random single-use challenge (valid 10 minutes), the browser signs it, and the server verifies both the signature and that the public key derives to the claimed address. Proven ownership earns a JWT.
5Why do keys never leave the browser?tap to revealhide
Self-custody. If the server held keys, users would have to trust us with their coins. By keeping the secret in the browser, the user signs every action themselves and only signatures travel to the server. The trade-off: losing the key means losing access forever — there's no password reset.
6How do you prevent double spending?tap to revealhide
Two layers. (1) The transaction nonce: each account has a counter, and a transaction must use the next nonce. After a transaction confirms, the nonce advances, so the same transaction can't be replayed. (2) Balance checks: validation enforces amount + fee ≤ balance, and within a block, running state catches two transactions from the same sender trying to overdraw.
7How does the order book work?tap to revealhide
It's a price → queue map. Bids and asks are sorted (BTreeMap), and each price level keeps a FIFO queue. When an order arrives it fills against the best opposite price while they cross, at the maker's price. What doesn't fill rests on the book. Market orders (bid price = i64::MAX, ask price = 0) always cross and never rest.
8What's the difference between on-chain and off-chain here?tap to revealhide
Wallet transfers, the faucet, and staking escrow are on-chain — signed transactions that go through the mempool and into blocks. Trading is off-chain — matching happens in memory and settlement writes directly to the balances table in one database transaction. Real exchanges do the same and batch-commit to the chain.
9How is everything stored?tap to revealhide
In PostgreSQL. There's no special blockchain file — blocks and transactions are rows in tables. The 'mempool' is just a status: pending transactions are rows with status='pending'. The in-memory order book is rebuilt from the orders table at boot. Postgres is the single source of truth.
10What's a nonce and why does it matter?tap to revealhide
A per-account counter that must match exactly for a transaction to be valid. After a transaction confirms, the nonce increments. It stops replay attacks (the same signed transaction being submitted twice) and forces transactions from one wallet to be sent in order.
11Why are amounts integers instead of floats?tap to revealhide
Floating-point arithmetic can introduce rounding errors — dangerous with money. All amounts are integer 'minor units' (1 XCH = 100,000,000 minor units). Both frontend and backend use integers, and the UI converts for display only.
12What would you improve if you had more time?tap to revealhide
Strong answers: (1) make block production a single atomic DB transaction; (2) add real P2P networking so multiple nodes actually talk; (3) move the rate limiter to Redis for horizontal scaling; (4) store the refresh token more securely and actually use it; (5) add foreign keys for extra integrity.