Розробка системи сегрегації активів для кастодіана

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

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

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

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

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

Розробка системи сегрегації активів для кастодіана

Кастодіани — компанії, які професійно зберігають крипто-активи клієнтів. Ключова вимога регуляторів й клієнтів: активи різних клієнтів повинні бути строго розділені. "Спільний пул" неприйнятний: якщо кастодіан несе збитки або банкротується, клієнт повинен мати можливість однозначно ідентифікувати свої активи й отримати їх назад. Це й есть сегрегація.

Нормативний контекст

Вимоги до сегрегації активів визначаються юрисдикцією. MiCA (EU) вимагає відокремлення клієнтських активів від власних. FCA (UK) — аналогічно. SEC для крипто-кастодіанів у США — поки у розробці, але NYDFS BitLicense вже містить вимоги до сегрегації.

Ключова вимога: можливість аудиту. Аудитор у будь-який момент повинен мати можливість сопоставити on-chain адреси з записами про клієнтів й підтвердити, що активи клієнта A не перемішані з активами клієнта B.

Архітектурні моделі сегрегації

Один адрес на клієнта (Full Segregation)

Кожен клієнт отримує унікальну on-chain адресу (або набір адрес — по одній на кожен підтримуваний blockchain). Активи фізично розділені на рівні blockchain.

Переваги:

  • Максимальна прозорість для клієнта й аудитора
  • Простий доказ права власності
  • Ізоляція ризиків: проблема одного клієнта не впливає на інших

Недоліки:

  • Високі operational costs при великій кількості клієнтів (тисячі адрес, окремі gas поповнення для кожної)
  • Складніше оптимізувати ліквідність

Віртуальна сегрегація зі спільним пулом

Активи зберігаються на спільних адресах, але внутрішня база даних веде точний облік долі кожного клієнта. Аналог: банківський рахунок (ви не знаєте в якому фізичному сховищі лежать ваші гроші).

Переваги:

  • Низькі operational costs
  • Простіше управляти ліквідністю

Недоліки:

  • Нормативно складніше обґрунтувати як "сегрегацію"
  • При банкротстві кастодіана — активи клієнтів можуть бути оспорені кредиторами

Гібридна модель

Для крупних клієнтів (інститути) — виділені адреси. Для рітейлу — віртуальна сегрегація з можливістю переводу на dedicated address за запитом.

Детальна архітектура системи

Управління адресами

Ключи зберігаються в HSM. Адреси генеруються детерміновано через HD-derivation:

m/44'/60'/{clientId}'/0/0 → основний адрес клієнта
m/44'/60'/{clientId}'/0/1 → адрес для конкретного активу
m/44'/60'/{clientId}'/1/0 → change адрес

Це дозволяє відновити все адреси з master seed без додаткового сховища.

interface ClientWallet {
  clientId: string;
  blockchain: string;
  address: string;
  derivationPath: string;
  createdAt: Date;
  keyStorageLocation: 'hsm_slot_1' | 'hsm_slot_2'; // для geo-redundancy
}

class AddressManager {
  async createClientAddress(
    clientId: string,
    blockchain: string
  ): Promise<ClientWallet> {
    // Атомарна операція: перевіряємо що адрес ще не створений
    return this.db.transaction(async (trx) => {
      const existing = await trx('client_wallets')
        .where({ clientId, blockchain })
        .first();
      
      if (existing) return existing;
      
      const index = await this.getNextIndex(trx, blockchain);
      const derivationPath = `m/44'/60'/${clientId}'/0/${index}`;
      const address = await this.hsm.deriveAddress(derivationPath);
      
      return trx('client_wallets').insert({
        clientId,
        blockchain,
        address,
        derivationPath,
        createdAt: new Date(),
      }).returning('*');
    });
  }
}

Бухгалтерський облік (Ledger)

Двойна запис обов'язкова. Кожне рух активів повинен балансуватися:

CREATE TABLE ledger_entries (
    id BIGSERIAL PRIMARY KEY,
    entry_type VARCHAR(32) NOT NULL, -- debit/credit
    client_id UUID NOT NULL REFERENCES clients(id),
    asset VARCHAR(64) NOT NULL,    -- ETH, USDC, BTC
    blockchain VARCHAR(32) NOT NULL,
    amount NUMERIC(36, 18) NOT NULL CHECK (amount > 0),
    balance_after NUMERIC(36, 18) NOT NULL,
    reference_type VARCHAR(32), -- deposit, withdrawal, fee, transfer
    reference_id UUID,
    tx_hash VARCHAR(66),
    block_number BIGINT,
    created_at TIMESTAMPTZ DEFAULT NOW() NOT NULL,
    created_by VARCHAR(64) NOT NULL, -- system, user_id
    CONSTRAINT no_negative_balance CHECK (balance_after >= 0)
);

CREATE TABLE client_balances (
    client_id UUID REFERENCES clients(id),
    asset VARCHAR(64),
    blockchain VARCHAR(32),
    balance NUMERIC(36, 18) NOT NULL DEFAULT 0,
    last_updated_at TIMESTAMPTZ DEFAULT NOW(),
    PRIMARY KEY (client_id, asset, blockchain)
);

Reconciliation. Щодня система повинна сверяти on-chain баланси з записами у ledger:

async function reconcile(blockchain: string, asset: string): Promise<ReconciliationResult> {
  const clientWallets = await db.clientWallets.findAll({ blockchain });
  
  const results = await Promise.all(
    clientWallets.map(async (wallet) => {
      const onChainBalance = await getOnChainBalance(wallet.address, asset);
      const ledgerBalance = await db.clientBalances.getBalance(
        wallet.clientId, asset, blockchain
      );
      
      const discrepancy = onChainBalance - ledgerBalance;
      
      return {
        clientId: wallet.clientId,
        address: wallet.address,
        onChainBalance,
        ledgerBalance,
        discrepancy,
        status: Math.abs(discrepancy) < TOLERANCE ? 'ok' : 'mismatch',
      };
    })
  );
  
  const mismatches = results.filter(r => r.status === 'mismatch');
  if (mismatches.length > 0) {
    await this.alertService.sendAlert('RECONCILIATION_MISMATCH', mismatches);
  }
  
  return { results, mismatches, timestamp: new Date() };
}

Моніторинг вхідних депозитів

Система повинна відслідковувати все вхідні транзакції на адреси клієнтів й автоматично зараховувати:

class DepositMonitor {
  async watchAddress(address: string, clientId: string) {
    // Підписка на нові блоки через WebSocket
    this.provider.on('block', async (blockNumber) => {
      const block = await this.provider.getBlock(blockNumber, true);
      
      for (const tx of block.transactions) {
        if (tx.to?.toLowerCase() === address.toLowerCase()) {
          await this.processDeposit({
            clientId,
            txHash: tx.hash,
            amount: tx.value,
            asset: 'ETH',
            blockNumber,
          });
        }
      }
    });
    
    // Також відслідковуємо ERC-20 Transfer події
    this.monitorERC20Transfers(address, clientId);
  }
  
  private async processDeposit(deposit: DepositEvent) {
    // Чекаємо confirmations (зазвичай 12-20 для finality)
    await this.waitForConfirmations(deposit.txHash, REQUIRED_CONFIRMATIONS);
    
    await this.db.transaction(async (trx) => {
      // Перевіряємо ідемпотентність
      const existing = await trx('deposits').where({ txHash: deposit.txHash }).first();
      if (existing) return;
      
      // Записуємо депозит
      await trx('deposits').insert(deposit);
      
      // Оновлюємо ledger
      await this.ledger.credit(trx, deposit.clientId, deposit.asset, deposit.amount);
    });
  }
}

Вывід коштів (Withdrawal)

Вывід завжди вимагає approval workflow. Після approval:

  1. Перевірка балансу клієнта у ledger
  2. Резервування коштів (debit pending)
  3. Підпис транзакції у HSM
  4. Broadcast on-chain
  5. Очікування confirmations
  6. Фінальне списання з ledger (або reversal при failure)

Idempotency. Кожен withdrawal request має унікальний idempotency key. Повторний запит з тим же ключем повертає статус існуючого, не створює новий.

Proof of Reserves

Для публічного підтвердження платоспроможності — Merkle tree на основі client balances:

// Кожен клієнт отримує proof що його баланс включений в загальне дерево
// Без розкриття даних інших клієнтів
async function generateProofOfReserves(): Promise<ProofOfReserves> {
  const balances = await db.getAllClientBalances();
  
  // Будуємо Merkle tree
  const leaves = balances.map(b => 
    keccak256(encode(['address', 'uint256'], [b.address, b.balance]))
  );
  
  const tree = new MerkleTree(leaves, keccak256, { sort: true });
  
  // Публікуємо root on-chain
  await proofOfReservesContract.updateRoot(tree.getRoot());
  
  return {
    root: tree.getRoot(),
    totalBalance: balances.reduce((sum, b) => sum + b.balance, 0n),
    timestamp: Date.now(),
    proofs: balances.map((b, i) => ({
      clientId: b.clientId,
      proof: tree.getProof(leaves[i]),
    })),
  };
}

Compliance й аудит

Audit trail. Все операції з неізмінною історією. Логи зберігаються в append-only сховищі (AWS QLDB або PostgreSQL з audit triggers).

Reporting. Щомісячні звіти для кожного клієнта: рух коштів, комісії, поточні баланси. Щоквартальні для аудиторів: reconciliation reports, proof of reserves.

KYT (Know Your Transaction). Інтеграція з Chainalysis, Elliptic або TRM Labs для перевірки вхідних транзакцій на зв'язок із санкційними адресами й mixer-ами.

Стек

Компонент Технологія
HSM AWS CloudHSM або Thales
Database PostgreSQL + AWS QLDB (audit log)
Blockchain monitoring Alchemy/Infura + own indexer
Reconciliation Cron job + alerting
KYT Chainalysis Reactor API
API Node.js + TypeScript, REST + gRPC
Frontend React (admin dashboard)

Сроки

  • Core ledger + address management: 6-8 тижнів
  • Deposit monitoring + withdrawal flow: 4-6 тижнів
  • Reconciliation + proof of reserves: 3-4 тижні
  • KYT integration + compliance reporting: 3-4 тижні
  • Security audit: обов'язковий, +4-8 тижнів

Итого: 5-6 місяців до production-ready системи.