Разработка системы P2P-торговли криптовалютой

Проектируем и разрабатываем блокчейн-решения полного цикла: от архитектуры смарт-контрактов до запуска DeFi-протоколов, NFT-маркетплейсов и криптобирж. Аудит безопасности, токеномика, интеграция с существующей инфраструктурой.
Показано 1 из 1 услугВсе 1306 услуг
Разработка системы P2P-торговли криптовалютой
Сложная
от 2 недель до 3 месяцев
Часто задаваемые вопросы
Направления блокчейн-разработки
Этапы блокчейн-разработки
Последние работы
  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1258
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1170
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    873
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1092
  • image_logo-advance_0.png
    Разработка логотипа компании B2B Advance
    563
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    830

Разработка системы P2P-торговли криптовалютой

P2P (peer-to-peer) торговля криптовалютой — это платформа, где пользователи торгуют напрямую между собой, а система выступает escrow и арбитром. В отличие от обычной биржи, здесь нет matching engine — есть объявления, переговоры и dispute resolution. Технически это проще биржи, но организационно сложнее: фрод-менеджмент, репутационная система и защита пользователей — критические компоненты.

Архитектура P2P системы

Основные сущности

Объявление (Offer)
├── Пользователь (maker)
├── Тип (buy/sell)
├── Криптовалюта
├── Фиатная валюта
├── Способы оплаты (методы)
├── Курс (фиксированный или привязанный к рынку)
├── Лимиты (min/max сумма)
└── Условия и требования (только верифицированные, мин. рейтинг)

Сделка (Trade)
├── Объявление (ссылка)
├── Maker + Taker
├── Сумма крипты
├── Сумма фиата
├── Статус (created → paid → released | disputed | cancelled)
├── Escrow адрес
└── История сообщений

Escrow механизм

Escrow — сердце P2P системы. Продавец блокирует криптовалюту в escrow-контракте до подтверждения оплаты. Это защищает покупателя от скама.

On-chain escrow (смарт-контракт):

contract P2PEscrow {
    enum TradeStatus { Active, Completed, Disputed, Cancelled }

    struct Trade {
        address seller;
        address buyer;
        address token;
        uint256 amount;
        uint256 releaseTimeout;  // автоматический release через N часов
        TradeStatus status;
        bool sellerConfirmed;
        bool buyerPaid;
    }

    mapping(bytes32 => Trade) public trades;

    event TradeCreated(bytes32 tradeId, address seller, address buyer, uint256 amount);
    event TradeCompleted(bytes32 tradeId);
    event TradeDisputed(bytes32 tradeId);

    function createTrade(
        bytes32 tradeId,
        address buyer,
        address token,
        uint256 amount,
        uint256 timeoutHours
    ) external {
        IERC20(token).transferFrom(msg.sender, address(this), amount);

        trades[tradeId] = Trade({
            seller: msg.sender,
            buyer: buyer,
            token: token,
            amount: amount,
            releaseTimeout: block.timestamp + timeoutHours * 1 hours,
            status: TradeStatus.Active,
            sellerConfirmed: false,
            buyerPaid: false
        });

        emit TradeCreated(tradeId, msg.sender, buyer, amount);
    }

    function confirmRelease(bytes32 tradeId) external {
        Trade storage trade = trades[tradeId];
        require(msg.sender == trade.seller, "Not seller");
        require(trade.status == TradeStatus.Active, "Invalid status");

        trade.status = TradeStatus.Completed;
        IERC20(trade.token).transfer(trade.buyer, trade.amount);
        emit TradeCompleted(tradeId);
    }

    function openDispute(bytes32 tradeId) external {
        Trade storage trade = trades[tradeId];
        require(
            msg.sender == trade.buyer || msg.sender == trade.seller,
            "Not party"
        );
        trade.status = TradeStatus.Disputed;
        emit TradeDisputed(tradeId);
    }

    // Арбитр (мультисиг) решает спор
    function resolveDispute(bytes32 tradeId, address winner) external onlyArbitrator {
        Trade storage trade = trades[tradeId];
        require(trade.status == TradeStatus.Disputed);

        trade.status = TradeStatus.Completed;
        IERC20(trade.token).transfer(winner, trade.amount);
    }
}

Custodial escrow (централизованный): биржа хранит средства на своих кошельках. Технически проще, быстрее, дешевле (нет газа). Биржа несёт полную кастодиальную ответственность. Большинство крупных P2P платформ (LocalBitcoins, Binance P2P) используют именно этот подход.

Ценообразование: фиксированное vs плавающее

Фиксированная цена: продавец указывает конкретный курс. Может устареть к моменту сделки.

Плавающая цена (market-linked): курс = spot цена × (1 + margin%). Например: "Продаю BTC за 102% от Binance spot цены".

def calculate_offer_price(
    reference_price: float,
    margin_percent: float,
    side: str
) -> float:
    """
    side='sell': продавец просит premium над рынком
    side='buy': покупатель предлагает дисконт
    """
    if side == 'sell':
        return reference_price * (1 + margin_percent / 100)
    else:
        return reference_price * (1 - margin_percent / 100)

Reference price агрегируется из нескольких источников (Binance, CoinGecko) с median для защиты от манипуляций.

Защита от фрода

Типичные схемы мошенничества

Chargeback fraud: покупатель платит через reversible метод (PayPal Friends & Family всё равно могут быть возвращены через спор с банком), получает крипту, затем инициирует chargeback.

