פיתוח DEX עם ספר הזמנות: חוזים חכמים וארכיטקטורה

סוחרים רגילים לפקודות מגבילות ופנקס הזמנות ב-CEX, אך בבורסות DeFi עם AMM זה אינו זמין — רק פקודות שוק עם החלקה. אנחנו בונים בורסת DEX עם פנקס הזמנות המספקת נזילות ברמת CEX מבלי לוותר על ביזור. הצוות שלנו מספק את הפרויקט במפתח מלא — מארכיטקטורת חוזים חכמים ועד אינטגרציית מנוע התאמה ותמיכה מתמשכת.

שירותי פיתוח בלוקצ'יין

שאלות נפוצות

העבודות האחרונות

  • פיתוח אתר חברה B2B ADVANCE
    פיתוח אתר חברה B2B ADVANCE
    1481
  • פיתוח אפליקציית ווב עבור FEEDME
    פיתוח אפליקציית ווב עבור FEEDME
    1335
  • פיתוח אתר עבור BELFINGROUP
    פיתוח אתר עבור BELFINGROUP
    1034
  • פיתוח חנות מקוונת לחברת FURNORO
    פיתוח חנות מקוונת לחברת FURNORO
    1293
  • עיצוב לוגו לחברת B2B Advance
    עיצוב לוגו לחברת B2B Advance
    738
  • פיתוח אפליקציית ווב עבור Enviok
    פיתוח אפליקציית ווב עבור Enviok
    1031

סוחרים רגילים לפקודות מגבילות ולספרי הזמנות בבורסות מרכזיות (CEX). אך בבורסות DeFi עם AMM, זה אינו זמין—רק פקודות שוק עם החלקה (slippage). אנו בונים בורסת DEX עם ספר הזמנות המספקת נזילות דומה ל-CEX מבלי לוותר על ביזור. הניסיון שלנו: למעלה מ-10 שנים בבלוקצ'יין ולמעלה מ-50 פרויקטים, כולל אינטגרציות עם AMM ו-L2.

בעיות שאנו פותרים

  • עלויות גז לאחסון על-השרשרת: כל פקודה היא עסקה, כל התאמה היא עסקה; בתדירות מסחר, זה לא כלכלי—הפתרון: מנוע התאמה מחוץ לשרשרת + סילוק על-השרשרת.
  • Front-running ו-MEV: ב-mempool הציבורי, פקודות גלויות לכולם; בוטים יכולים לבצע front-running לעסקה שלך—אנו משתמשים בחתימות EIP-712 עם nonce לא סטנדרטיים, אינטגרציה עם Flashbots, ואיגוד עסקאות (batching).
  • נזילות בהשקה: ספר הזמנות ריק מפחיד סוחרים—פתרונות: אינטגרציה עם מאגרי AMM כגיבוי, שירות RFQ לפקודות מוסדיות, תוכנית market maker עם עמלות מופחתות.

באיזה מודל ספר הזמנות לבחור?

ספר הזמנות מלא על-השרשרת: ספר ההזמנות מאוחסן ומותאם ישירות בחוזה חכם. כל פקודה היא עסקה. עלות גז גבוהה: הצבה, ביטול, מילוי—הכל משולם על ידי הסוחר. זמן השהיה ~12 שניות (בלוק של Ethereum). Front-running בלתי נמנע. מתאים רק למכירות פומביות ולסילוק בקבוצות (batch settlement).

ספר הזמנות מחוץ לשרשרת + סילוק על-השרשרת: המודל הדומיננטי. התאמה—מחוץ לשרשרת (מהיר, חינם). רק העסקה הסופית מסולקת על-השרשרת. דוגמאות: dYdX v3 (Starkware), Serum (Solana). התאמה מחוץ לשרשרת עדיפה על פני מלא על-השרשרת פי 10-100 בעלות גז ופי 10 במהירות.

היברידי: פקודות מחוץ לשרשרת + התאמה על-השרשרת: פקודות חתומות מחוץ לשרשרת (EIP-712), מאוחסנות בספר הזמנות מחוץ לשרשרת, אך ההתאמה מבוצעת על-השרשרת בסילוק. דוגמה: 0x Protocol, Hashflow. Maker אינו משלם גז עבור הצבה—רק עבור ביצוע.

קריטריון על-השרשרת מחוץ לשרשרת + סילוק על-השרשרת היברידי
עלות גז גבוהה נמוכה בינונית
זמן השהיה ~12 שניות <1 שנייה <1 שנייה
מורכבות נמוכה בינונית גבוהה
התאמה לשימוש מכירות פומביות מסחר מקצועי יצירת שוק (market making)

חוזים חכמים לסילוק

חתימות פקודות EIP-712:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

