Уявіть: ваше крипто-казино обробляє тисячі депозитів на день, але одного разу через баг з ідемпотентністю один користувач отримує подвійне зарахування на $50 000. Або виведення коштів зависає на 12 годин через неоптимальну чергу. Такі інциденти не тільки підривають довіру, але й можуть коштувати ліцензії. З понад 8-річним досвідом та 50+ реалізованими проєктами для клієнтів з ЄС, Азії та СНД ми гарантуємо архітектурну надійність — і знаємо, як уникнути цих проблем на рівні архітектури.
Нижче розберемо ключові компоненти надійної фінансової системи крипто-казино: internal ledger, hot/cold wallet, AML-перевірка та регулярна звірка.
Чому internal ledger — основа надійності?
Крипто-казино не зберігає кошти користувачів безпосередньо на блокчейні. Правильна архітектура — internal ledger (внутрішня бухгалтерська книга). Це стандарт для всіх криптобірж та казино з багатомільйонними оборотами. Double-entry bookkeeping — основа обліку (див. Wikipedia).
Переваги цієї схеми:
- Миттєві операції всередині системи (ставки, бонуси, перекази між іграми) — без очікування блокчейн-підтверджень.
- Можливість дробових балансів нижче мінімальної суми транзакції.
- Повний аудит кожної операції через double-entry ledger.
Double-entry ledger надійніший за простий облік у рази: кожна операція має debit і credit, що виключає арифметичні помилки на рівні архітектури. Ризик розбіжності балансів зводиться до нуля при правильній реалізації.
Як реалізується прийом депозитів?
Ось покроковий процес:
- Генерація унікальної депозитної адреси для кожного користувача через HD Wallet.
- Обробка вхідних транзакцій: система очікує задану кількість підтверджень (залежить від мережі).
- Ідемпотентне зарахування на внутрішній баланс — повторна обробка блокується на рівні БД.
Приклад коду:
class DepositService:
REQUIRED_CONFIRMATIONS = {
"BTC": 2,
"ETH": 12,
"USDT_TRC20": 20,
"SOL": 30,
"BNB": 15,
}
async def get_deposit_address(self, user_id: str, currency: str) -> str:
"""Повертає унікальний deposit address для користувача"""
existing = await self.address_repo.get(user_id=user_id, currency=currency)
if existing:
return existing.address
address = await self.wallet_manager.generate_address(currency, user_id)
await self.address_repo.save(user_id=user_id, currency=currency, address=address)
return address
async def on_incoming_transaction(self, tx: BlockchainTransaction):
"""Викликається при кожній вхідній транзакції"""
address_record = await self.address_repo.find_by_address(tx.to_address, tx.currency)
if not address_record:
return
deposit = PendingDeposit(
user_id=address_record.user_id,
currency=tx.currency,
amount=tx.amount,
tx_hash=tx.hash,
required_confirmations=self.REQUIRED_CONFIRMATIONS.get(tx.currency, 12),
current_confirmations=tx.confirmations,
status="PENDING",
)
await self.deposit_repo.save(deposit)
async def on_confirmation_update(self, tx_hash: str, confirmations: int):
deposit = await self.deposit_repo.get_by_tx(tx_hash)
if not deposit or deposit.status != "PENDING":
return
if confirmations >= deposit.required_confirmations:
await self.credit_user(deposit)
async def credit_user(self, deposit: PendingDeposit):
"""Зараховуємо на внутрішній баланс (ідемпотентна операція)"""
async with self.db.transaction():
if await self.deposit_repo.is_credited(deposit.id):
return
await self.balance_repo.credit(
user_id=deposit.user_id,
currency=deposit.currency,
amount=deposit.amount,
reference=f"DEPOSIT:{deposit.tx_hash}",
)
await self.deposit_repo.mark_credited(deposit.id)
await self.notifier.send_deposit_confirmed(
user_id=deposit.user_id,
amount=deposit.amount,
currency=deposit.currency,
)
Внутрішній облік: double-entry ledger
Весь облік коштів — через ledger з double-entry. Кожна операція — кредит або дебет з reference на джерело. Використовуємо денормалізовану таблицю для швидкого доступу до поточного балансу.
CREATE TABLE ledger_entries (
id BIGSERIAL PRIMARY KEY,
entry_time TIMESTAMPTZ NOT NULL DEFAULT NOW(),
user_id UUID NOT NULL,
currency VARCHAR(16) NOT NULL,
amount NUMERIC(24, 8) NOT NULL,
balance_after NUMERIC(24, 8) NOT NULL,
type VARCHAR(32) NOT NULL,
reference_id VARCHAR(64),
description VARCHAR(255),
INDEX(user_id, currency, entry_time DESC)
);
Поточний баланс користувача обчислюється як сума записів, але для продуктивності зберігається в окремій таблиці з перевірками balance >= locked.
Як працює виведення коштів?
class WithdrawalService:
MIN_WITHDRAWAL = {
"BTC": Decimal("0.0001"),
"ETH": Decimal("0.005"),
"USDT_TRC20": Decimal("5"),
}
async def request_withdrawal(self, user_id, currency, amount, destination_address):
if amount < self.MIN_WITHDRAWAL.get(currency, Decimal("1")):
raise ValidationError(f"Мінімальне виведення: {self.MIN_WITHDRAWAL[currency]} {currency}")
user_balance = await self.balance_repo.get_balance(user_id, currency)
if user_balance.available < amount:
raise InsufficientFundsError()
if not self.validate_address(destination_address, currency):
raise ValidationError("Недійсна адреса призначення")
aml_result = await self.aml_service.check_address(destination_address, currency)
if aml_result.risk_score > 7:
raise ComplianceError("Адреса призначення не пройшла AML перевірку")
async with self.db.transaction():
await self.balance_repo.lock_funds(user_id, currency, amount)
request = WithdrawalRequest(
user_id=user_id,
currency=currency,
amount=amount,
destination=destination_address,
status="PENDING",
aml_score=aml_result.risk_score,
)
await self.withdrawal_repo.save(request)
await self.withdrawal_queue.enqueue(request.id)
return request
async def process_withdrawal(self, request_id):
request = await self.withdrawal_repo.get(request_id)
if request.amount_usd > 10_000:
if not request.manual_approved:
await self.notify_compliance_team(request)
return
try:
tx_hash = await self.hot_wallet.send(
currency=request.currency,
to=request.destination,
amount=request.amount - self.get_network_fee(request.currency),
)
await self.withdrawal_repo.mark_sent(request.id, tx_hash)
except InsufficientHotWalletFunds:
await self.alert_treasury("Hot wallet потребує поповнення")
await self.withdrawal_repo.mark_queued(request.id)
Hot/Cold Wallet управління
Hot wallet — онлайн гаманець для обробки виведень. Повинен містити лише операційний запас: 15–20% сумарних коштів користувачів. Cold wallet — офлайн зберігання. Multi-signature (3-з-5 ключів), ключі зберігаються у різних відповідальних осіб. Поповнення hot wallet — ручний процес з кількома підписами.
| Характеристика | Hot Wallet | Cold Wallet |
|---|---|---|
| Доступ | 24/7 онлайн | Офлайн, підключається за необхідності |
| Частка коштів | 15-20% | 80-85% |
| Підпис | Один ключ (або 2FA) | Multi-signature (3 з 5) |
| Швидкість виведення | Миттєво | Потрібне ручне переміщення |
| Ризик злому | Вищий, але сума обмежена | Мінімальний |
class HotWalletManager:
TARGET_BALANCE_PCT = 0.15
LOW_BALANCE_THRESHOLD_PCT = 0.05
async def check_balance_health(self, currency):
hot_balance = await self.get_hot_wallet_balance(currency)
total_user_balances = await self.balance_repo.get_total_user_balance(currency)
ratio = float(hot_balance / total_user_balances) if total_user_balances > 0 else 1.0
if ratio < self.LOW_BALANCE_THRESHOLD_PCT:
await self.alert_treasury(
f"Hot wallet {currency} низький: {ratio:.1%} від балансів користувачів. "
f"Потрібне поповнення: {total_user_balances * Decimal('0.15') - hot_balance:.4f} {currency}"
)
Reconciliation: захист від розбіжностей
Щоденно звіряємо внутрішні баланси з реальними блокчейн-даними. Будь-яка помилка в коді або зловживання миттєво виявляються. Автоматична система сповіщає фін-відділ при розбіжності понад 0.0001 одиниці валюти. За весь час роботи ми не допустили жодної фінансової втрати у клієнтів завдяки цій системі. Наші системи обробляють до 50 000 транзакцій щоденно з 99.99% аптаймом.
Які мережі блокчейнів підтримуються?
Ми підтримуємо Ethereum, Polygon, Arbitrum, Optimism, Base, Solana, BNB Chain, а також USDT на TRC20 та ERC20. За запитом додаємо будь-яку EVM-сумісну мережу. У таблиці нижче вказані мінімальні суми виведення та кількість підтверджень для кожної мережі.
| Мережа | Мінімальне виведення | Підтвердження |
|---|---|---|
| Bitcoin | 0.0001 BTC | 2 |
| Ethereum | 0.005 ETH | 12 |
| USDT TRC20 | 5 USDT | 20 |
| Solana | 0.01 SOL | 30 |
| BNB Chain | 0.01 BNB | 15 |
Що входить у роботу
- Архітектура internal ledger з double-entry та idempotency.
- Генерація унікальних депозитних адрес через HD Wallet.
- Обробка вхідних транзакцій з налаштовуваним числом підтверджень.
- Виведення коштів з інтеграцією AML-перевірки та черги завдань.
- Hot/cold wallet управління з алертами.
- Система щоденної звірки.
- Документація API та стратегія бекапів.
- Технічна підтримка на етапі запуску.
Як отримати надійну систему?
Замовте аудит вашої системи — ми виявимо вразливості. Зв'яжіться з нами, щоб обговорити інтеграцію та отримати консультацію.







