System Design শেখো
সব কেস স্টাডি

NFT Marketplace ডিজাইন

14 মিনিটintermediate
এক নজরে
  • NFT-র ownership ও token থাকে on-chain (smart contract), কিন্তু ছবি/metadata-র মতো ভারী জিনিস থাকে off-chain — সাধারণত IPFS বা CDN-এ।
  • Marketplace নিজে কয়েন রাখে না; কেনা-বেচা smart contract-এর মাধ্যমে হয়, আর wallet (যেমন MetaMask) দিয়ে user transaction sign করে।
  • দ্রুত browsing-এর জন্য blockchain event indexer দিয়ে on-chain data off-chain DB-তে index করা হয়, কারণ সরাসরি chain থেকে query করা ধীর।

আজকের কেস স্টাডি — "OpenSea-র মতো একটা NFT marketplace ডিজাইন করো।" এটা crypto exchange-এর চেয়ে সহজ, কারণ marketplace সাধারণত non-custodial — মানে আমরা user-এর কয়েন বা key রাখি না। আমরা শুধু একটা সুন্দর দোকান বানাই যেখানে মানুষ NFT browse করে, আর কেনা-বেচা হয় blockchain-এর smart contract দিয়ে।

সহজ উদাহরণ

ভাবো একটা আর্ট গ্যালারি যেখানে প্রতিটা ছবির নিচে একটা সরকারি দলিল (smart contract) আছে যা প্রমাণ করে এটা কার। গ্যালারি নিজে দলিল বদলায় না — দলিল রেজিস্ট্রি অফিসে (blockchain) আছে। গ্যালারি শুধু ছবিগুলো সুন্দর করে সাজিয়ে দেখায়, দাম লেখে, আর ক্রেতাকে রেজিস্ট্রি অফিসে নিয়ে গিয়ে মালিকানা বদলের ব্যবস্থা করে দেয়। ছবিগুলো (ভারী জিনিস) গুদামে (IPFS/CDN), আর মালিকানার দলিল রেজিস্ট্রিতে (on-chain)।

১. সমস্যা বোঝা (Requirements)

Functional requirements:

  • Minting: creator একটা NFT তৈরি করবে (smart contract-এ token mint)।
  • Listing: owner একটা NFT বিক্রির জন্য দাম দিয়ে list করবে।
  • Buying: user fixed price-এ কিনবে।
  • Bidding/Auction: user bid দিতে পারবে, সর্বোচ্চ bid জিতবে।
  • Browsing/Search: collection, দাম, trait অনুযায়ী filter ও sort।
  • Wallet integration: MetaMask-এর মতো wallet connect ও transaction sign।

Non-functional requirements:

  • Consistency with chain: যা দেখাচ্ছি তা যেন chain-এর সত্যিকার অবস্থার সাথে মেলে (eventual consistency গ্রহণযোগ্য কারণ chain নিজেই async)।
  • Fast browsing: millions NFT দ্রুত search/filter।
  • Availability: দোকান সবসময় খোলা।
  • Security: আমরা key রাখি না, কিন্তু signature request-এ user কী sign করছে তা স্পষ্ট দেখানো জরুরি।

২. স্কেল আন্দাজ (Estimation)

ধরি:
- মোট NFT          = 100 মিলিয়ন
- মোট user         = 10 মিলিয়ন, DAU = 1 মিলিয়ন
- Browse-heavy: প্রতি user প্রতিদিন 50 page view
  -> 1M * 50 = 50M views/day ~ 580 reads/sec avg
  -> peak ~ 5x = ~3,000 reads/sec  (cache + CDN দিয়ে সামলানো)

Write (mint/list/buy) অনেক কম:
- ধরি 200k on-chain action/day ~ 2-3 ops/sec
  -> কিন্তু প্রতিটা gas fee দিয়ে on-chain, latency chain-নির্ভর

Metadata/image storage:
- 100M NFT * গড় 2MB image -> ~200 TB (IPFS/CDN-এ, on-chain নয়)

Index DB:
- 100M NFT + listing + event history
  -> on-chain event index করে off-chain DB-তে, কয়েক TB

মূল শিক্ষা: এটা read-heavy, write-light system। Browsing দ্রুত করাই বড় কাজ, আর ভারী image কখনো on-chain যায় না।

৩. API ডিজাইন

# Browsing (off-chain index থেকে দ্রুত)
GET    /v1/nfts?collection=X&sort=price&trait=...
GET    /v1/nfts/{contract}/{tokenId}
GET    /v1/collections/{id}

