Интеграция ZKP для приватных транзакций
Ethereum — публичный реестр. Каждый transfer() виден всем: отправитель, получатель, сумма. Для большинства DeFi-протоколов это нормально. Но есть классы приложений — корпоративные расчёты, конфиденциальные голосования, приватные торги, payroll на блокчейне — где прозрачность становится проблемой. Zero-Knowledge Proof позволяет доказать корректность транзакции без раскрытия её содержимого.
Что такое ZKP применительно к транзакциям
ZKP — это криптографическая конструкция, где prover убеждает verifier в истинности утверждения, не раскрывая информацию, лежащую в основе утверждения. Для приватных транзакций это означает:
- «Я перевёл 100 токенов, и после перевода мой баланс неотрицателен» — без раскрытия ни баланса, ни суммы, ни адресов
- «Я голосовал в этом proposal» — без раскрытия варианта голоса
- «Это легитимная транзакция согласно правилам протокола» — без раскрытия деталей
В контексте блокчейна используются преимущественно zk-SNARKs (Groth16, PLONK) и zk-STARKs. Разница не только техническая — она влияет на выбор архитектуры.
Ключевые системы доказательств
| Система | Размер доказательства | Verifier gas | Trusted setup | Постквантовая |
|---|---|---|---|---|
| Groth16 | ~200 байт | ~300K gas | Да (per-circuit) | Нет |
| PLONK | ~400 байт | ~500K gas | Универсальный | Нет |
| STARKs | 40-200 KB | Высокий | Нет | Да |
| Noir (Barretenberg) | ~500 байт | ~400K gas | Универсальный | Нет |
Для on-chain верификации Groth16 — наиболее gas-эффективный выбор. Но circuit-specific trusted setup создаёт операционный overhead: каждый новый circuit требует отдельной ceremony (или использования универсальных SRS).
PLONK с универсальным trusted setup проще в эксплуатации. Aztec Protocol использует UltraPLONK. Scroll и линеарка zkSync используют кастомные вариации.
Архитектурные паттерны для приватных транзакций
UTXO-based модель (Zcash-подход)
Средства хранятся как notes — зашифрованные UTXO. Каждая транзакция потребляет старые notes и создаёт новые. On-chain хранится только commitment (хэш note) и nullifier (предотвращает double-spend).
spend(note) → proof(note exists in tree, note not spent, balance >= amount)
→ reveal nullifier (добавляем в nullifier set)
→ create new note commitments
Это подход Tornado Cash, Aztec v1, Zcash. Verifier на Solidity проверяет ZK-доказательство, проверяет nullifier в mapping, обновляет Merkle tree commitments.
Слабое место — Tornado Cash показал, что даже с ZKP metadata analysis (timing атаки, суммы) может деанонимизировать участников. ZKP скрывает связь транзакций, но не паттерны поведения.
Шифрование состояния через FHE (Fully Homomorphic Encryption)
Fhenix и Inco используют FHE для шифрования state on-chain. Смарт-контракты работают с зашифрованными значениями напрямую. Это концептуально отличается от ZKP: не «докажи, что транзакция корректна», а «выполни операцию над зашифрованными данными». Технология ещё незрелая — вычислительный overhead FHE огромен — но активно развивается.
Инструменты для ZKP-интеграции
Circom + SnarkJS
Наиболее распространённый стек для custom circuits:
circuit.circom → compile → R1CS → Powers of Tau → proving key + verification key
→ verifier.sol (Solidity)
Circom — язык для описания arithmetic circuits. Компилятор превращает circuit в R1CS (Rank-1 Constraint System). SnarkJS генерирует ключи и Solidity-верификатор.
Пример простого circuit для проверки диапазона (range proof):
pragma circom 2.1.0;
include "circomlib/circuits/comparators.circom";
template RangeProof(bits) {
signal input value; // private
signal input maxValue; // public
component lt = LessThan(bits);
lt.in[0] <== value;
lt.in[1] <== maxValue;
lt.out === 1;
}
component main {public [maxValue]} = RangeProof(64);
Это доказывает, что приватное value меньше публичного maxValue, не раскрывая само value.
Noir (Aztec)
Более высокоуровневый язык, похожий на Rust. Абстрагирует от arithmetic circuits. Используем для проектов, где команда не хочет погружаться в R1CS.
fn main(x: Field, y: pub Field) {
assert(x != y);
// x остаётся приватным, y — публичный вход
}
Noir компилирует в ACIR → Barretenberg backend → Solidity верификатор.
ZK-email, Semaphore, WorldCoin: готовые примитивы
Semaphore — библиотека для анонимных сигналов (голосования, whitelist membership). Позволяет доказать членство в группе без раскрытия идентичности. Часто используется для governance:
// Пользователь доказывает, что он в группе избирателей
// без раскрытия своего адреса
semaphore.verifyProof(
merkleTreeRoot,
nullifierHash, // предотвращает повторное голосование
signal, // хэш голоса
proof
);
Compliance и приватность: не взаимоисключающие понятия
Регуляторы беспокоит не сама приватность, а возможность отмывания. ZKP позволяет строить selective disclosure — транзакция приватна для наблюдателей, но владелец может раскрыть детали регулятору с криптографическим доказательством корректности.
Aztec v3 (Noir) и Aleo строят compliance-layer поверх ZKP: viewing key позволяет аудитору видеть транзакции конкретного пользователя, не нарушая приватность для остальных.
Процесс интеграции ZKP
Аналитика. Определяем, какие именно данные нужно скрыть. Суммы? Адреса? Факт участия? Это определяет архитектуру: UTXO-модель, commitment scheme, или selective disclosure.
Проектирование circuit. Формализуем constraint system. Какие входы приватные (witness), какие публичные? Какие утверждения доказываем? Проверяем на soundness — нет ли пути сгенерировать валидное доказательство для некорректного утверждения.
Разработка. Пишем circuit на Circom или Noir, тестируем на тестовых векторах. Генерируем Solidity verifier. Интегрируем в смарт-контракт. Разрабатываем prover-сервис (ZK-доказательства вычисляются off-chain, занимают секунды-минуты CPU).
Аудит. Circuit soundness — отдельная дисциплина от Solidity аудита. Уязвимость может быть в constraint system, а не в смарт-контракте. Используем Circomspect для статического анализа Circom circuits.
Производительность. Proof generation на сервере: Groth16 — 1-5 секунд, PLONK — 5-30 секунд. Для мобильных/браузерных клиентов — WebAssembly prover (SnarkJS) или делегирование на backend.
Ориентиры по срокам
Интеграция готового ZKP примитива (Semaphore, Tornado-fork): 2-4 недели. Разработка custom circuit с нуля (range proof, приватный transfer): 4-8 недель. Полноценный ZKP-протокол с compliance-слоем, prover сервисом и фронтендом: 2-3 месяца.
Сроки существенно зависят от сложности circuit и выбора proving system — PLONK проще в сопровождении, Groth16 быстрее и дешевле on-chain.







