Перейти к основному содержимому

Практикум — шаг 4: compliance и тесты

Разработчику Аналитику

← Шаг 3 · Шаг 4 · Обзор

Завершаем практикум слоем compliance и автотестами. Этот слой отделяет учебную игрушку от сервиса, который можно показывать комплаенсу и аудиторам.


KYC-уровни

class KycLevel(str, Enum):
NONE = "none"
BASIC = "basic"
ENHANCED = "enhanced"
УровеньВ практикумеНа бирже
noneСуточный лимит 100 LAB, крупные переводы запрещеныОграниченный вывод
basicОбычные переводы после «проверки паспорта»Стандартный retail
enhancedПереводы ≥ 1000 LABVIP, юрлица, источник средств

Пороги заданы константами в compliance.py — в продакшене они приходят из конфигурации и политик AML.


Проверки перед переводом

def check_transfer(self, sender, recipient, amount) -> tuple[bool, str]:
if recipient in SANCTIONED_ADDRESSES:
return False, "адрес в учебном sanctions-списке"
...
if amount >= ENHANCED_KYC_THRESHOLD and profile.kyc_level is not KycLevel.ENHANCED:
return False, "крупный перевод требует enhanced KYC"

Типичные категории в реальных системах:

  • Sanctions screening (списки OFAC, МВФ, национальные перечни).
  • Лимиты по KYC (суточные / месячные).
  • Travel Rule для крупных переводов (передача данных контрагента между VASP).

Материал про KYC на биржах — в главе о криптовалютах и вводной.


Журнал аудита (audit log)

Каждое решение compliance записывается:

def _audit(self, event: str, **fields: Any) -> None:
self.audit_log.append({"ts": time.time(), "event": event, **fields})

События: register, kyc_update, transfer_ok, blocked_kyc, blocked_sanctions.

В продакшене журнал:

  • пишется в append-only хранилище (WORM, отдельная БД);
  • коррелирует с trace_id HTTP-запроса;
  • хранится по срокам политики (годы).

Для разбора инцидента выведите хвост в demo.py:


import json

print(json.dumps(ledger.compliance.audit_log[-3:], indent=2, ensure_ascii=False))

Автотесты (pytest)

Из корня ledger-lab/:

pytest -q

Пример теста целостности цепи (tests/test_ledger.py):

from ledger_lab.block import genesis_block
from ledger_lab.chain import Blockchain

def test_chain_after_mine():
chain = Blockchain(difficulty=1)
chain.mine_block([{"type": "transfer", "amount": 1}])
ok, _ = chain.is_valid()
assert ok
СценарийЧто проверить
Цепочка после mine_blockis_valid() → успех
Подмена transactions без нового хешаis_valid() → отказ
Подпись Ed25519sign / verify на одном сообщении
Vault AESround-trip PEM с паролем
Крупный перевод без enhanced KYCsubmit_transfer → отказ
Адрес из sanctions-спискаsubmit_transfer → отказ

Тесты — живой чек-лист регрессии. На каждое правило compliance заведите отдельный кейс «ожидаем отказ» и «ожидаем успех».


Дисклеймер и право

Практикум иллюстрирует технические механизмы. Запуск обмена криптоактивами для клиентов в РФ и других странах требует правового анализа (лицензии, 115-ФЗ, FATF, GDPR для данных KYC). Учебный код не является готовым compliance-решением.


Куда развивать проект

Идеи для самостоятельной доработки (от простого к сложному):

  1. REST API (FastAPI) поверх Ledger — эндпоинты POST /transfer, GET /chain.
  2. Стакан заявок — лимитные заявки buy/sell и matching в памяти.
  3. Persist — SQLite для цепи и audit log; перезапуск без потери истории.
  4. P2P — два процесса обмениваются блоками и выбирают длинную цепь (replace_chain).
  5. Testnet — подключение к Sepolia через web3.py только для чтения блоков (без хранения ключей в коде).

Смежные разделы:


Итог практикума

Вы собрали приложение, где:

  • Блокчейн отвечает за неизменяемый журнал операций.
  • Криптография подтверждает авторство переводов и защищает секреты.
  • Ledger моделирует учёт активов и очередь транзакций.
  • Compliance показывает, как продуктовые правила стоят перед движением средств.

Вернитесь к обзору или к итогам раздела, чтобы связать практику с теорией.

См. также

Другие статьи этого же раздела в боковом меню (как на странице "О разделе").