Розробка системи мультичейн-виплат

Проєктуємо та розробляємо блокчейн-рішення повного циклу: від архітектури смарт-контрактів до запуску DeFi-протоколів, NFT-маркетплейсів та криптобірж. Аудит безпеки, токеноміка, інтеграція з наявною інфраструктурою.
Показано 1 з 1Усі 1306 послуг
Розробка системи мультичейн-виплат
Складний
~1-2 тижні
Часті запитання

Напрямки блокчейн-розробки

Етапи блокчейн-розробки

Останні роботи

  • image_website-b2b-advance_0.webp
    Розробка сайту компанії B2B ADVANCE
    1311
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1222
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    922
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1151
  • image_logo-advance_0.webp
    Розробка логотипу компанії B2B Advance
    614
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    887

Розроблення системи мультичейн-оплати

Приймати крипто-платежі "в одній мережі" — давно вирішена задача. Але як тільки клієнт хоче приймати платежі в ETH, USDC, BNB, SOL, USDT на Tron та також Bitcoin — це уже архітектурна задача. Кожна мережа має свою модель адрес, фіналізацію транзакцій, ризики двійного видатків, SDK та вимоги до нод. Склеїти все це в єдину надійну систему — нетривіально.

Ключові архітектурні рішення

Перш ніж писати код, потрібно прийняти три рішення, які визначають всю архітектуру.

Custodial vs Non-custodial

Custodial — система сама зберігає кошти до вивезення мерчантом. Простіше технічно, але вимагає ліцензування (у більшості юрисдикцій зберігання чужих крипто-активів = фінансова діяльність). Вимагає HSM або MPC для ключів, регулярні аудити.

Non-custodial — кошти напрямо на адреси мерчанта, система тільки детектує платежі. Технічно складніше (немає єдиного hot wallet), але регуляторно чистіше. Більшість B2B рішень використовують цей підхід.

HD Wallet vs Smart Contract адреси

HD Wallet (BIP32/BIP44) — генеруємо унікальну deposit адресу для кожного платежу з одного seed. m/44'/60'/0'/0/invoice_id — кожен invoice отримує свою адресу. Працює для всіх EVM мереж та Bitcoin. Моніторинг: підписуємося на події всіх генерованих адрес.

import { HDNodeWallet, Mnemonic } from 'ethers';

function generateDepositAddress(mnemonic: string, invoiceId: number): string {
  const wallet = HDNodeWallet.fromPhrase(
    mnemonic,
    `m/44'/60'/0'/0/${invoiceId}`
  );
  return wallet.address; // одинакова адреса для всіх EVM мереж
}

Важливо: Bitcoin та Solana потрібні різні derivation paths (BIP44 coin types: 0 для BTC, 501 для SOL, 60 для ETH).

Smart Contract підхід (Forward Contract / Payment Splitter) — кожному мерчанту розгортається або назначається смарт-контракт, який автоматично форвардить кошти на головну адресу. Зручно для EVM мереж: одна адреса, будь-які токени, автоматична обробка. CREATE2 дозволяє обчислити адресу контракту до розгортання — можна дати клієнту адресу одразу, розгорнути контракт тільки при першому платежі.

// CREATE2 factory для deterministic deposit адреси
contract DepositFactory {
    function getDepositAddress(bytes32 salt) external view returns (address) {
        return Create2.computeAddress(salt, keccak256(type(ForwardDeposit).creationCode));
    }
    
    function deployDeposit(bytes32 salt, address recipient) external returns (address) {
        return address(new ForwardDeposit{salt: salt}(recipient));
    }
}

Requirement for Confirmations

Різні мережі вимагають різну кількість підтверджень для безпечної фіналізації:

Мережа Рекомендовані підтвердження Час
Bitcoin 3-6 30-60 хв
Ethereum 12-20 3-4 хв
BNB Chain 15-20 45-60 сек
Polygon 256 ~8 хв
Solana 32 (finalized) ~15 сек
Tron 20 ~1 хв
Arbitrum 1 (L2) <1 сек

Polygon PoS має глибокі реорги — 256 підтверджень для safe finality не перебільшення. Arbitrum успадковує фіналізацію від Ethereum після settlement.

Архітектура системи

[Payment Gateway API]
        ↓
[Invoice Service] ← зберігає invoice state, triggers, webhooks
        ↓
[Address Generator] ← HD wallet або CREATE2 factory
        ↓
[Chain Monitors] ← один процес на мережу
  ├─ EthereumMonitor   (WebSocket eth_subscribe)
  ├─ BscMonitor        (WebSocket)
  ├─ SolanaMonitor     (WebSocket account subscribe)
  ├─ TronMonitor       (Event API polling)
  └─ BitcoinMonitor    (ZMQ або Electrum)
        ↓
[Confirmation Tracker] ← очікує N підтверджень
        ↓
[Webhook Dispatcher] ← повідомляє мерчанта

Chain Monitors — найбільш критичний компонент. Кожен монітор повинен:

  • Переживати обриви з'єднання з нодою (auto-reconnect + catch-up)
  • Обробляти реорганізації (invalidate pending confirmations)
  • Детектувати як native coins так і ERC-20/BEP-20/SPL токени
  • Працювати незалежно — падіння одного монітора не повинно крахувати інших

EVM моніторинг

import { createPublicClient, webSocket, parseAbiItem } from 'viem';

const client = createPublicClient({
  chain: mainnet,
  transport: webSocket('wss://eth-mainnet.g.alchemy.com/v2/...'),
});