contract OrderBookSettlement {
    bytes32 public constant ORDER_TYPEHASH = keccak256(
        "Order(address maker,address taker,address makerToken,address takerToken,"
        "uint256 makerAmount,uint256 takerAmount,uint256 nonce,uint256 expiry)"
    );

    struct Order {
        address maker;
        address taker; // address(0) = any taker
        address makerToken;
        address takerToken;
        uint256 makerAmount;
        uint256 takerAmount;
        uint256 nonce;
        uint256 expiry;
    }

    mapping(address => mapping(uint256 => bool)) public usedNonces;
    mapping(bytes32 => uint256) public filledAmounts; // partial fills

    function fillOrder(
        Order calldata order,
        bytes calldata signature,
        uint256 takerFillAmount // for partial fills
    ) external {
        require(block.timestamp < order.expiry, "ORDER_EXPIRED");
        require(
            order.taker == address(0) || order.taker == msg.sender,
            "INVALID_TAKER"
        );
        bytes32 orderHash = getOrderHash(order);
        require(
            filledAmounts[orderHash] + takerFillAmount <= order.takerAmount,
            "OVERFILL"
        );
        // Verify EIP-712 signature
        address recovered = recoverSigner(orderHash, signature);
        require(recovered == order.maker, "INVALID_SIGNATURE");
        // Calculate maker amount proportional to partial fill
        uint256 makerFillAmount = (order.makerAmount * takerFillAmount) / order.takerAmount;
        filledAmounts[orderHash] += takerFillAmount;
        // Atomic swap
        IERC20(order.takerToken).transferFrom(msg.sender, order.maker, takerFillAmount);
        IERC20(order.makerToken).transferFrom(order.maker, msg.sender, makerFillAmount);
        emit OrderFilled(orderHash, order.maker, msg.sender, makerFillAmount, takerFillAmount);
    }
}

מפרט EIP-712 מגדיר את מבנה החתימה. היבטי אבטחה מרכזיים: // SPDX-License-Identifier: MIT pragma solidity ^0.8.19; contract OrderBookSettlement { bytes32 public constant ORDER_TYPEHASH = keccak256( "Order(address maker,address taker,address makerToken,address takerToken," "uint256 makerAmount,uint256 takerAmount,uint256 nonce,uint256 expiry)" ); struct Order { address maker; address taker; // address(0) = any taker address makerToken; address takerToken; uint256 makerAmount; uint256 takerAmount; uint256 nonce; uint256 expiry; } mapping(address => mapping(uint256 => bool)) public usedNonces; mapping(bytes32 => uint256) public filledAmounts; // partial fills function fillOrder( Order calldata order, bytes calldata signature, uint256 takerFillAmount // for partial fills ) external { require(block.timestamp < order.expiry, "ORDER_EXPIRED"); require( order.taker == address(0) || order.taker == msg.sender, "INVALID_TAKER" ); bytes32 orderHash = getOrderHash(order); require( filledAmounts[orderHash] + takerFillAmount <= order.takerAmount, "OVERFILL" ); // Verify EIP-712 signature address recovered = recoverSigner(orderHash, signature); require(recovered == order.maker, "INVALID_SIGNATURE"); // Calculate maker amount proportional to partial fill uint256 makerFillAmount = (order.makerAmount * takerFillAmount) / order.takerAmount; filledAmounts[orderHash] += takerFillAmount; // Atomic swap IERC20(order.takerToken).transferFrom(msg.sender, order.maker, takerFillAmount); IERC20(order.makerToken).transferFrom(order.maker, msg.sender, makerFillAmount); emit OrderFilled(orderHash, order.maker, msg.sender, makerFillAmount, takerFillAmount); } } למילוי חלקי, filledAmounts נגד שימוש חוזר (replay), ו-usedNonces חובה. עבור approve סטנדרטי, נדרשת עסקה נפרדת—Permit2 של Uniswap Labs פותר זאת עם חתימה אחת.

כיצד פועל מנוע ההתאמה מחוץ לשרשרת?

זהו שירות בעל ביצועים גבוהים הדומה למנוע התאמה של CEX, אך עם מאפיינים ייחודיים:

  1. פקודות הן הודעות חתומות, לא על-השרשרת.
  2. מילוי חלקי מנוטר מחוץ לשרשרת ועל-השרשרת (מיפוי filledAmounts).
  3. ביטול פקודה: nonce על-השרשרת או ביטול מחוץ לשרשרת עם אישור maker.
from dataclasses import dataclass
from decimal import Decimal
from typing import Optional
import asyncio

@dataclass
class SignedOrder:
    maker: str
    taker_token: str
    maker_token: str
    taker_amount: Decimal
    maker_amount: Decimal
    nonce: int
    expiry: int
    signature: str

    @property
    def price(self) -> Decimal:
        """Цена в единицах maker_token за taker_token"""
        return self.maker_amount / self.taker_amount

    @property
    def is_expired(self) -> bool:
        import time
        return time.time() > self.expiry