Counterfeit payment proof: поддельный скриншот об оплате. Продавца давят на скорейший release.

Triangle fraud: A убеждает B продать крипту C, B получает деньги от реальной жертвы (которая думает что покупает что-то другое), скам разворачивается против жертвы.

Account takeover: угон аккаунта с хорошей репутацией для проведения скам-сделок.

Технические защиты

Методы оплаты риск-скоринг:

Метод Chargeback risk Рекомендация
Банковский перевод (SEPA) Низкий Разрешить
Наличные лично Нет Разрешить
PayPal (G&S) Высокий Запретить/предупреждение
Western Union Средний Ограниченно
Revolute Средний Зависит от страны
Crypto-to-crypto Нет Разрешить

KYC верификация: обязательная верификация личности для любой суммы выше порога. SMS верификация недостаточна — нужен ID + selfie.

Репутационная система:

class ReputationScore:
    def calculate(self, user_id: str) -> dict:
        stats = self.db.get_user_stats(user_id)

        completed = stats['completed_trades']
        cancelled = stats['cancelled_trades']
        disputed_won = stats['disputes_won']
        disputed_lost = stats['disputes_lost']
        days_active = stats['days_active']

        # Completion rate
        total = completed + cancelled
        completion_rate = completed / total if total > 0 else 0

        # Dispute rate (процент сделок с диспутом)
        dispute_rate = (disputed_won + disputed_lost) / completed if completed > 0 else 0

        score = (
            completion_rate * 40 +        # 0-40 баллов
            (1 - dispute_rate) * 30 +     # 0-30 баллов
            min(completed / 100, 1) * 20 +  # до 20 баллов за объём
            min(days_active / 365, 1) * 10  # до 10 баллов за стаж
        )

        return {
            "score": round(score * 100),
            "level": self.get_level(score),
            "completed": completed,
            "completion_rate": completion_rate,
            "dispute_rate": dispute_rate
        }

Поведенческий анализ (anti-fraud ML):

  • Нестандартное время активности
  • Множество аккаунтов с одного IP/устройства
  • Необычно высокий объём для нового аккаунта
  • Паттерны, совпадающие с известными фрод-схемами

Dispute resolution процесс

Workflow спора:

1. Открытие спора (покупатель или продавец)
2. Автоматическое уведомление обеих сторон
3. 24 часа на представление доказательств:
   - Скриншоты переписки
   - Банковские выписки
   - Видео/фото при личной встрече
4. Арбитр рассматривает дело
5. Решение арбитра → release или return
6. Апелляция (опционально, для крупных сумм)

Арбитраж — дорогостоящий процесс при масштабе. Большинство платформ автоматизируют решение простых случаев (например: покупатель прислал bank statement, продавец молчит более 12 часов → автоматический release в пользу покупателя).

Чат и коммуникация

End-to-end encrypted чат

Для P2P сделок желателен E2E чат. Реализация через Signal Protocol или Libsodium:

// Клиентская генерация ключевой пары
const keyPair = nacl.box.keyPair();

// Обмен публичными ключами через сервер
// Шифрование сообщения публичным ключом получателя
function encryptMessage(message, recipientPublicKey, senderSecretKey) {
  const nonce = nacl.randomBytes(nacl.box.nonceLength);
  const messageBytes = nacl.util.decodeUTF8(message);

  const encrypted = nacl.box(
    messageBytes,
    nonce,
    recipientPublicKey,
    senderSecretKey
  );

  return {
    nonce: nacl.util.encodeBase64(nonce),
    ciphertext: nacl.util.encodeBase64(encrypted)
  };
}

Сервер хранит только зашифрованные сообщения — не может читать переписку. Важно для соответствия GDPR и доверия пользователей.

Хранение доказательств для диспутов: сообщения хранятся в базе с подписью сервера о времени отправки. При открытии спора оба участника дают согласие на передачу истории чата арбитру.

Фиатные методы оплаты

Интеграция банковских переводов

Для регионов с доступным instant banking (SEPA Instant в EU, Faster Payments в UK, PIX в Бразилии) можно автоматизировать подтверждение оплаты:

class BankingWebhook:
    async def handle_sepa_notification(self, event: dict):
        """Обработка webhook от банка при получении SEPA перевода"""
        amount = event['amount']
        reference = event['reference']  # структурированный референс

        # Парсим trade_id из референса (продавец указал его покупателю)
        trade_id = self.parse_trade_reference(reference)
        if not trade_id:
            return

        trade = await self.db.get_trade(trade_id)
        if abs(trade.fiat_amount - amount) < 0.01:  # допуск $0.01
            await self.auto_confirm_payment(trade_id)
            await self.notify_seller(trade.seller_id, trade_id)

Автоматическое подтверждение через банковский webhook резко снижает нагрузку на службу поддержки и ускоряет release.

Технический стек

Компонент Технология
Backend API Node.js / Go
Database PostgreSQL (сделки, пользователи)
Real-time чат WebSocket (Socket.io)
Escrow Смарт-контракт или custody DB
KYC Sumsub / Sum&Substance
Fraud detection Python ML pipeline
Notifications Firebase FCM + email
Фиатная интеграция Banking API / Webhooks

P2P платформа технически проще CEX, но требует зрелых операционных процессов: команды поддержки, арбитров, мониторинга фрода. Недооценка операционной стороны — главная причина провала P2P проектов.