ZK-compression — это новый архитектурный приём в экосистеме Solana, который комбинирует уже знакомую state compression (с корнями Merkle на L1) с нуль-разглашательными доказательствами (zk-proofs). Идея проста: *вычислительно* проверить на L1 корректность изменений «тяжёлого» состояния, а само состояние держать в дешёвом/компрессированном представлении, не раздувая аккаунты и «ренту». В результате разработчики могут создавать токены и PDA-аккаунты без ренты (rent-free) и в разы сократить стоимость масштабных приложений (игры, соцсети, рекламные графы, биллинг) — не покидая L1 Solana и сохраняя его безопасность и композиционность.
ZK-compression — эволюция state compression (на базе Concurrent Merkle Trees), принесшая в неё универсальные доказательства корректности переходов состояния и общий фреймворк для «компрессированных» токенов/ПДА.
Откуда выросла ZK-compression: кратко о state compression
State compression в Solana — это способ хранить «массовые» данные не в аккаунтах, а в коммитментах на цепи: корень Concurrent Merkle Tree (CMT) лежит на L1, а сами элементы (листья) и их изменения индексируются off-chain. Транзакции прикладывают Merkle-доказательства, а программы проверяют их против корня. На этой базе появились compressed NFTs (cNFT) и другие массовые структуры (миллионы объектов за копейки). См. также транзакция и комиссии.
Ключевые свойства:
* CMT поддерживает *параллельные* обновления (fast-forwarding proofs), что позволяет в одном слоте успевать до ~2048 модификаций без коллизий; за счёт этого можно хранить до миллиардa элементов в одной структуре и добиться >10 000× экономии on-chain-места (по сравнению с наивным хранением каждой записи в аккаунте). * В реестре NFT это вылилось в cNFT: минт огромных коллекций с парой транзакций на корни и «копеечными» затратами за объект.
Что добавляет ZK-compression
Если state compression требует пересылать и проверять Merkle-пути при каждом действии, то ZK-compression позволяет прикладывать короткое zk-доказательство, проверка которого дешевле и стабильнее по газу. За счёт этого:
* Дешевле хранить состояние: L1 держит лишь *коммитменты/корни* и минимальные метаданные, а доказательства корректности переходов проверяются как compute. В Solana вычисления стоят дешевле, чем долговременное хранение аккаунтов — это делает обмен «storage → compute» выгодным. * Рента исчезает там, где она блокировала масштаб: становятся возможны rent-free PDA и rent-free токены (сжатые токен-аккаунты), пригодные для миллиардных масштабов. * Композиционность остаётся L1-уровня: в отличие от L2-роллапов, здесь нет «собственного консенсуса»; верификация идёт *внутри* программ на Solana, и любые контракты могут принимать такие доказательства как входные данные.
Коротко: state compression = «Merkle-корни на цепи + off-chain индексация», ZK-compression = «+ zk-доказательство корректности перехода вместо (или поверх) длинных Merkle-путей».
Архитектура: из каких блоков состоит решение
1) Деревья/коммитменты на L1. Как и прежде, база — Concurrent Merkle Tree со специальными правилами параллельных вставок/замен. Корни и служебная структура хранятся в аккаунте/программе, управляемых вашим приложением.
2) Индексер и слой доступности данных. Чтобы клиенты не таскали весь Merkle-путь, задействуются индексеры (Helius/Light и др.). Они следят за слотами, записывают изменения листьев и помогают собирать/кэшировать артефакты для пруверов. Для cNFT уже де-факто стандарт — DAS API (Digital Asset Standard) у RPC-провайдеров.
3) Прувер и формат доказательств. Локально (или на бэкенде) генерируется zk-доказательство того, что предложенная операция:
- согласуется с «старым» коммитментом,
- корректно обновляет конкретный лист/набор листьев (баланс, атрибут, владение и т.д.),
- даёт новый корень, который вы и собираетесь записать на L1.
Типичные схемы — zkSNARK (ради коротких пруфов и быстрой валидации).
4) Ончейн-верификация. Ваша программа (или общий «верификатор») принимает пруф и проверяет его корректность в рамках слота/транзакции. Если ОК — обновляется корень CMT/коммитмент. Для вызывающего контракта это похоже на «обычную» инструкцию, но он получает гарантии корректности без доступа к некомпрессированным данным.
5) Прикладные примитивы. Сверху строятся высокоуровневые штуки: rent-free токены, rent-free PDA (сжатые записи с доступом по ключу), массовые реестры (идентификаторы, лайки, графы друзей), биллинговые записи и проч.
Поток «жизни» данных: пример на токенах
Сценарий: хотим реестр «балансов» как сжатые листья, без типичных «тяжёлых» SPL-token-аккаунтов.
1) Коммитмент. Разворачиваем CMT под «балансовую» карту (ключ = PDA/адрес пользователя + ID токена; значение = количество). 2) Минт. Оператор или минтер публикует переход «0 → X» вместе с zk-доказательством корректности: пруф показывает, что «старое» значение было 0, а «новое» = X; верификатор убеждается, что новый корень соответствует применённому патчу. 3) Трансфер. Отправитель подготавливает пруф «уменьшил A на y, увеличил B на y» (возможно, как один батч). Контракт проверяет пруф и меняет корень. 4) Сжигание/списание. Аналогично: пруф о корректности «A → A − y». 5) Чтение/UX. Клиенты читают индексер или используют доказуемые «read-эндпойнты», для критичных операций — прикладывают пруфы «на чтение» (membership/non-membership), если это требуется логикой.
Плюсы: нет «тысяч аккаунтов-хранилищ», нет ренты, «массовые» операции становятся дешевле/предсказуемее; всё остаётся компонуемым на L1.
Почему это экономно именно на Solana
У Solana хранение аккаунтов — дорогая часть, а вычисления сравнительно дешевле. ZK-compression обменивает дорогой storage на дешёвый compute: мы проверяем пруфы на L1 и не плодим аккаунты/рентабельные PDA. На других сетях эта замена бывает экономически невыгодной (compute дороже), а в Solana она «ложится» естественно.
Грубые ориентиры из практики:
* «Базовая» state compression уже даёт на порядки меньшую цену (классический пример — cNFT с миллионами минтов). * ZK-слой снимает накладные расходы на длинные Merkle-пути и позволяет *обобщить* модель на токены/балансы/PDA. * В материалах по ZK-compression сообщалось об экономии до 99% хранения и потенциально до нескольких тысяч раз по «эффективной ренте» для некоторых паттернов — в зависимости от частоты обновлений и размера данных.
Чем ZK-compression отличается от L2/роллапов
* Никакого отдельного консенсуса/валидаторов. Всё — на L1 Solana; пруф проверяет ваш контракт. * Композиционность уровня L1. Любая программа может принимать пруфы от другой, нет мостов/асинхронных выходов. * DA-модель: «данные доступны» через саму Solana (журнал слотов) и индексеры, корни — на L1; критичные приложения могут дублировать индексацию и хранение «сырых» сообщений.
По духу это ближе к «обобщённым коммитментам и пруфам на L1», чем к отдельному уровню исполнения.
Сравнение: classic state compression vs ZK-compression
| Критерий | Classic state compression (Merkle) | ZK-compression |
|---|---|---|
| Что передаём в txn | Полный Merkle-путь (может быть длинным) | Короткий zk-пруф корректности |
| Стоимость/латентность | Дешево, но растёт с глубиной/частотой | Стабильнее по газу при росте данных |
| Типы данных | cNFT, деревья атрибутов, реестры | + токены/балансы, PDA (rent-free) |
| Совместимость | Нативно L1, нужна индексация | Нативно L1, нужна индексация + прувер |
| Риск | Коллизии/«устаревшие» пути | Корректность схемы пруфа и верификатора |
Где это уже применяется
* cNFT и «массовые» коллекции. Практика показала надёжность state compression (Bubblegum) и RPC-индексации (DAS). * ZK-tokens / rent-free PDA. Появляются SDK и программы, позволяющие выпускать «сжатые» токены/учётные записи (балансы, баллы лояльности, в-игровую экономику) без ренты — с доказуемыми переходами на L1. * Социальные графы, лайки, счётчики, рекламные события. Там, где много маленьких записей и обновлений, экономия максимальна. * Pay-per-action биллинг, подписки, микроплатежи. «Счётчик-как-листья» + пруф корректности инкремента.
Стек разработчика: из чего собирать продукт
Программы:
- spl-account-compression (интерфейсы к CMT): создание/обновление деревьев, fast-forwarding, вспомогательные проверки.
- «Верификатор zk»: библиотека/программа для проверки конкретной схемы (Groth16 и др.).
Инфраструктура:
- RPC с поддержкой DAS/индексации cNFT/state-compression (Helius и аналоги).
- Индексер ZK-compression: хранит «сырые» изменения, подготавливает артефакты для прувера, предоставляет read-эндпойнты.
SDK/клиент:
- Клиент для генерации пруфов (браузер/сервер) и упаковки инструкций.
- Утилиты для отладки: проверка корней, сравнение снапшотов, восстановление Merkle-путей.
Деплой:
- Версионируйте схемы пруфов, держите артефакты (vk/keys) под контроль-версий.
- Закладывайте миграции корней и процедуры «аварийного обновления» (при смене дерева/параметров).
Безопасность, доверие и риски
1) Доверие к индексации. Индексер — это *удобство и кеш*, но он не источник истины: истина — корни/коммитменты на L1. Пользовательская сторона либо пересчитывает пути/пруфы, либо доверяет провайдеру только как кэшу (пруф всё равно проверяет L1).
2) Корректность пруфов/верификатора. Убедитесь, что ваша схема надежно кодирует инварианты (нет «пустых переходов», переполнений, рассинхронизаций). Любые баги в верификаторе — критичны, потому что он «решает», что считать валидным переходом состояния.
3) Совместимость с экосистемой SPL. Классические протоколы могут ожидать «обычные» SPL-счета и токены. Для интеграций готовьте адаптеры (например, «декодировать баланс» через доказательство чтения или держать «мост-обёртку» между SPL и «сжатой» книгой балансов).
4) Liveness и восстановление. Спланируйте мульти-индексацию (несколько провайдеров/инстансов), снапшоты деревьев, резервные каналы. Если индексер падает, пользователи должны иметь способ вычислить пруф локально или переключиться.
5) Приватность. ZK-пруфы не обязаны скрывать величины/адреса — они доказывают корректность. Если требуется приватность содержимого, проектируйте соответствующие схемы (скрытые поля/диапазоны), помня о стоимости вычислений.
6) Экономика и тарифы. Пруф-генерация «стоит» CPU/GPU и время. Для UX может понадобиться батчирование операций и «тарифные планы» (часть пруфов — на бэкенде).
Практические рекомендации по проектированию
* Начните с state compression (Merkle-пути) — она уже боевая и проста для cNFT/реестров. Когда упрётесь в длину путей/накладные, подмешивайте ZK для горячих участков. * Думайте ключами данных: как вы адресуетe листья? Ключ = seed(program) + user + resource уменьшит коллизии и облегчит миграции. * Версионируйте деревья и схемы. Каждый релиз — свой tree_id/vk_id, «мягкая миграция» через дублирование корней и «временные мосты». * Интегрируйте «доказательства чтения». Не только записи: нередко нужно доказать «баланс ≥ X» или «элемент отсутствует» (*non-membership*). * Делайте DR-плейбуки: «индексер умер», «ключи верификатора утекают», «нужно откатиться на снапшот». * UX-подсказки: показывайте пользователю новый корень, статус верификации, понятные ошибки (несогласованный пруф, устаревший снапшот).
Примеры сценариев
Игры и соцсети. Миллионы предметов/лайков/очки опыта → листья; действия игрока — пруфы изменения. Никаких «миллионов PDA», быстрый онбординг.
Маркетплейсы/NFT-сервисы. cNFT + ZK-пруфы для «массовых» апдейтов атрибутов/роялти без длинных путей и с предсказуемой ценой.
Финтех/биллинг. Счётчики начислений/лимитов и «пей-пер-акшн» при микротранзакциях, где rent-модель обычных аккаунтов экономически губительна.
Идентичность/доступ. Сжатые allow-листы/роли; доказательство членства/не-членства на L1; обновления списков большими батчами.
Часто задаваемые вопросы (FAQ)
Это «роллап на Solana»? Нет. ZK-compression — это L1-парадигма: ваши программы на Solana принимают и проверяют пруфы, корни и коммитменты живут на L1.
Где лежат данные? Хэш-корни и служебное на L1 (в аккаунтах/программах), «сырые» записи и разносы — у индексеров/в приложении. Истина для корректности — пруф + корень на L1.
Насколько это дешевле? Зависит от паттерна. Для «массовых объектов» state compression уже показывала >10 000× экономии хранения; ZK-слой убирает накладные на пути и даёт rent-free PDA/токены, что особенно выгодно при частых апдейтах.
Можно ли «скрывать» суммы/поля? Да, схемой пруфа, но это увеличит вычислительную цену. Базовые кейсы — доказуемая корректность, а не приватность.
Как читать «баланс» из сжатого токена? Через индексер/SDK и при необходимости — пруф чтения (membership). Контракты-потребители могут требовать пруф, если логика критична.
Что с совместимостью с DeFi? Нужны адаптеры. Часть протоколов будет работать напрямую (принимая пруфы), часть — через мост-обёртку к классическому SPL.
Сравнение подходов хранения состояния в Solana
| Подход | Где данные | Что проверяет L1 | Стоимость/масштаб |
|---|---|---|---|
| Классические аккаунты | В аккаунтах (rent) | Ничего сверх стандартных инвариантов | Простой UX, но дорого при масс-данных |
| State compression (Merkle) | Листья off-chain, корни в CMT | Merkle-путь → новый корень | Дёшево, но накладные растут с глубиной |
| ZK-compression | Листья off-chain/индексер; корни на L1 | zk-пруф корректности перехода | Дорого вычислять пруф, но стабильно и дёшево на L1 |
Лучшие практики для продакшна
* Держите несколько индексеров и автоматические сверки корней. * Логируйте каждую смену корня с метаданными (slot, tree_id, vk_id). * Делайте контрактные гвардии: лимиты на размер патча, дедлайны слотов, «анти-повтор». * Планируйте миграции дерева (рост глубины, фрагментация листьев) заранее. * Документируйте формат пруфов, выкладывайте верификационные ключи (vk) и используйте семантическую версионизацию.
См. также
- Rollups (L2) (для сравнения архитектур)
- Токенизированные фонды (пример приложений с тяжёлым состоянием)
- Blacklists у стейблкоинов (об админ-ролях и рисках в контрактах)