class OffChainOrderBook:
    def __init__(self, pair: str):
        self.pair = pair
        self.bids: list[SignedOrder] = []  # buy orders, sorted by price DESC
        self.asks: list[SignedOrder] = []  # sell orders, sorted by price ASC
        self._settlement_queue = asyncio.Queue()

    async def add_order(self, order: SignedOrder, side: str):
        if side == 'bid':
            self.bids.append(order)
            self.bids.sort(key=lambda x: x.price, reverse=True)
        else:
            self.asks.append(order)
            self.asks.sort(key=lambda x: x.price)
        await self.try_match()

    async def try_match(self):
        while self.bids and self.asks:
            best_bid = self.bids[0]
            best_ask = self.asks[0]
            if best_bid.is_expired:
                self.bids.pop(0)
                continue
            if best_ask.is_expired:
                self.asks.pop(0)
                continue
            if best_bid.price >= best_ask.price:
                # Match found
                fill_amount = min(best_bid.taker_amount, best_ask.taker_amount)
                await self._settlement_queue.put({
                    'bid': best_bid,
                    'ask': best_ask,
                    'fill_amount': fill_amount
                })
                # Update or remove filled orders
                best_bid.taker_amount -= fill_amount
                best_ask.taker_amount -= fill_amount
                if best_bid.taker_amount == 0:
                    self.bids.pop(0)
                if best_ask.taker_amount == 0:
                    self.asks.pop(0)
            else:
                break

כמה חוסך איגוד עסקאות?

אצווה של 10 מילוי בעסקה אחת חוסכת ~70% גז בהשוואה ל-10 עסקאות נפרדות. הפונקציה expiry מאפשרת זאת.

function fillOrderBatch(
    Order[] calldata orders,
    bytes[] calldata signatures,
    uint256[] calldata fillAmounts
) external {
    require(orders.length == signatures.length, "LENGTH_MISMATCH");
    for (uint256 i = 0; i < orders.length; i++) {
        fillOrder(orders[i], signatures[i], fillAmounts[i]);
    }
}

מה מציעות L2 ו-appchain?

פריסה: dYdX v4 על Cosmos appchain מציעה אפס עמלות לסוחרים וזמן השהיה של <1 אלפית שנייה. Arbitrum / zkSync L2 מפחיתות עלות גז פי 10-100—פקודות על-השרשרת הופכות לכלכליות עבור נפחים >$100. Starkware עם הוכחות תקפות (validity proofs) מתמודדת עם למעלה מ-10,000 עסקאות בשנייה.

כיצד להבטיח נזילות בהשקה?

  • אינטגרציה עם AMM: אם אין market maker, הנתב מפנה למאגר AMM (לדוגמה, Uniswap V3).
  • תוכנית market maker: עמלות מופחתות, מסגרת אשראי, התאמה בעדיפות.
  • RFQ: סוחרים מוסדיים מבקשים הצעות מחיר ישירות מ-MM רשומים.

השוואה עם AMM

קריטריון בורסת DEX עם ספר הזמנות בורסת DEX עם AMM
יעילות הון גבוהה (ללא נזילות בטלה) נמוכה (V2) / גבוהה (V3)
חוויית משתמש לסוחרים מוכרת, פקודות מגבילות פשוטה יותר, שוק בלבד
יצירת שוק דורש מקצוענים נגיש לכל ספקי הנזילות (LPs)
סיכון front-running גבוה (ללא הגנה) בינוני (sandwich)
זמן השהיה תלוי בארכיטקטורה בלוק אחד
מורכבות גבוהה בינונית

תהליך הפיתוח

  1. אנליטיקה: בחירת בלוקצ'יין, L2, מודל התאמה (על-השרשרת/מחוץ לשרשרת/היברידי).
  2. עיצוב: ארכיטקטורת חוזים חכמים, שירותים מחוץ לשרשרת, API.
  3. יישום: פיתוח חוזי סילוק, מנוע התאמה, אינטגרציה עם ארנקים.
  4. בדיקות: בדיקות יחידה, בדיקות אינטגרציה, fuzzing (Echidna), סימולציה ברשת testnet.
  5. ביקורת: אוטומטית (Slither, Mythril) ובדיקת קוד ידנית.
  6. פריסה: השקה בשלבים עם ניטור.

מה כלול בעבודה

  • תיעוד ארכיטקטורה ו-API
  • גישה לקוד המקור של החוזים ומנוע ההתאמה
  • הוראות פריסה וניטור
  • הכשרת צוות לניהול
  • תמיכה לחודש לאחר הפריסה

לוחות זמנים: MVP תוך 2–3 חודשים, מערכת מלאה עם L2 ו-RFQ מ-6 חודשים. העלות מחושבת באופן אישי. צרו קשר לייעוץ וקבלו הערכה תוך יומיים. הזמינו פיתוח כדי להאיץ את זמן היציאה לשוק.