Философия, мысли и спойлеры
Добрый день, уважаемые хабровчане ;). Мы продолжаем серию публикаций о нашем участии в «разношерстных» хакатонах, проводящихся под эгидой коммерческих, государственных и иных организаций самого необычного формата, направленности, специфики, толка и рассуждений.
В общем, мы стараемся на зацикливаться на конкретно одной тематике и/или специфике, и постоянно пробуем себя, в различных направлениях. Да, не скрою, порой мы ввязываемся в, откровенно, рискованные истории, там, где совсем не имеем опыта и/или имеем крайне отдаленное представление о том, что от нас требуется ;)). Плохо это или хорошо, тут можно мыслить двояко, однако, у нас получается, учитывая, что из 10 хакатонов, которые мы провели 8 оказались, для нас успешными (или почти) и мы весьма преуспели на этом поприще соревновательного Data Science.
При этом, выходя на хак, мы для себя уже составили небольшой роадмап, что нам, в целом, интересно, помимо решения предложенного кейса и на что мы акцентируем внимание в первую очередь:
Во-первых, мы постоянно «щупаем» рынок и смотрим, что сейчас востребовано, на что направленны усилия бизнеса, что ему интересно и какие, в этой связи, наработки можем предложить мы исходя из наших возможностей и познаний;
Во‑вторых, только самые нестандартные решения и задачи на «стыке», и я бы даже сказал, на конфликте интересов, дают совершенно уникальные прорывы. Так было у нас часто, когда для определения эпилепсии (на одном из хакатоне) мы использовали высокочастотные алгоритмы из трейдинга и получили точность в 97%, или, когда мы применяли решения из теории графов к задачам информационной безопасности. Во многом это дает развитие новых подходов и получается посмотреть на задачу с иного угла, а не заниматься бесконечной оптимизацией наработанных уже существующих технологий;
В‑третьих, мы всегда «мониторим» стек передовых разработок, тем самым оперативно пополняем свой багаж новыми идеями и анализом решений конкурентов, будь то подходы, модели, методики и/или практики кодинга. Сюда же входят стратегии, анализ и идейная составляющая заявленных кейсов. Тут идет вход буквально все от обширного поиска идей и решений по всем имеющимся ресурсам до рассмотрения самых бредовых и невероятных идей;
В‑четвертых, это проверка своих сил, и понимания неких политических процессов и веяний от текущих экономических реалий, в которые мы все погружены и должны учитывать при корректировки своих научных задач, потребностей, направлений разработки и экспертной мысли. Во многом, это позволяет понять куда «дует» ветер и что надо заказчику, что у него в голове, о чем он думает и самое главное, во что он готов инвестировать.
В‑пятых, это разработка собственных внутренних продуктов, расширение деловых связей, обкатка «домашних заготовок», тактик, подходов и анализа работы готовых инструментов, оттачивания сложившихся настроений и взглядов на разработку ПО.
Как видите, задачи и решения весьма и весьма разноплановые, но в общем, укладываются в единую канву и специфику спортивного Data Science, алгоритмизации, кодинга, математики и философии программирования в целом.
Примерно, с такими же настроениями, мы пришли и на этот (DeFi-2025, Сбер) очередной хак, посвященный разработке блокчейн-решений и анализу уязвимостей смарт-контрактов и web-3.
Забегая вперед скажу, что нам не хватило, каких-то 0.06% для того, чтобы войти в топ-8 номинируемых команд. В общем, мы получили по сумме баллов за наше решение 13.44, тогда как у лидера было порядка 16. Отрыв небольшой, учитывая сложность задачи и ее первоначальное очень жесткое условие: одним из проходных критериев было создать уникальное решение, до этого нигде не фигурирующее в цифровом поле до 2025 года текущего месяца. С таким мы столкнулись впервые и были немного удивлены. Да. хакатон и подразумевает нечто подобное, но все же надо было понять, что вместе с нами было еще 28 команд, и они тоже умеют гуглить ;)). Наша команда называлась BlockTeam.

