Мы сталкивались с ситуацией, когда DeFi-протокол терял 12 млн USDC из-за взаимодействия с адресом, включённым в санкционный список OFAC через 40 минут после публикации. Система блокировки подозрительных адресов должна проверять каждый запрос против актуального blacklist с latency <10ms и пропускной способностью до 10 000 rps. Мы строим двухуровневую архитектуру: on-chain смарт-контракт для децентрализованных протоколов и off-chain сервис для централизованных бирж. Гарантируем точность с нулевым false negative и снижение gas cost на 15%.
Как работает автоматическое обновление системы блокировки подозрительных адресов?
Ключевая проблема — источники санкционных списков обновляются асинхронно. OFAC публикует обновления несколько раз в неделю, Chainalysis — в real-time. Наша система объединяет их через единый API с использованием ETag и кэширования. Это позволяет синхронизировать blacklist менее чем за 300 секунд после выхода обновления. Благодаря Bloom filter вероятность false positive не превышает 0.1% при скорости проверки адреса менее 5 мс.
// Cron: каждый час проверяем обновления OFAC @Cron("0 * * * *") async syncOFACList() { const etag = await this.cache.get("ofac_etag"); const response = await fetch("https://www.treasury.gov/ofac/downloads/SDN_advanced.xml", { headers: etag ? { "If-None-Match": etag } : {}, }); if (response.status === 304) return; // не изменился const xml = await response.text(); const addresses = parseOFACCryptoAddresses(xml); await this.blocklist.updateAddresses(addresses, "OFAC"); await this.cache.set("ofac_etag", response.headers.get("ETag")); this.logger.log(`OFAC sync: ${addresses.length} crypto addresses`); } Для Chainalysis используем streaming API — каждое новое подозрительное событие немедленно отправляется в очередь RabbitMQ и обрабатывается за <500ms.
Почему двухуровневая архитектура необходима для системы блокировки подозрительных адресов?
Однослойный on-chain блоклист неэффективен для high-load систем: gas cost при каждой транзакции высок, а обновление занимает время. Мы разделяем on-chain (смарт-контракт) и off-chain (сервис с Bloom filter) уровни. Off-chain проверка через Bloom filter в 5 раз быстрее полного сканирования, а on-chain модификатор notBlocked добавляет всего 100 gas к обычному вызову. False positive rate настраивается — обычно менее 0.1% при нулевом false negative.
| Метрика | On-chain | Off-chain |
|---|---|---|
| Latency проверки | ~500 ms (включая gas) | <5 ms |
| Пропускная способность | ~100 rps | >10 000 rps |
| Стоимость на запрос | ~100 gas | <0.001 USD |
| False negative | 0% | 0% |
| Источник | Обновление | Стоимость | Поддержка |
|---|---|---|---|
| OFAC SDN | Несколько раз/неделю | Бесплатно | Да |
| EU Sanctions | Раз/день | Бесплатно | Да |
| Chainalysis | Real-time | Платно | API |
| Elliptic | Real-time | Платно | API |
On-chain блоклист (для смарт-контрактов) — разработка системы блокировки
contract AddressBlocklist { // Управление через multisig или governance address public admin; mapping(address => bool) public blocked; mapping(address => string) public blockReasons; event AddressBlocked(address indexed addr, string reason); event AddressUnblocked(address indexed addr); function blockAddress(address addr, string calldata reason) external onlyAdmin { blocked[addr] = true; blockReasons[addr] = reason; emit AddressBlocked(addr, reason); } function blockBatch(address[] calldata addrs, string calldata reason) external onlyAdmin { for (uint i = 0; i < addrs.length; i++) { blocked[addrs[i]] = true; blockReasons[addrs[i]] = reason; } } modifier notBlocked(address addr) { require(!blocked[addr], string.concat("Address blocked: ", blockReasons[addr])); _; } } // Использование в протоколе contract Protocol is AddressBlocklist { function deposit(uint256 amount) external notBlocked(msg.sender) { // логика депозита } } Off-chain блоклист (для бирж и сервисов)
Для высоконагруженных систем — Redis Bloom Filter для быстрой проверки принадлежности адреса к blocklist. Bloom filter снижает latency в 5 раз по сравнению с полным сканированием базы.
class AddressBlocklistService { private bloomFilter: RedisBloom; private exactBlocklist: Set<string>; async isBlocked(address: string): Promise<BlockStatus> { const normalized = address.toLowerCase(); // Bloom filter: false позитивы возможны, false негативы — нет if (!await this.bloomFilter.exists(normalized)) { return { blocked: false }; // быстрый ответ: точно не в blocklist } // Exact check для подтверждения (bloom filter мог дать false positive) const exactMatch = await this.db.findBlockedAddress(normalized); if (!exactMatch) return { blocked: false }; return { blocked: true, reason: exactMatch.reason, source: exactMatch.source, addedAt: exactMatch.addedAt, }; } async updateFromSanctionsList(): Promise<void> { // OFAC SDN список (обновляется несколько раз в неделю) const ofacAddresses = await fetchOFACCryptoAddresses(); // Chainalysis Sanctioned Addresses список const chainalysisAddresses = await this.chainalysis.getSanctionedAddresses(); const allNew = [...ofacAddresses, ...chainalysisAddresses]; for (const addr of allNew) { await this.bloomFilter.add(addr.address.toLowerCase()); await this.db.upsertBlockedAddress({ address: addr.address.toLowerCase(), reason: addr.reason, source: addr.source, }); } } } Детали реализации Bloom filter
Мы используем RedisBloom с конфигурацией, оптимизированной под ожидаемое количество адресов (до 1 млн) и желаемый false positive rate (0.01%). Это позволяет держать память в пределах 2 MB.Как внедрить систему: пошаговый план для вашего проекта
- Анализ архитектуры — определяем ваши сценарии (DeFi, CEX, NFT) и выбираем подход: on-chain, off-chain или гибрид. Оцениваем текущую нагрузку: средний RPS, количество активных пользователей.
- Выбор источников блоклиста — подключаем OFAC SDN, EU Sanctions, платные API (Chainalysis, Elliptic) или community-списки. Настраиваем автоматическое обновление с интервалом от 5 минут до 1 часа.
- Разработка смарт-контрактов — реализуем AddressBlocklist с модификаторами и batch-операциями. Интегрируем multisig для управления. Gas-оптимизация: используем mapping и event-driven логику.
- Создание off-chain сервиса — разворачиваем Redis с Bloom filter, настраиваем очередь RabbitMQ для real-time обновлений. Обрабатываем up to 10 000 rps с latency <5 ms.
- Тестирование и аудит — покрываем unit-тестами (Foundry/Hardhat), используем Slither для статического анализа, проводим fuzzing на Echidna. Проверяем ложные срабатывания на исторических данных за 6 месяцев.
- Деплой и мониторинг — развертываем на mainnet/testnet с многофазным запуском. Подключаем Tenderly для отслеживания gas и TPS. Настраиваем алерты при массовых блокировках.
Что входит в работу
- Архитектура: проектирование on-chain/off-chain компонентов с учётом ваших сценариев (DeFi, CEX, NFT).
- Реализация: смарт-контракты (Solidity), серверная часть (TypeScript, Redis), интеграция с источниками.
- Документация: API-схемы, инструкции по развертыванию, руководство администратора.
- Обучение: короткая сессия для команды по эксплуатации и решению инцидентов.
- Поддержка: 2 недели пост-релизного сопровождения, исправление ошибок.
Ориентировочные сроки разработки — от 2 до 3 недель. Стоимость рассчитывается индивидуально на основе объёма интеграций и SLA.
Закажите разработку системы защиты вашего протокола уже сегодня. Получите консультацию по внедрению — наши инженеры с 6-летним опытом в Web3 помогут подобрать оптимальное решение для вашего проекта.







