
Серия: Zcash с первых принципов . Статья 6 . Shielded Protocol (финал) Для кого: новички, прочитавшие статьи с 0 по 5. Здесь всё соединяется воедино. Что вы поймёте в итоге: полную и корректную ментальную модель shielded-транзакции Zcash, где каждое понятие из серии занимает своё место, а все циклы из Статьи 0 замыкаются.
Мы начали в Статье 0 с парадокса и истории о запечатанных конвертах на публичной доске. Затем мы посвятили пять статей построению деталей: конечные поля, эллиптические кривые, commitments, деревья Меркла и доказательства с нулевым разглашением. Теперь мы соберём их вместе и посмотрим, как работает настоящий приватный платёж — от начала до конца.
По отдельности каждая изученная вами часть остроумна. Но магия Zcash — в том, как они сцепляются друг с другом. Один nullifier сам по себе не даёт приватности. Один commitment сам по себе не предотвращает подделку. Одно доказательство само по себе не доказывает ничего полезного. Именно сборка превращает пять компонентов в деньги, которые одновременно приватны и заслуживают доверия.
Эта статья — и есть такая сборка. К концу фраза «сеть проверяет транзакцию, которую не может увидеть» будет ощущаться уже не как парадокс, а как очевидное следствие частей, которые вы уже понимаете.
Вот вся серия на одной странице: соответствие между элементами истории из Статьи 0 и реальным механизмом.
| Элемент истории из Статьи 0 | Реальный компонент | Построен из |
|---|---|---|
| Деньги внутри конверта | Note (значение, получатель, случайность) | кодируется как элементы поля (Ст. 1) |
| Запечатанный непрозрачный конверт | Note commitment | commitment Pedersen / Sinsemilla (Ст. 2, 3) |
| Публичная доска | Дерево note commitment (anchor = его корень) | инкрементальное дерево Меркла (Ст. 4) |
| Жетон пустоты | Nullifier | ZK-дружественный хеш note + секретного ключа (Ст. 2, 3) |
| «Деньги на входе равны деньгам на выходе» | Value commitments + проверка баланса | гомоморфные commitments Pedersen (Ст. 2, 3) |
| Магия за кулисами | Доказательство с нулевым разглашением | zk-SNARK над арифметической схемой (Ст. 5) |
| «Только вы можете прочитать свой конверт» | Зашифрованная note + viewing keys | шифрование + иерархия ключей (эта статья) |
Всё, что пользователь может делать, исходит из одного секрета — spending key — через однонаправленную иерархию (каждая стрелка — необратимое выведение благодаря trapdoor-механизмам из Статей 2 и 3):

Стоит заметить две вещи, и обе следуют из предыдущих статей:
Чтобы приватно потратить note, вы должны одновременно убедить сеть в четырёх вещах не раскрывая саму note, её значение, её позицию или свою личность. Каждое утверждение обеспечивается компонентом, который вам уже знаком.

Доказательство не раскрывает ни одного из базовых фактов (какая именно note, чей ключ, какое значение). Оно раскрывает только то, что все четыре утверждения выполняются. В этом и состоит весь трюк shielded Zcash, выраженный одной диаграммой.
Ещё в Статьях 2 и 3 мы отмечали, что commitments Pedersen складываются: commitment к v_1 плюс commitment к v_2 даёт commitment к v_1 + v_2. Вот где это начинает работать на практике.
Каждая входящая и исходящая note несёт value commitment: commitment Pedersen v.G + r.H, скрывающий её значение v. Поскольку они складываются, сеть может вычислить:
(sum of input value commitments) − (sum of output value commitments)
Если транзакция сбалансирована (деньги не созданы и не уничтожены), части v сокращаются точно, и остаётся только commitment к нулевому значению, ослеплённый оставшейся случайностью. Отправитель доказывает, что знает эту оставшуюся случайность, создавая небольшую подпись, называемую binding signature. Корректная binding signature возможна только тогда, когда значения действительно сбалансированы, и при этом не раскрывается ни одна сумма.
Это самая наглядная иллюстрация во всей серии того, зачем нам понадобились гомоморфные commitments на основе кривых. Правило «деньги на входе равны деньгам на выходе» обеспечивается тем, что мы складываем запечатанные конверты и проверяем, что результат запечатывает ноль.
Давайте соберём платёж от Alice к Bob. В качестве обучающей модели мы возьмём ясную структуру Sapling «сторона траты / сторона вывода».
Shielded-транзакция объединяет два типа описаний:
| Описание траты (потребляет note) | Описание вывода (создаёт note) |
|---|---|
| value commitment входа | value commitment выхода |
| anchor, относительно которого строится доказательство (корень дерева) | новый note commitment (новый лист) |
| nullifier потраченной note | ephemeral key для шифрования |
| перерандамизированный публичный ключ + подпись авторизации траты | зашифрованная note (шифртекст для получателя) |
| zk-SNARK, доказывающий четыре утверждения | zk-SNARK, доказывающий, что вывод корректно сформирован |
Плюс одна binding signature для всего пакета, обеспечивающая баланс значений (раздел 5).

