Разработка системы депозитов и выводов

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

Разработка системы депозитов и выводов

Система депозитов и выводов — самая критичная с точки зрения безопасности часть криптобиржи. Здесь хранятся и перемещаются реальные средства пользователей. Каждая ошибка — прямые финансовые потери. Разберём архитектуру с акцентом на безопасность и устойчивость к сбоям.

Архитектура депозитов

Генерация депозитных адресов

Каждый пользователь получает уникальный депозитный адрес для каждой сети. Существуют два подхода:

HD Wallet (Hierarchical Deterministic). Из одного мастер-seed генерируется детерминированное дерево ключей по BIP-32/BIP-44. Для Bitcoin: m/44'/0'/0'/0/{user_index}. Для Ethereum: m/44'/60'/0'/0/{user_index}.

import { HDNodeWallet } from "ethers";

const masterNode = HDNodeWallet.fromMnemonic(Mnemonic.fromPhrase(MASTER_MNEMONIC));

function getDepositAddress(userId: number, coinIndex: number): string {
  // m/44'/coinIndex'/0'/0/userId
  const child = masterNode
    .deriveChild(44 + 0x80000000)  // purpose
    .deriveChild(coinIndex + 0x80000000)  // coin type
    .deriveChild(0 + 0x80000000)  // account
    .deriveChild(0)               // external
    .deriveChild(userId);
  return child.address;
}

Мастер-seed хранится в HSM (Hardware Security Module) или в зашифрованном vault (HashiCorp Vault). Публичные ключи для генерации адресов — в БД, приватные ключи для подписи — только в HSM.

Shared address + memo. Один адрес на всю биржу, пользователь указывает memo/tag при отправке. Используется для Ripple (XRP), Stellar (XLM), Cosmos. Дешевле в обслуживании, но ошибка в memo — потеря средств.

Мониторинг входящих транзакций

Сервис мониторинга подписывается на события блокчейна:

  • EVM chains: eth_subscribe("logs", { address: [depositAddresses], topics: [ERC20_TRANSFER_TOPIC] }) через WebSocket к ноде + polling eth_getBlockByNumber как fallback
  • Bitcoin: zmqpubrawtx от Bitcoin Core + периодическое сканирование адресов через scantxoutset
  • TRON: TronGrid WebSocket или polling TronScan API
type DepositMonitor struct {
    node         EthClient
    db           *DB
    confirmations int // минимум подтверждений
}

func (m *DepositMonitor) ProcessBlock(blockNum uint64) {
    receipts := m.node.GetBlockReceipts(blockNum)
    
    for _, receipt := range receipts {
        for _, log := range receipt.Logs {
            if !isERC20Transfer(log) {
                continue
            }
            
            to := common.HexToAddress(log.Topics[2].Hex())
            if !m.db.IsDepositAddress(to) {
                continue
            }
            
            m.recordPendingDeposit(Deposit{
                TxHash:      receipt.TxHash,
                BlockNum:    blockNum,
                UserAddress: to,
                Token:       log.Address,
                Amount:      new(big.Int).SetBytes(log.Data),
            })
        }
    }
}

Подтверждения и finality

Количество требуемых подтверждений зависит от сети и суммы:

Сеть Минимум подтверждений Причина
Bitcoin 3–6 Вероятность реорга
Ethereum 12–20 (или finalized) Post-merge finality
Polygon PoS 100–256 Checkpoint finality
BSC 15–20 PoSA, более централизован
TRON 19 Solid consensus
Solana 32 (finalized) Tower BFT

После достижения порога подтверждений депозит зачисляется на баланс пользователя. До этого — в статусе pending. Отображаем пользователю pending депозиты с индикатором прогресса.

Reorg handling: хранить block_hash вместе с block_number. При обнаружении реорга (хэш блока изменился) — помечать затронутые транзакции как reorged и переначинать мониторинг.

Консолидация средств (sweeping)

Депозитные адреса — тысячи или миллионы. Хранить ETH на каждом адресе — дорого и небезопасно. Нужна автоматическая консолидация на master hot wallet:

func (s *Sweeper) SweepAddress(depositAddr Address) error {
    balance, _ := s.node.GetBalance(depositAddr)
    
    if balance.Cmp(s.minSweepAmount) < 0 {
        return nil // не стоит газа
    }
    
    // Для ERC20: сначала нужно отправить ETH на газ
    if s.token != ETH {
        gasCost := estimateGas(depositAddr, HOT_WALLET, token)
        s.fundGas(depositAddr, gasCost)
    }
    
    // Подписываем через HSM — приватный ключ depositAddr никогда не покидает HSM
    tx := s.buildTransfer(depositAddr, HOT_WALLET, balance)
    signed := s.hsm.Sign(depositAddr, tx)
    return s.node.SendRawTransaction(signed)
}

Для ERC20 токенов задача осложняется: нужен ETH на газ на депозитном адресе. Решения:

  1. Gas station: отправлять ETH перед sweep, потом sweep токенов
  2. Gasless sweep через EIP-2612/permit: если токен поддерживает permit, биржа сама оплачивает газ
  3. Batch sweep через multicall: один вызов собирает средства с множества адресов

