פוקר אימרסיבי על הבלוקצ'יין: ערוצי מצב ומערכת אקולוגית של NFT
פוקר על הבלוקצ'יין—שם הסתרת קלפים היא קריטית, אך הבלוקצ'יין הוא שקוף—מציב דילמה למפתחים: יישום פוקר מנטלי בסביבה ציבורית. ללא ארכיטקטורה מחוץ לשרשרת, עלויות גז והשהייה הופכים את המשחק לבלתי אפשרי. בניגוד לפוקר מסורתי שבו הדילר מחלק קלפים עם הפנים כלפי מטה, כל עסקה בחוזה חכם נראית לכל הצמתים. הצפנה לבדה אינה מספיקה; נדרש מפתח הנשלט על ידי השחקנים. לכל אחת מארבע הגישות—פוקר מנטלי, ZK, TEE, ושרת מחוץ לשרשרת—יש פשרות משלה בגז, השהייה ואמון. בדקנו את כולן ובחרנו את המעשית ביותר לייצור: ערוצי מצב עם שרת משחק מחוץ לשרשרת וסילוק על השרשרת. זה מאפשר עיבוד של עד 1000 ידיים בשנייה עם עמלות מתחת ל-$0.01 ליד ב-L2—סדר גודל זול יותר מחלופות על השרשרת.
הבעיה היסודית: הסתרת מידע על השרשרת
גישה 1: פוקר מנטלי עם Commit-Reveal
הגישה הקריפטוגרפית הקלאסית, שתוארה על ידי שמיר, ריבסט ואדלמן (1979):
- כל שחקן תורם זרע אקראי לערבוב (שלב ההתחייבות).
- החפיסה מעורבבת דטרמיניסטית משילוב של כל הזרעים.
- כל קלף מוצפן עם המפתח של כל שחקן (הצפנה בשכבות).
- קלף נחשף רק כאשר כל השחקנים חשפו את חלקם במפתח.
בעיה: עם 6 שחקנים, כל קלף מוצפן ב-6 שכבות. חשיפה דורשת 6 עסקאות על השרשרת. ביד פוקר עם 5 סבבים, מדובר בעשרות עסקאות ליד. גז והשהייה אינם מקובלים ברשת הראשית.
גישה 2: הוכחות ZK לקלפים נסתרים
ZK-SNARK מאפשר להוכיח "השחקן מחזיק בקלף בעל הערך הנדרש לתשלום" מבלי לחשוף את הקלף עצמו עד לסיום. פרויקטים כמו ZK-Holdem (על Circom) מנסים דרך זו. מורכבות: מעגלי ZK לחוקי פוקר (הערכת יד מלאה) אינם טריוויאליים. יצירת הוכחה במכשירים ניידים איטית (שניות); על שולחן עבודה זה מקובל.
גישה 3: סביבת ביצוע מהימנה (TEE)
שירות דילר פועל ב-Intel SGX או AWS Nitro Enclave—סביבה מבודדת שבה אפילו מפעיל השרת אינו יכול לראות את הנתונים. קלפים מחולקים בתוך ה-TEE; שחקנים רואים רק את הקלפים שלהם דרך ערוץ מוצפן. רק תוצאות סבב והתחייבויות עולות על השרשרת. פשרה: אמון ביצרן ה-TEE (Intel). עבור רוב יישומי המשחקים, זה מקובל—לא גרוע יותר מאמון בדילר בקזינו.
גישה 4: שרת משחק מחוץ לשרשרת + סילוק על השרשרת
האפשרות המעשית ביותר לייצור: שרת משחק שומר על מצב המשחק מחוץ לשרשרת, שחקנים חותמים על מהלכים (הימור, קיפול, העלאה) דרך ערוץ מצב, והתוצאה הסופית נרשמת על השרשרת לתשלום.
Players → [Game Server] → manages hidden cards, game state
↕ signed moves (state channel)
↓ final result + signatures
[Settlement Contract] → pays out winners למה ערוצי מצב אידיאליים לפוקר
ערוצי מצב הם המודל המושלם לפוקר. שחקנים פותחים ערוץ, מפקידים כספים, וכל המהלכים הם הודעות חתומות מחוץ לשרשרת. עסקאות השרשרת היחידות הן פתיחת וסגירת הערוץ. ערוצי מצב יעילים פי 10 בגז מאשר משחק על השרשרת.
contract PokerStateChannel {
struct Channel {
address[6] players;
uint256[6] deposits;
uint256 totalPot;
bytes32 stateHash; // хэш текущего состояния игры
uint256 nonce; // счётчик ходов
ChannelStatus status;
}
struct PlayerMove {
uint8 playerId;
MoveType moveType; // BET, RAISE, CALL, FOLD, CHECK
uint256 amount;
uint256 channelNonce; // должен соответствовать nonce channel
bytes signature; // подпись игрока
}
function openChannel(address[6] calldata players, uint256[6] calldata deposits) external payable returns (bytes32 channelId) {
// Verify all deposits
uint256 totalDeposit = 0;
for (uint i = 0; i < 6; i++) totalDeposit += deposits[i];
require(msg.value == totalDeposit, "Incorrect deposit");
channelId = keccak256(abi.encode(players, block.timestamp, block.prevrandao));
channels[channelId] = Channel({
players: players,
deposits: deposits,
totalPot: totalDeposit,
stateHash: bytes32(0),
nonce: 0,
status: ChannelStatus.OPEN
});
}
function closeChannel(
bytes32 channelId,
uint256[6] calldata finalBalances,
bytes[6] calldata playerSignatures
) external {
Channel storage ch = channels[channelId];
require(ch.status == ChannelStatus.OPEN, "Channel not open");
// Верифицируем подписи всех игроков на final state
bytes32 finalStateHash = keccak256(abi.encode(channelId, finalBalances, ch.nonce));
for (uint i = 0; i < 6; i++) {
require(
ECDSA.recover(ECDSA.toEthSignedMessageHash(finalStateHash), playerSignatures[i]) == ch.players[i],
"Invalid player signature"
);
}
// Выплачиваем
for (uint i = 0; i < 6; i++) {
if (finalBalances[i] > 0) {
payable(ch.players[i]).transfer(finalBalances[i]);
}
}
ch.status = ChannelStatus.CLOSED;
}
} מנגנון מחלוקות
אם שרת המשחק נעלם או מנסה לרמות, ערוץ המצב חייב לכלול פתרון מחלוקות. אנו משתמשים במנגנון מבוסס זמן: אם שחקן לא מקבל תשובה תוך N בלוקים, הוא יכול ליזום מחלוקת על ידי הצגת המצב החתום האחרון. הצד השני חייב להגיב עם מצב חדש יותר. אם לא, השחקן שפנה מנצח. אנו גם משתמשים בחשיפה כפויה: בסיום, כל השחקנים הפעילים חייבים לחשוף קלפים על השרשרת תוך זמן מוגדר, אחרת הם נחשבים כמקפלים.
הבטחת ערבוב הוגן ללא חשיפת קלפים
שרת המשחק מערבב את החפיסה. כדי להוכיח הוגנות, אנו משתמשים בערבוב commit-reveal:
- לפני החלוקה, השרת מפרסם hash של הזרע:
Players → [Game Server] → manages hidden cards, game state ↕ signed moves (state channel) ↓ final result + signatures [Settlement Contract] → pays out winners - שחקנים תורמים את האנטרופיה שלהם
- החפיסה הסופית = shuffle(seed XOR player_entropy_1 XOR ... XOR player_entropy_N)
- לאחר המשחק, השרת חושף את הזרע—כל אחד יכול לאמת את הערבוב
// Server side
const serverSeed = crypto.randomBytes(32)
const commitment = keccak256(concat([serverSeed, salt]))
await contract.publishCommitment(channelId, commitment)
// After all player entropy received:
const finalSeed = xorAll([serverSeed, ...playerEntropyContributions])
const deck = shuffleDeck(standardDeck, finalSeed) // deterministic Fisher-Yates
// After game:
await contract.revealSeed(channelId, serverSeed, salt)
// Anyone can verify:
hash(serverSeed + salt) == commitment
// And:
shuffle(standardDeck, serverSeed XOR playerEntropy) == used deckשיטה זו מספקת הוגנות ניתנת לאימות מבלי לחשוף קלפים עד סוף המשחק.
לוגיקת משחק מחוץ לשרשרת
לוגיקת הפוקר (הערכת יד בטקסס הולדם, סבבי הימורים, ניהול קופה) מתבצעת כולה מחוץ לשרשרת על השרת. החוזה מטפל רק ב: הפקדה, התחייבויות מצב, מחלוקות ותשלומים.
// Hand evaluator
import { Hand } from 'pokersolver'
function evaluateHand(holeCards: Card[], communityCards: Card[]): HandResult {
const hand = Hand.solve([...holeCards, ...communityCards].map(c => c.toString()))
return {
rank: hand.rank,
name: hand.name, // 'Royal Flush', 'Full House', etc.
value: hand.value,
cards: hand.cards
}
}
function determineWinner(players: ActivePlayer[], communityCards: Card[]): Winner[] {
const hands = players.map(p => ({
player: p,
hand: Hand.solve([...p.holeCards, ...communityCards].map(c => c.toString()))
}))
const winners = Hand.winners(hands.map(h => h.hand))
return winners.map(w => hands.find(h => h.hand === w)!.player)
} אילו נכסי NFT מבוקשים במערכת האקולוגית של פוקר?
- אווטארים / פרופילי NFT לשחקנים. NFT קוסמטיים אינם משפיעים על המשחק אך מספקים זהות ושוק משני. ERC-721 עם מטא-דאטה דינמי (אחוז ניצחונות, משחקים ששוחקו) דרך tokenURI עם נתונים על השרשרת או מחוצה לה.
- NFT של שולחן פוקר. שולחן פרטי כ-NFT: בעל ה-NFT שולט בהגדרות השולחן (אחוז עמלה, מבנה בליינדים, הזמנה בלבד) ומקבל חלק מהעמלה. הכנסה פסיבית למחזיקי NFT.
- ערכות צ'יפים וסקינים לחפיסות קלפים. קוסמטי בלבד, אך משמעותי לשימור שחקנים. ERC-1155 לקוסמטיקה ניתנת להחלפה.
טוקנומיקה ועמלה
עמלה היא אחוז מכל קופה, בדומה לקזינו. 2–5% מהקופה הוא סטנדרט. בפוקר על השרשרת, העמלה הולכת לאוצר הפרוטוקול. חלוקה:
Pot rake (3%) → 50% burn / buyback game token
→ 30% staking rewards (stakers = liquidity providers)
→ 20% development fundNFT להחזר עמלה. שחקנים עם NFT מסוים מקבלים החזר חלקי של העמלה. מעודד החזקת NFT ופועל כשקע של טוקנים (NFT נרכשים עם טוקנים).
מה כלול בעבודה
- תיעוד ארכיטקטוני (גישת הסתרת קלפים, עיצוב ערוץ מצב)
- חוזים חכמים (ערוץ מצב, NFT, עמלה) עם בדיקות וביקורת
- שרת משחק על Node.js עם לוגיקת פוקר ו-WebSocket
- פרונטאנד על React עם Three.js/Pixi.js ואינטגרציית ארנק (wagmi + WalletConnect v2)
- אינטגרציה עם TEE או ZK (בהתאם לבחירה)
- גישה למאגר Git, פריסה ל-testnet, הדרכת צוות
- 3 חודשי תמיכה לאחר ההשקה
| שלב | לוח זמנים | תוצאה |
|---|---|---|
| ארכיטקטורה | שבוע 1 | בחירת גישה, מסמך |
| חוזים חכמים | 3-4 שבועות | חוזים + בדיקות |
| שרת משחק | 3-5 שבועות | שרת + ערבוב |
| פרונטאנד | 4-6 שבועות | ממשק + אינטגרציית ארנק |
| ביקורת ו-testnet | שבועיים | סקירת אבטחה |
| MVP | 3-4 חודשים | משחק עובד |
| ייצור | 6-9 חודשים | מערכת אקולוגית מלאה |
מחסן טכנולוגיות
| רכיב | טכנולוגיה |
|---|---|
| חוזים חכמים | Solidity + Foundry |
| ערוצי מצב | Nitro Protocol / מותאם אישית |
| שרת משחק | Node.js + TypeScript |
| זמן אמת | WebSocket (Socket.io) |
| פרונטאנד | React + Three.js / Pixi.js לשולחן |
| ארנק | wagmi + WalletConnect v2 |
| ZK (אם נבחר) | Circom + snarkjs |
| TEE (אם נבחר) | AWS Nitro Enclaves |
לצוות שלנו ניסיון של 5+ שנים בפיתוח בלוקצ'יין והוא סיפק למעלה מ-20 פרויקטים על Ethereum ו-L2. הזמינו MVP מ-3 חודשים—בואו נדון בארכיטקטורה ובלוחות זמנים. צרו קשר להערכת פרויקט חינם.