Организация, команда и все-все-все
Итак, полетели карусели ;)). Всегона хак было выделено 3 недели: анализ, запилы, допилы, перепилы и снова перетяжка синей изолентой со всеми костылями, ночными созвонами, случайными волшебными озарениями, паникой на борту и литрами поглощённого кофе. Скажу сразу, мне понравилось, и команда тоже откровенно кайфанула, а как должно быть по‑другому на соревнованиях ;)). Говоря о команде, мызашли на хак с «ноги» втроем и как-то быстро раскинули задачи. Прикинули, что за чем идет и кто что делает, при том, что бодрая коммуникация созрела в головах как-то сама собой. Более того, к нам присоединился человек и другого вуза и получилось сборная Red-Team по анализу смарт-контрактов:
Владимир Миронов (это я) (Финансовый университет при Правительстве РФ): аналитика, проработка общего решения, математика, тестирование гипотез и уязвимостей смарт-контрактов, конвертация смарт-контрактов в графы, файн-тюнинг моделей машинного обучения, общая мотивация и задор и научный руководитель по курсовой Александра Лобова;
Александр Лобов (Финансовый университет при Правительстве РФ): аналитика, анализ работы смарт-контрактов, работа с инструментами по взлому смарт-контрактов, поиск багов, бэкенд, разработка моделей машинного обучения, чил на уровне серфера и запиленный за неделю курсач, который, кстати лег в базу этого хака;
Санников Николай (МГТУ им. Баумана): аналитика, анализ работы смарт-контрактов, разработка сайта, поднятие чат-бота, фронтенд, DevOps, дизайн, ресерч, тайминг вкупе с дожиманием идеи и неиссякаемый юмор.
Теперь кейсы. Нам на выбор предложили 6 раскаток, в общем и целом, одного ковша разлива, если подходить максимально широко и открыто, но это и хорошо. Нам не пришлось долго выбирать и терзаться сомнениями, что и как, а то или не то, и мы сразу «погнали» в бой. Да, надо отдать должное организаторам и перечислить все‑таки все таски какие они были в дикой природе, так вот:
Сервис для защиты персональной информации;
Протокол восстанавливаемых биометрических ключей;
Сервис по аналитике и мониторингу смарт-контрактов и отслеживанию изменений в них (наш);
ZkKYC — сервис, который позволит упростить пользовательский опыт в части KYC;
Платформа оракулов;
По таймингу было 26 марта — 12 мая — сам период проведения хакатона,12 мая — дедлайн подачи решений; 30 мая — публичные питчи финалистов на митапе. Дополнительно нам еще обозначили, что надо сделать поддержку сети TRON (это был отдельный челендж с блекджеком и анализом красоты, но об этом чуть позже). Кроме всего, нам выкатили требования, что хотелось бы увидеть и более того сделали акцент, что, если кто‑то сделает решение задачи на графах, это будет, прям самый самолет. И мы такое сделали)))