Архитектура выводов

Очередь и апрувы

Вывод проходит несколько стадий:

REQUESTED → VALIDATED → APPROVED → SIGNING → BROADCASTING → PENDING → CONFIRMED

VALIDATED: проверка баланса, лимитов, AML/KYC. Если прошёл — резервируем средства (вычитаем из available balance).

APPROVED: для крупных сумм — manual review оператором биржи или мультиподпись (M-of-N апрув от нескольких операторов). Для малых сумм — автоматический апрув.

SIGNING: подпись транзакции в HSM или cold wallet системе. Никогда не подписываем на сервере, где хранится логика апрувов — разделение обязанностей.

BROADCASTING: отправка транзакции в сеть. После этого транзакцию нельзя отменить (теоретически).

Gas management

Biржа должна оплачивать газ за выводы. Нужна система управления газом:

  • Мониторинг eth_gasPrice / EIP-1559 baseFee + maxPriorityFee
  • Бюджет на газ: учитываем стоимость газа в себестоимости вывода или в комиссии
  • RBF (Replace By Fee) для застрявших Bitcoin транзакций
  • EIP-1559 bump: при застревании Ethereum транзакции — отправить с тем же nonce и увеличенным maxFeePerGas
type GasTracker struct {
    mu           sync.Mutex
    currentBase  *big.Int
    priorityFee  *big.Int
}

func (g *GasTracker) RecommendGas(urgency string) GasParams {
    g.mu.RLock()
    defer g.mu.RUnlock()
    
    multiplier := map[string]float64{
        "slow":   1.0,
        "normal": 1.2,
        "fast":   1.5,
    }[urgency]
    
    return GasParams{
        MaxFeePerGas:         multiplyBig(g.currentBase, multiplier * 2),
        MaxPriorityFeePerGas: multiplyBig(g.priorityFee, multiplier),
    }
}

Нотификации и статусы

Пользователь должен видеть состояние вывода в реальном времени. Интеграция:

  • WebSocket push при каждом изменении статуса
  • Email/Telegram уведомления на ключевых этапах (апрув, отправка, подтверждение)
  • Transaction hash с ссылкой на explorer сразу после broadcasting

Безопасность

Критические проверки

Whitelist адресов: требовать добавления нового адреса за 24–48 часов до возможности вывода на него. При добавлении — email подтверждение + 2FA. Предотвращает мгновенный вывод при компрометации аккаунта.

Anti-phishing: отображать anti-phishing код в письмах и UI (пользователь сам его устанавливает). Если его нет — подозрительно.

Лимиты вывода: дневные лимиты по уровням KYC. При превышении — manual review.

Velocity checks: несколько выводов за короткое время → временная блокировка и уведомление.

Hot/Warm/Cold wallet сегрегация

  • Hot wallet: небольшой операционный запас (10–20% от дневного объёма выводов), всегда online, автоматические выводы
  • Warm wallet: multi-sig (2-of-3 или 3-of-5 hardware keys), пополняет hot wallet раз в день
  • Cold wallet: оффлайн хранение, только для крупных резервов, ручная процедура доступа

Распределение: 5–10% hot, 15–20% warm, 70–80% cold. Конкретные цифры зависят от объёмов и модели рисков биржи.

Мониторинг аномалий

type WithdrawalGuard struct {
    limits     map[UserID]DayLimits
    velocities map[UserID][]time.Time
}

func (g *WithdrawalGuard) Check(req WithdrawalRequest) error {
    // 1. Дневной лимит
    if g.limits[req.UserID].Used + req.Amount > g.limits[req.UserID].Max {
        return ErrDayLimitExceeded
    }
    
    // 2. Velocity: не более 5 выводов за 10 минут
    recent := g.getRecentWithdrawals(req.UserID, 10*time.Minute)
    if len(recent) >= 5 {
        return ErrVelocityLimitExceeded
    }
    
    // 3. Новый адрес — только если прошло время карантина
    if !g.isWhitelistedAddress(req.UserID, req.Address) {
        return ErrAddressNotWhitelisted
    }
    
    return nil
}

Инфраструктура и надёжность

Нода vs API провайдер: собственная полная нода даёт надёжность и независимость. API провайдеры (Alchemy, QuickNode, Infura) — удобство, но зависимость от третьей стороны. Для production биржи: несколько провайдеров + собственная нода, failover автоматический.

Идемпотентность: каждый запрос на вывод имеет уникальный withdrawal_id. Повторная обработка одного ID не создаёт дубль транзакции. Критично для восстановления после сбоев.

Transaction monitoring: после broadcasting — периодическая проверка статуса транзакции. Если через N минут не в mempool — считаем дропнутой, отправляем заново с корректным nonce.

Сроки и стоимость

Компонент Срок
Ethereum + ERC20 депозиты/выводы 4–6 недель
Bitcoin 3–4 недели
TRON 2–3 недели
Каждая дополнительная EVM-сеть 1–2 недели
Мультивалютный hot wallet менеджмент 3–4 недели
Admin dashboard для мониторинга 2–3 недели

Полная система для 5-7 сетей с HSM интеграцией, AML проверками и административным интерфейсом — 3–5 месяцев.