Проследите приватность: сеть проверила anchor, проверила, что nullifier новый, проверила доказательство и проверила баланс. Она приняла корректный платёж, не узнав ни сумму, ни адрес, ни то, какая именно note была потрачена. При этом nullifier потраченной note (её смерть) и новый commitment Bob (рождение его note) находятся в двух разных публичных структурах без видимой связи между ними — это и есть разорванная связь из Статьи 0.
Статья 0 намеренно оставляла открытые вопросы. Вот они все — теперь уже закрытые.
| Цикл, открытый в Статье 0 | Чем замыкается |
|---|---|
| Как возможен запечатанный, но неподделываемый конверт? | Commitments: hiding за счёт случайности, binding за счёт устойчивости к коллизиям / trapdoor-механизма кривой (Ст. 3) |
| Откуда берутся ключи и секретные рецепты? | Арифметика полей и умножение скаляра на эллиптической кривой (Ст. 1, 2) |
| Что именно представляет собой «доска»? | Инкрементальное дерево Меркла из note commitment; его корень — это anchor (Ст. 4) |
| Почему жетон пустоты нельзя связать с его конвертом? | Nullifier — это keyed hash, хранящийся в отдельном множестве, отдельно от commitments (Ст. 2, 3, 4) |
| Как доказать корректность, ничего не раскрывая? | zk-SNARK над арифметической схемой, кодирующей все четыре утверждения (Ст. 5) |
| Как получатель узнаёт, что ему заплатили? | Note шифруется на его адрес; он выполняет пробную расшифровку с помощью viewing key (эта статья) |
| Как приватно обеспечивается «деньги на входе = деньги на выходе»? | Гомоморфные value commitments + binding signature (разд. 5) |
Парадокс с первой страницы, проверить то, чего нельзя увидеть, теперь полностью исчезает. Сеть проверяет утверждения о скрытых данных, а не сами данные.
Мы объясняли всё на структуре Sapling, потому что именно в ней разделение наиболее наглядно. Текущий дизайн, Orchard, не заменяет эти идеи, а уточняет их:
| Sapling | Orchard | |
|---|---|---|
| Единица транзакции | отдельные описания Spend и Output | объединённые Actions (каждое выполняет одну трату и один вывод) |
| Система доказательств | Groth16 (trusted setup) | Halo 2 (без trusted setup) |
| Кривые | BLS12-381 + Jubjub | Pallas / Vesta (Pasta) |
| Хеш для commitment | Pedersen | Sinsemilla |
Все концепции из этой статьи напрямую переносятся сюда; Orchard в основном объединяет трату и вывод в один блок и заменяет систему доказательств на вариант без церемонии. Пять опор остаются теми же.
Это самая полная картина в серии, но всё же она остаётся моделью. Мы упростили точные кодировки note в поле, точные формулы выведения ключей, перерандамизацию ключей траты, diversified addresses, memo-поля, обработку комиссий, полное различие между value commitments и note commitments, а также точную роль каждой подписи. Мы также показали один канонический поток; реальные транзакции могут одновременно содержать много трат и выводов и могут смешивать transparent- и shielded-части. Авторитетным источником остаётся Zcash Protocol Specification. То, чем вы теперь владеете, — это правильная форма; спецификация заполняет все размеры и детали.
| Термин | Значение простыми словами |
|---|---|
| Spending key | Единственный корневой секрет, из которого выводятся все ключи пользователя |
| Viewing Key | Раскрывает ваши транзакции держателю, не позволяя ему тратить средства |
| Spend description | Часть tx, которая потребляет note (nullifier, anchor, proof) |
| Output description | Часть tx, которая создаёт note (commitment, шифртекст, proof) |
| Action (Orchard) | Единый блок, одновременно выполняющий одну трату и один вывод |
| Value commitment | Гомоморфный commitment Pedersen к сумме |
| Binding signature | Подпись, доказывающая баланс значений без их раскрытия |
| Anchor | Корень дерева, относительно которого трата доказывает принадлежность |
| Trial decryption | Проверка получателем новых commitments, чтобы найти note, предназначенные ему |
Видит ли сеть когда-нибудь сумму или то, кто кому заплатил? Нет. Она проверяет доказательство, новизну nullifier, anchor и binding signature. Все приватные значения остаются скрытыми.
Что мешает мне потратить одну и ту же note дважды? Nullifier. При трате он публикуется; сеть отклоняет любой nullifier, который уже находится в множестве nullifier. Одна и та же note всегда даёт один и тот же nullifier.
Как можно проверить баланс, если суммы скрыты? Value commitments складываются гомоморфно; commitments сбалансированной транзакции сокращаются до commitment к нулю, что и доказывает binding signature.
Могу ли я доказать свои транзакции аудитору, не отдавая ему контроль? Да. Передайте viewing key. Он раскроет вашу shielded-активность, но не сможет авторизовать траты благодаря однонаправленной иерархии ключей.
Sapling устарел теперь, когда существует Orchard? Обе системы существовали в сети; Orchard — это текущий дизайн. Концепции у них общие, поэтому понимание одной даёт понимание другой.
Друг говорит: «Раз доказательство скрывает сумму, вор мог бы просто заявить, что его выводы стоят больше, чем его входы, и напечатать себе бесплатные деньги». Используя раздел 5, объясните в двух предложениях, почему это не сработает. (Ответ ниже.)
Суммы скрыты, но каждая из них заключена в гомоморфный value commitment, и сеть складывает все commitments входов и вычитает все commitments выходов; если бы скрытые значения не сходились, результат не запечатывал бы ноль, и никакую корректную binding signature нельзя было бы создать. Вор может скрыть сколько именно, но не может провести несбалансированные значения через проверку баланса, поэтому напечатать бесплатные деньги невозможно: ничего не раскрывая, он всё равно будет пойман арифметикой.
Теперь вы прошли путь от одного парадокса до полноценного приватного платежа:

Отсюда естественное следующее направление уходит глубже: во внутреннее устройство Groth16 и Halo 2, церемонии trusted setup, подробное устройство схем Sapling и Orchard, выведение ключей и diversified addresses, а также эволюцию протокола через обновления сети. Но фундамент теперь заложен, и у каждой из этих тем уже есть место, к которому её можно привязать.
Часть серии Zcash с первых принципов для ZecHub. Лицензия CC BY-SA 4.0.