Контекст модели аккаунтов
Пропустите этот раздел, если вы знакомы с аккаунтами Solana и их структурой.
- Данные: фактические байты, в которых хранится состояние программы, балансы токенов или другая информация
- Владелец: программа, которая управляет этим аккаунтом и может изменять его данные
- Лампорты: баланс SOL аккаунта для освобождения от арендной платы
- Исполняемость: содержит ли этот аккаунт программный код
Базовая подписка на аккаунты
Начнём с простого примера подписки на изменения в аккаунтах токенов. Этот скрипт будет уведомлять вас при каждом изменении баланса токенов:BKMHWYLAX4un3HUbR7a3u9jPmzCiLNa4mSj1RiX11eWF.
У этого аккаунта есть:
- 2 039 280 лампортов (баланс около 0,002 SOL — это сумма, необходимая для освобождения этого аккаунта токена от арендной платы)
- Программа-владелец
TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA(это программа SPL Token) - Подпись транзакции
5C9Hr5nG2j8eQz6inxPmfyjbYdmXddzUDyR1iQgEnjYQ3RNvuP4Zzc8t1enLNy7Rk8KNCtQPEQztENYWxkt9GaVD, указывающая, какая именно транзакция вызвала изменение этого аккаунта - Слот 352366983, указывающий, когда это обновление произошло в блокчейне
- Поле данных, содержащее 165 байт данных аккаунта в кодировке base58
Принцип фильтрации аккаунтов с помощью datasize
Поле данных имеет ключевое значение: оно содержит фактическую структуру аккаунта токена. Используем это понимание для интеллектуальной фильтрации аккаунтов.Зачем использовать фильтрацию по datasize?
Чтобы понять, зачем нужна фильтрация, сначала разберёмся, что представляют собой аккаунты токенов. Для каждого токена в кошельке существует отдельный аккаунт ончейн. Если в вашем кошельке хранятся 3 разных токена (USDC, BONK и SOL), у вас фактически есть 1 аккаунт кошелька (основной аккаунт SOL) и 3 аккаунта токенов (по одному для каждого типа токена). Размер каждого аккаунта токена составляет ровно 165 байт. В нём хранится информация о том, какой токен он содержит (адрес минта), кому он принадлежит (адрес вашего кошелька) и сколько в нём токенов (количество). Программе Token Program принадлежат миллионы аккаунтов в Solana, но не все они являются «аккаунтами токенов», в которых хранятся балансы пользователей. Вот что происходит с фильтрацией и без неё: Без фильтрации — поток данных:- Аккаунты токенов (165 байт) — пользовательские балансы: миллионы аккаунтов
- Аккаунты минтов (82 байта) — определения токенов: сотни тысяч аккаунтов
- Аккаунты с мультиподписью (355 байт) — управление общими кошельками: десятки тысяч аккаунтов
- Аккаунты Associated Token Program (различные размеры) — миллионы аккаунтов
- Без фильтрации: миллионы обновлений аккаунтов (создание минтов, изменения мультиподписей и т. д.)
- С фильтрацией по datasize: только изменения балансов токенов
Откуда берутся 165 байт?
В этом нет никакой магии: это следует из структуры аккаунта программы SPL Token. В исходном коде видно, что структураAccount определяет ровно 165 байт:
- Аккаунты минтов (82 байта)
- Аккаунты с мультиподписью (355 байт)
- Аккаунты программы связанных аккаунтов токенов
- Другие связанные с токенами аккаунты иного размера
Декодирование структуры аккаунта
Теперь, когда мы понимаем, почему установили фильтр на 165 байт, декодируем содержимое аккаунта из нашего примера:- Байты 0–31: адрес минта (какой токен хранится в этом аккаунте)
- Байты 32–63: адрес владельца (кому принадлежит этот аккаунт токена)
- Байты 64–71: количество токенов (сколько токенов находится в аккаунте)
- Байты 72–164: дополнительные метаданные (делегат, состояние, право закрытия и т. д.)
Объединение фильтров: datasize + memcmp для максимальной точности
Теперь, когда мы знаем, что адрес минта находится в байтах 0–31, можно ещё больше сузить выборку. Допустим, мы хотим отслеживать только аккаунты токена USDC. Можно объединить фильтрdatasize с фильтром memcmp, чтобы выбрать точный адрес минта:
- Фильтр по владельцу: «Покажи аккаунты, принадлежащие Token Program» (миллионы аккаунтов)
- Фильтр по datasize: «Но только стандартные аккаунты токенов размером 165 байт» (сотни тысяч)
- Фильтр по memcmp: «И только те, в которых хранится USDC» (тысячи)
Чтение обновлений аккаунтов USDC: кто, сколько и где?
Теперь посмотрим, что именно содержат эти отфильтрованные обновления. Создадим монитор специально для USDC, который при изменении аккаунта токена отвечает на ключевые вопросы:- Кому принадлежит этот аккаунт токена?
- Сколько USDC теперь в нём содержится?
- Где произошло изменение (какой именно аккаунт изменился)?
- Когда произошло это изменение?
- Какая транзакция вызвала изменение?
bs58.encode(), чтобы преобразовать двоичные объекты Buffer в читаемые строки.
Полный справочник по фильтрации
Помимо уже использованных базовых фильтровowner, datasize и memcmp, подписки на аккаунты поддерживают дополнительные параметры фильтрации, позволяющие ещё больше сузить результаты:
Фильтрация конкретных аккаунтов
Отслеживайте конкретные аккаунты по их открытым ключам:Комбинированные стратегии фильтрации
Главное преимущество заключается в объединении нескольких типов фильтров. Вот удобная концептуальная модель:- Охватите широкую область с помощью
owner— «Покажи все аккаунты, которыми управляет эта программа» - Отфильтруйте по структуре с помощью
datasize— «Но только аккаунты этого конкретного типа» - Выберите конкретные данные с помощью
memcmp— «И только те, которые содержат эту конкретную информацию» - Отслеживайте известные аккаунты с помощью
account— «Или отслеживай только интересующие меня конкретные аккаунты»
Общая картина
Представьте подписки на аккаунты как просмотр потока изменений базы данных в реальном времени. Состояние Solana фактически представляет собой огромное хранилище пар «ключ — значение», где каждый аккаунт является отдельной записью. При выполнении программы изменяют эти аккаунты. Подписка позволяет в реальном времени отслеживать изменения конкретных записей. Система фильтрации работает подобно индексам базы данных: вы отслеживаете не просто «все изменения», а «изменения аккаунтов, соответствующих этим критериям». Благодаря этому можно создавать быстро реагирующие приложения, которые немедленно обрабатывают актуальные ончейн-события, не перегружая систему ненужными данными.Применение этого шаблона к другим программам
Рассмотренный подход применим к любой программе Solana. Вот общий шаблон:- Изучите структуру аккаунта — проверьте исходный код или документацию программы
- Начните с фильтрации по владельцу — выберите программу, которая управляет аккаунтами
- Примените структурные фильтры — используйте размер аккаунта, шаблоны данных или другие характеристики, чтобы выбрать аккаунты конкретных типов
- Добавьте целевые фильтры — сосредоточьтесь на конкретных аккаунтах, состояниях или значениях данных, важных для вашего приложения