// Моніторинг ERC-20 Transfer на наші адреси
const unwatch = client.watchEvent({
  event: parseAbiItem('event Transfer(address indexed from, address indexed to, uint256 value)'),
  args: { to: monitoredAddresses },
  onLogs: async (logs) => {
    for (const log of logs) {
      await processIncomingTransfer({
        chain: 'ethereum',
        token: log.address,
        from: log.args.from,
        to: log.args.to,
        amount: log.args.value,
        txHash: log.transactionHash,
        blockNumber: log.blockNumber,
      });
    }
  },
});

Solana моніторинг

Solana має іншу модель: токени зберігаються не на адресі користувача напрямки, а в Associated Token Accounts (ATA). Для прийому USDC потрібно знати ATA адресу користувача для цього токена:

import { Connection, PublicKey } from '@solana/web3.js';
import { getAssociatedTokenAddress, TOKEN_PROGRAM_ID } from '@solana/spl-token';

const USDC_MINT = new PublicKey('EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v');

async function getUsdcDepositAddress(userPublicKey: PublicKey): Promise<string> {
  const ata = await getAssociatedTokenAddress(USDC_MINT, userPublicKey);
  return ata.toBase58();
}

// Моніторинг через WebSocket
const connection = new Connection('wss://api.mainnet-beta.solana.com');
connection.onAccountChange(ataAddress, (accountInfo) => {
  // обробка зміни балансу
});

Bitcoin моніторинг

Для Bitcoin без кастомної ноди можна використовувати Electrum Protocol або сторонні сервіси (BlockCypher API, Tatum). Для серйозної production системи рекомендую власний bitcoind + Electrs (Electrum Rust server):

from electrum_client import ElectrumClient

client = ElectrumClient('127.0.0.1', 50001)

# Підписка на історію адреси
async def monitor_bitcoin_address(address: str):
    script_hash = address_to_scripthash(address)  # sha256(scriptPubKey), reversed
    await client.subscribe_scripthash(script_hash, callback=on_history_change)

Обробка токенів та конвертація

Whitelist токенів. Не приймайте довільні токени — тільки pre-approved список. Інакше зловмисник може відправити worthless ERC-20 токен, який технічно є "платежем".

Slippage при конвертації в stablecoins. Якщо мерчант хоче отримувати USD-еквівалент, система повинна конвертувати волатильні активи. Використовуйте агрегатори (1inch) з tight slippage tolerance та мінімальною сумою конвертації для рентабельності.

Underpayment handling. Клієнт заплатив 99.5 USDC замість 100. Потрібна політика: припустима похибка (звичайно 0.5-1%), partial payment (invoice помічається як partially paid, вимагає доплати), або автоматичний refund. Все це повинно бути в бізнес-логіці, не в смарт-контракті.

Webhook надійність

Повідомлення мерчанта про платіж — критично важливий момент. Webhook може упасти, зависнути, повернути 5xx. Паттерн надійної доставки:

class WebhookDispatcher:
    MAX_ATTEMPTS = 5
    RETRY_DELAYS = [30, 120, 600, 3600, 86400]  # сек: 30с, 2м, 10м, 1ч, 24ч
    
    async def dispatch_with_retry(self, webhook_url: str, payload: dict, attempt: int = 0):
        try:
            async with aiohttp.ClientSession() as session:
                resp = await session.post(
                    webhook_url,
                    json=payload,
                    headers={'X-Signature': self.sign_payload(payload)},
                    timeout=aiohttp.ClientTimeout(total=30)
                )
                if resp.status == 200:
                    await self.mark_delivered(payload['event_id'])
                    return
        except Exception as e:
            log.error(f"Webhook failed attempt {attempt}: {e}")
        
        if attempt < self.MAX_ATTEMPTS:
            await asyncio.sleep(self.RETRY_DELAYS[attempt])
            await self.dispatch_with_retry(webhook_url, payload, attempt + 1)

HMAC-підпис payload (X-Signature header) дозволяє мерчанту верифікувати підлинність уведомлення.

Інфраструктура та безпека

HD wallet ключі — master seed зберігається в KMS (AWS KMS або HashiCorp Vault). Сервіс генерації адреси не зберігає seed локально — запитує KMS на кожну операцію. Derivation індекси зберігаються в БД — втрата їх означає неможливість знайти платежі.

Rate limiting та abuse. Invoice generation повинна бути rate-limited на рівні API key. Невикористані invoice з істекшим строком — архівувати, не видаляти (потрібні для аудиту).

Reconciliation. Щоденна звірка: сумуємо всі підтверджені платежі по нашим даним vs баланс hot wallet (якщо custodial). Розбіжності — алерт одразу.

Стек та терміни

Технологічний стек:

Шар Вибір
API FastAPI (Python) або Fastify (Node.js)
Chain моніторинг Python asyncio / Node.js workers, по одному process на chain
БД PostgreSQL (invoices, transactions) + Redis (pending confirmations, cache)
Черги Redis Streams або RabbitMQ для webhook dispatch
Деплой Kubernetes (High Availability критична)

Етапи розроблення:

  • Базовий EVM моніторинг + invoice flow: 3-4 тижні
  • Додавання Bitcoin та Solana: +2-3 тижні
  • Конвертація в stablecoins: +1-2 тижні
  • Webhook system + dashboard для мерчантів: +2-3 тижні
  • Load testing, security review, production deployment: +2 тижні

Всього для повнофункціональної системи з 5-6 підтримуваних мереж: 10-14 тижнів.