# Listing / Offers (off-chain DB + signed message)
POST   /v1/listings        # body: {contract, tokenId, price, signedOrder}
GET    /v1/listings?contract=X
POST   /v1/offers          # bid: {contract, tokenId, amount, signedOrder}

# Mint helper
POST   /v1/mint/metadata   # IPFS-এ metadata upload, URI ফেরত

# Wallet
POST   /v1/auth/wallet     # wallet signature দিয়ে login (nonce sign)

লক্ষ্য করো: listing/buy-র আসল money-movement smart contract-এ হয়। আমাদের API অনেক সময় শুধু একটা signed order (off-chain signature) রাখে, যা পরে on-chain execute হয় — এতে gas বাঁচে।

৪. ডেটা মডেল

সবচেয়ে গুরুত্বপূর্ণ সিদ্ধান্ত — on-chain vs off-chain split:

Dataকোথায়কেন
Token ownershipOn-chain (ERC-721/1155)মালিকানার একমাত্র সত্য
Transfer/sale eventOn-chainআসল লেনদেন chain-এ
Image / large mediaOff-chain (IPFS + CDN)on-chain রাখা অসম্ভব ব্যয়বহুল
Metadata JSONIPFS (link on-chain)immutable + সস্তা
Listing/search indexOff-chain DBদ্রুত query/filter

কয়েকটা off-chain table:

Tableমূল কলাম
nftscontract, token_id, owner, metadata_uri, image_cdn_url, traits
collectionscollection_id, name, contract, creator
listingsid, contract, token_id, price, seller, signed_order, status
offersid, contract, token_id, amount, bidder, expiry, status
eventsevent_id, type, contract, token_id, from, to, txid, block

events table-টা indexer পূরণ করে — chain থেকে পড়া transfer/sale event-এর off-chain copy।

৫. হাই-লেভেল ডিজাইন

মূল component:

  • Frontend + Wallet Connect: browse করে, আর wallet (MetaMask) দিয়ে sign/transaction।
  • API / Backend: listing, offer, search request সামলায়।
  • Smart Contracts: NFT contract (mint/transfer) + marketplace contract (buy/sell/auction escrow)।
  • IPFS / Storage + CDN: image ও metadata; CDN দিয়ে দ্রুত serve।
  • Blockchain Node: chain-এর সাথে কথা বলা।
  • Event Indexer: নতুন block-এর event ধরে off-chain DB update।
  • Search/DB + Cache: Elasticsearch/Postgres + Redis দ্রুত browsing।

Mint flow:

  1. Creator image upload → backend IPFS-এ রাখে → metadata JSON বানিয়ে IPFS-এ রাখে, URI পায়।
  2. Creator-এর wallet NFT contract-এর mint(to, tokenURI) call করে (gas দেয়)।
  3. Mint event chain-এ যায় → Indexer ধরে → nfts table-এ নতুন row।

Buy flow:

  1. Seller NFT list করে (অনেক সময় শুধু signed order, off-chain)।
  2. Buyer "Buy" চাপলে wallet marketplace contract-এ transaction পাঠায় (টাকা + NFT atomic swap)।
  3. Contract NFT buyer-কে transfer করে, payment seller-কে।
  4. Sale event chain-এ → Indexer ownership ও listing status update।

মনে রাখো: marketplace backend কখনো NFT বা টাকা ধরে রাখে না। আসল swap smart contract-এর escrow logic-এ atomic-ভাবে হয়, তাই "টাকা দিলাম কিন্তু NFT পেলাম না" হওয়ার সুযোগ নেই।

৬. গভীরে (Deep Dive)

৬.১ On-chain vs Off-chain Split (IPFS-এ ছবি কেন)

Ethereum-এ data রাখা মারাত্মক ব্যয়বহুল — কয়েক KB রাখতেই অনেক gas। একটা 2MB image on-chain রাখা কার্যত অসম্ভব। তাই:

  • On-chain: শুধু token (owner, token_id) আর একটা tokenURI যা metadata-র দিকে নির্দেশ করে।
  • Off-chain: metadata JSON (নাম, description, traits, image link) আর আসল image।

Image সাধারণত IPFS-এ রাখা হয়, content hash (CID) দিয়ে। এর সুবিধা: hash content থেকে তৈরি, তাই কেউ চুপিচুপি image বদলাতে পারে না (immutability)। দ্রুত serve করতে IPFS-এর সামনে CDN/gateway বসানো হয়।

সাবধান