Разработка, тестирование и суровая математика
Мы для себя взял задачку по мониторингу смарт‑контрактов и более того, она была один в один похожа на тему курсовой Александра («Моделирование и анализ поведения смарт‑контрактов на блокчейнах с использованием ML»), которую я предложил Саше в нашем универе. Разработали концепт, идею, вектор движения и направленности, быстро обсудили, прикинули тулзы и история «покатилась». Саша «мухой» написал, работу, отлично защитил ее, показал уверенное знание предмета и что не маловажно, мы получили качественно‑полное решение с моделью машинного обучения и анализом.
Однако, для хака этого было мало, и мы «завернули» наше решение в кое‑что помоднее. Мы стали думать, как подойти к анализу уязвимостей более полно. Наша задача состояла в разработке анализатора уязвимостей для смарт‑контрактов и оценке того, как наиболее полно можно проводить тестирование, а главное загодя. При этом, мы предложили «перегонять» смарт‑контракты в графы, далее исследуя топологию графов проводить оценку структуры и выявлять характерные паттерны. Более того, подобные паттерны мы сделали и для CVE (уязвимости смарт‑контрактов). Сравнивая механизмы и сигнатуры смартов и CVE, мы можем анализировать и на «горячую», говорить о том является ли смарт‑контракт уязвимым или нет.
Смысл этого решения заключается в том, что мы еще до «прогонки» CVE по смарту уже примерно знаем пул уязвимостей, которые возможно отработают и можем расширить его подобрав подобные по имеющимся сигнатурам и, более того, рассмотреть модифицированные варианты.
Данный подход позволил более комплексно подойти к анализу смартов, быстрее получать список возможных проблемных случаев и устранять возможные коллизии, при том что мы подошли к уязвимостям с разных сторон, одна из которых являлось представление в виде графов. Более того, графы оказались очень чувствительными к изменениям: если в смарте что‑то поменяется будь то точка, запятая или пробел, то сразу мы это увидим на наших метриках и сможем оперативно отследить с нахождением точки изменений.
То есть мы не только проводим точный анализ появления уязвимости точь‑в-точь, но и задаем вероятностное пространство появление новых, зачастую даже не задокументированных уязвимостей. А так как использование смартов нацелено на финансовые транзакции, актуальность данного решения была более чем очевидна.
Итак, при построении итогового графа мы ориентировались еще и на метрики для анализа их геометрии, коих придумали порядка 28. Список, конечно, является не полным, и мы постоянно его расширяем и дополняем (да продолжаем проект, уже в рамках более расширенного класса задач), но все же решили выкатить:
Минимальное расстояние между вершинами;
Средняя длина ребра (Average rib length, ARL);
Дисперсия длин рёбер (Dispersion of edge lengths, DEL);
Максимальное отклонение углов (Maximum angle deviation, MAD);
Пересечения рёбер (Rib crossings, RC);
Площадь покрытия (Coverage area, CA);
Коэффициент сохранения соседних вершин (Conservation coefficient of neighboring vertices, CNF);
Степень соблюдения слоев (Degree of adherence to layers, DAL);
Расстояние центров масс компонентов (Distance of centers of mass of components, DCMC);
Симметрия (Symmetry, Sym);
Регулярность формы (Regularity of form, RF);
Разделение уровня важности (Separation of the level of importance, SLI);
Соотношение сторон окна (Window aspect ratio, WR);
Огибающая линия контура графа (Graph Contour Envelope);
Среднее абсолютное отклонение длины рёбер (Mean Absolute Edge Length Deviation);
Угол поворота (Angle Preservation Metric);
Критерий корреляции взаиморасположения (Proximity Correlation Criterion, PCC);
Показатель осевого выравнивания (Axis Alignment Index, AAI);
Суммарная кривизна рёбер (Total Edge Curvature, TEC);
Индекс стохастичности ориентации (Stochastic Orientation Index, SOI);
Нормированная вариация площади ячейки (Normalized Cell Area Variation, NCAV);
Относительная разница между максимальным и средним расстоянием (Relative Distance Difference Ratio, RDDR);
Размер краевых выпуклых оболочек (Convex Hull Size of Edges, CHSE);
Следующим моментом было всесторонне обнаружение уязвимости, и был собран конвейер на основе smartBugs и Slither (статические анализаторы смарт-контрактов). В качестве каркаса мы взяли smartBugs (куда уже входят smartCheck, solhint и conkas), но столкнулись с тем, что встроенный Slither работал нестабильно. Поэтому отдельно дополнили smartBugs более свежей версией Slither. Для удобства написали скрипт, который по адресу контракта на Etherscan (или в нужной сети) подтягивали исходники, строили дерево импортов и прогонял анализаторы. Результат каждого инструмента сохранялся в CSV вида:


После smartBugs мы запускали Slither — и расширяли таблицу до ~144 признаков, каждый из которых указывал на потенциальную проблему. Эти фичи кормили ансамбли машинного обучения: GradientBoosting, XGBoost, LightGBM, RandomForest и VotingClassifier. В итоге мы получали предсказания о наличии уязвимостей.
Дополнительно «прогоняли» контракт через свежий Slither: он возвращает конкретные ошибки и номера строк. Мы подтягиваем исходники заново и формировали PDF‑отчет, где для каждой проблемы показывали фрагменты кода и его описание — чтобы ревьюер мог мгновенно оценить «тревожные» места.
Здесь мы поддерживали только Ethereum и L2. Были попытки добавить TRON, но они «упёрлись» в отсутствие нормального Tronscan API: парсили страницы, пробовали декодировать байткод — но в условиях хакатона решили не тратить на это драгоценное время. Хотя решение по факту нашли и на эту проблему. Параллельно сделали на сайте фичу подписки на обновление прокси‑контрактов. Логика простая:
Пользователь указывает адрес контракта, обновление которого он хочет отследить, мы через Etherscan API получаем реализацию (Implementation);
Сохраняем код реализации и подписываемся на событие Upgraded;
Как только контракт обновляется, ловим новый адрес, подтягиваем его код и шлём уведомление в Telegram с до/после.

В планах — не только сообщать об обновлении, но и показывать diff между версиями и текстовое описание изменений. Ещё можно перестраховаться и несколько раз в сутки дергать реализацию напрямую (если кто‑то удалит ивент Upgraded), но это в следующий релиз — нам же нужно было успеть к дедлайну!