যদি NFT-র metadata একটা সাধারণ central server-এর URL-এ রাখো (IPFS নয়), আর সেই server বন্ধ হয়ে যায়, তাহলে NFT-র ছবি "ভেঙে" যাবে — token blockchain-এ থাকবে কিন্তু যা দেখাবার তা হারিয়ে যাবে। এটাকে "broken NFT" বলে। তাই metadata ও image IPFS/Arweave-এর মতো content-addressed, persistent storage-এ রাখাই নিরাপদ।

৬.২ Blockchain Event Indexing

কেন indexer লাগে? কারণ blockchain একটা ভালো database নয়। "সব Bored Ape listing দাম অনুযায়ী sort করো" — এই query chain সরাসরি দিতে পারে না।

Indexer যা করে:

  1. Blockchain node-এ নতুন block-এর জন্য subscribe/poll করে।
  2. আমাদের contract-এর event (Transfer, Sale, Bid) decode করে।
  3. Off-chain DB-তে nfts, listings, events update করে।
  4. তখন backend দ্রুত search/filter/sort করতে পারে।

খেয়াল রাখার বিষয়: reorg handling। নতুন block বাতিল হতে পারে, তাই indexer-কে confirmation অপেক্ষা করতে হয় ও প্রয়োজনে data rollback করতে হয়। আর indexer পিছিয়ে গেলে (lag) marketplace stale ownership দেখাবে।

৬.৩ Wallet Integration ও Auth

User password দেয় না — login হয় wallet দিয়ে:

  1. Backend একটা random nonce message পাঠায়।
  2. User-এর wallet সেটা private key দিয়ে sign করে (gas লাগে না, এটা off-chain message)।
  3. Backend signature যাচাই করে নিশ্চিত হয় user ওই address-এর মালিক।

Buy/list-এর সময় wallet একটা স্পষ্ট confirmation popup দেখায় — user ঠিক কী sign করছে। এই স্বচ্ছতা নিরাপত্তার জন্য জরুরি, কারণ ক্ষতিকর contract "approve all" আদায় করে fund চুরি করতে পারে।

৭. বটলনেক ও স্কেলিং

  • Browsing scale (read-heavy): এটা মূল load। Solution — Elasticsearch index, Redis cache, আর image-এর জন্য CDN। On-chain query কখনো hot path-এ রাখা যাবে না।
  • Indexer lag: indexer পিছিয়ে গেলে ভুল ownership/price দেখাবে। একাধিক worker, parallel block processing, আর backfill mechanism লাগে।
  • Image/metadata serving: 100M+ media — IPFS slow হতে পারে, তাই pinning service + CDN edge cache দরকার।
  • On-chain latency ও gas: buy/mint chain-নির্ভর, latency আমাদের হাতে নেই। তাই UI-তে pending/confirmed status স্পষ্ট দেখানো, আর gas বাঁচাতে off-chain signed order ব্যবহার করা।
  • Reorg/consistency: confirmation-aware indexing দিয়ে chain ও off-chain DB-র মধ্যে eventual consistency বজায় রাখা।

৮. সারসংক্ষেপ

একটা NFT marketplace-এর মূল কৌশল হলো কাজের সঠিক ভাগ: মালিকানা ও লেনদেন on-chain (smart contract), ভারী image/metadata off-chain (IPFS/CDN), আর দ্রুত browsing-এর জন্য on-chain event-কে indexer দিয়ে off-chain DB-তে index করা। Marketplace non-custodial — key বা কয়েন রাখে না, user wallet দিয়ে sign করে। এটা একটা read-heavy, write-light system যার আসল চ্যালেঞ্জ দ্রুত search আর chain-এর সাথে data sync।

ইন্টারভিউয়ার কী খোঁজেন

ইন্টারভিউয়ার সবার আগে দেখেন তুমি on-chain vs off-chain split পরিষ্কার বোঝো কিনা — ছবি যে on-chain যায় না, শুধু URI যায়, এটা না বললে design অবাস্তব। তারপর তারা চান তুমি indexer-এর প্রয়োজন ব্যাখ্যা করতে পারো (chain ভালো database নয়), non-custodial model বোঝো (wallet signing, marketplace key রাখে না), আর reorg/consistency-র মতো subtle জিনিস ছুঁতে পারো। "Read-heavy, তাই cache + CDN + search index" — এই framing করলে তোমার scaling sense ফুটে ওঠে।

মিনি কুইজ

1. একটা NFT-র ছবি সাধারণত কোথায় থাকে?

2. Marketplace দ্রুত browsing-এর জন্য কেন indexer ব্যবহার করে?

3. একটা NFT কেনার সময় marketplace কী রাখে না?