Далее, необходимо было все это оформить на платформе и «прикрутить» сервисы для работы. При этом ключевым решением стал выбор микросервисной архитектуры. Этот подход был выбран не случайно. Он позволил:
Использовать лучший инструмент для каждой задачи: Python с его богатой экосистемой для ML и анализа данных был выбран для бэкенда; он же, благодаря зрелым фреймворкам (aiogram), был использован и для Telegram‑бота. Node.js, идеально подходящий для асинхронных I/O‑операций, лег в основу сервиса мониторинга. React и TypeScript что обеспечило создание сложного и надежного пользовательского интерфейса.
Обеспечение изоляции отказоустойчивость: Падение или ошибка в одном из сервисов (например, в сервисе мониторинга) не приведет к остановке всей платформы.
Упрощение независимой разработки и масштабирование: Каждый сервис может дорабатываться и масштабироваться отдельно в зависимости от нагрузки. Оркестрация всех компонентов доверена docker‑compose, что стандартизирует процесс развертывания и локальной разработки. Стек фронтенда был выбран для достижения максимальной скорости разработки и долгосрочной надежности.
React 19: Выбран за проверенный компонентный подход, который упрощает создание пользовательской части приложения, и за огромную экосистему, гарантирующую стабильность.
TypeScript: Интегрирован для строгой типизации, что кардинально снижало количество ошибок еще на этапе написания кода и упрощало поддержку проекта.
Vite: Применен как сборщик нового поколения для обеспечения практически мгновенной «горячей» загрузки в разработке (HMR) и оптимизации финальной сборки.
Управление данными
TanStack: Чтобы не превращать код в бесконечную проверку статусов «загружается...», «ошибка!», «получилось!», мы использовали TanStack Query. Эту библиотеку можно представить, как личного ассистента для работы с запросами. Разработчик просто говорит: «добудь мне список контрактов», а TanStack Query сам разбирается со всей рутиной: он запомнит результат (кэширование), будет незаметно для пользователя обновлять его в фоне и не станет делать лишний запрос, если эти же данные понадобятся в другом месте через секунду. В итоге интерфейс работает быстрее и плавнее, а в коде не остается «душнины» из сотен isLoading.
Архитектура FSD
Для долгосрочной поддержки проекта была выбрана архитектура Feature‑Sliced Design. Её выбрали за ключевое преимущество: код группируется не по техническим типам, а по бизнес‑фичам. Такой подход радикально упрощает навигацию по коду, обеспечивает изоляцию фич друг от друга и позволяет легко их переиспользовать. Это делает разработку предсказуемой и готовой к масштабированию.
Структура приложения
Сайт разделен на четыре ключевые страницы: домашняя страница служит визитной карточкой проекта, а три остальные предоставляют основной инструментарий для отслеживания, анализа и визуализации смарт‑контрактов.
Бэкенд: Мозговой и Аналитический Центр
Это ядро всей системы, где происходит основная магия.
Выбор фреймворка: FastAPI был выбран за его производительность, которая достигается за счет асинхронности на базе asyncio, и за строгую типизацию благодаря Pydantic. Встроенная автоматическая генерация документации по стандарту OpenAPI (широко известному как Swagger).
Безопасность и Аутентификация
Реализован серверный флоу OAuth2 (Open Authorization), что является стандартом безопасности. Фронтенд не хранит и не обрабатывает секреты клиента. Используется двухступенчатая система токенов: Refresh Token: Долгоживущий JWT (JSON Web Token), который безопасно хранится в httpOnly cookie. Этот флаг делает токен недоступным для JavaScript, что защищает его от кражи через вредоносные скрипты, внедренные на страницу.
Access Token: Короткоживущий JWT (JSON Web Token), который хранится в памяти на фронтенде и используется для аутентификации API‑запросов. Его короткий срок жизни минимизирует риски в случае его утечки. Этот подход обеспечивает баланс между удобством (пользователю не нужно логиниться каждый 15 минут) и безопасностью.
Привязка Telegram: Процесс привязки построен на генерации одноразового кода. Это простой и надежный способ связать веб‑сессию пользователя с его Telegram‑аккаунтом, что является необходимым условием для отправки персонализированных уведомлений.
Сервис Мониторинга: Неусыпный Страж
Этот сервис — самая инновационная часть проекта. Обоснование стека: Node.js и TypeScript были выбраны как идеальное решение для задачи, требующей обработки большого количества одновременных, долгоживущих сетевых соединений (подписки на WebSocket RPC). Событийно‑ориентированная модель Node.js здесь раскрывается в полной мере, что делает этот стек стандартом для многих DeFi‑проектов, работающих с блокчейном в реальном времени.
Механизм работы:
Сервис получает из БД список прокси‑контрактов для отслеживания.
Он открывает WebSocket‑соединения с RPC‑узлами выбранных блокчейн‑сетей.
В рамках этих соединений он подписывается на событие Upgraded(address indexed implementation) для каждого из отслеживаемых контрактов. Этот ивент является стандартом для большинства обновляемых прокси (EIP-1967).
При получении события он немедленно инициирует процесс: скачивает исходный код старой и новой реализации через API обозревателей блоков, генерирует отчет и отправляет его на специальный эндпоинт бэкенда для дальнейшей обработки.
Эффективность: Использование WebSocket и подписки на события на несколько порядков эффективнее, чем постоянный опрос (polling) состояния каждого контракта.
База Данных: Общее Сердце Системы
В качестве системы управления базами данных был выбран PostgreSQL. Это мощная и надежная реляционная СУБД, которая отлично подходит для хранения структурированных данных о пользователях, контрактах и результатах аудитов. Взаимодействие с бэкендом: Бэкенд работает с БД через высокоуровневые инструменты SQLAlchemy и SQLModel, что позволяет ему оперировать данными как Python‑объектами и упрощает реализацию сложной бизнес‑логики. Роль в экосистеме: База данных — это не просто хранилище, а связующее звено между всеми сервисами. Она хранит данные пользователей, результаты аудитов, а также служит «доской задач» для сервиса мониторинга.
Telegram‑бот: Полноценный Интерфейс в Мессенджере
Архитекторы проекта не стали ограничиваться простой отправкой уведомлений, а создали полноценный альтернативный интерфейс для взаимодействия с платформой.
Python был выбран для консистентности с основным бэкендом, что упрощает переиспользование логики и моделей данных. В качестве фреймворка был использован aiogram 3.x — современный и высокопроизводительный асинхронный инструмент, идеально подходящий для создания сложных, отзывчивых ботов.
Ключевая роль — мгновенные уведомления: Главная особенность бота, ради которой он и создавался, — это получение оповещений. Для этого бот не использует традиционные опросы, а запускает собственный встроенный HTTP‑сервер (на базе aiohttp). Это позволяет ему принимать вебхуки от внутреннего бэкенда, обеспечивая моментальную доставку уведомлений об изменениях в отслеживаемых контрактах.
Полное дублирование функционала: Ключевое решение — бот полностью повторяет функциональные возможности веб‑версии. Пользователь может, не покидая Telegram, выполнять все основные действия: инициировать аудит, запрашивать визуализацию, добавлять контракты для отслеживания и управлять этим списком.
Интеграция через прокси‑страницы: Для отображения сложных данных (детальных отчетов аудита и графов визуализации) используется элегантный механизм. Бот не пытается «нарисовать» их в чате, а создает и отправляет пользователю прямую ссылку на специальную прокси‑страницу веб‑приложения, обеспечивая бесшовный пользовательский опыт.
Ключевая роль — Уведомления: Но главная особенность, ради которой создавался бот, — это
получение мгновенных уведомлений. Именно в Telegram приходят оповещения об изменениях в отслеживаемых контрактах, которые обнаруживает сервис мониторинга.
Подход к Развертыванию: Классический и Надежный
Для демонстрации и развертывания проекта был выбран проверенный и надежный подход: Инфраструктура: Все сервисы разворачиваются на стандартном сервере под управлением Ubuntu.
Оркестрация: Управление всеми компонентами экосистемы (Web, Backend, Updates, Bot, DB) осуществляется через docker‑compose. Это значительно упрощает процесс развертывания, поскольку вся сложная конфигурация сети и зависимостей между сервисами описывается в одном декларативном файле и управляется единой командой.
Итоговое Заключение: Архитектура для Роста
Платформа SafeDeFi является примером грамотно спроектированного продуктом, архитектура которого решает ключевые задачи проекта с очевидным прицелом на будущее развитие.
Ключевые сильные стороны архитектуры
Стратегическое разделение ответственности: Выбор микросервисной архитектуры не случаен. Он позволил четко разделить систему на независимые, логические блоки: пользовательский интерфейс (Web), ядро с бизнес‑логикой (Backend), инновационный сервис мониторинга (Updates), точка входа через мессенджер (Bot) и общее хранилище (DB). Такое разделение является залогом стабильности и упрощает поддержку.
Обоснованный полиглотный подход: Для каждого сервиса был выбран наиболее подходящий инструмент — React/TS для сложного интерфейса, Python/FastAPI для удобной разработки API и Node.js для высокопроизводительных I/O‑операций в сервисе мониторинга. Это прагматичное решение, а не погоня за технологиями. Два полноценных интерфейса: Предоставление пользователю выбора между полнофункциональным веб‑приложением и Telegram‑ботом, который полностью дублирует его возможности, значительно расширяет охват и удобство использования платформы.
Потенциал для развития
Выбранная архитектура создает прочный фундамент для дальнейшего роста. Изолированность сервисов позволяет безболезненно добавлять новый функционал, например, настройка CI/CD (непрерывная интеграция и доставка): Автоматизация процессов тестирования, сборки Docker‑образов и развертывания через GitHub Actions или GitLab CI значительно ускорит и обезопасит процесс вывода новых версий в продуктив.
Расширение поддержки блокчейнов: Интеграция не‑EVM сетей (например, Solana) потребует доработки в основном сервиса мониторинга и бэкенда, не затрагивая при этом клиентские приложения. Углубление аналитических возможностей: Внедрение новых видов анализа, таких как динамический (фаззинг), может быть реализовано как еще один изолированный модуль в бэкенде. В целом, проект демонстрирует глубокое понимание как предметной области, так и современных инженерных практик. Это не просто набор инструментов, а целостная и хорошо продуманная экосистема.

