Турнікет
Коротко
- Турнікет — це правило публічного обліку, яке відстежує, скільки вартості входить у кожен захищений пул і виходить з нього
- Він дає змогу будь-кому перевірити, що пул ніколи не виплачує більше, ніж у нього було внесено, навіть якщо транзакції всередині нього є приватними
- Це захищає обсяг ZEC від прихованої помилки, адже підроблені монети не можуть вийти з пулу, не порушивши підрахунок
- Платежі всередині пулу залишаються приватними. Транзакція, що переміщує ZEC між пулами, показує суму, яку вона переміщує
- Саме завдяки турнікету міграція з Orchard до Ironwood може довести, що обсяг захищених коштів є коректним
Для кого це
- Для всіх, хто хоче зрозуміти, як Zcash забезпечує надійність своєї приватної пропозиції
- Для користувачів, які стежать за міграцією з Orchard до Ironwood і хочуть зрозуміти, як вона доводить реальність пропозиції
- Для новачків, яким цікаво, як приватну грошову систему все ж можна аудіювати
Виклик
Shielded Zcash приховує суми, відправників і одержувачів. У цьому і є сенс приватності. Але це породжує складне запитання: якщо ніхто не бачить, що відбувається всередині shielded pool, то як узагалі можна знати, що загальна кількість ZEC є правильною? Як аудіювати гроші, яких не видно?
Якби якась помилка колись дозволила комусь підробляти монети всередині shielded pool, цю підробку приховувала б та сама приватність, що захищає чесних користувачів. Без запобіжника така невизначеність підривала б довіру до всієї пропозиції. Саме турнікет є тим запобіжником, який розв’язує цю проблему.
Що таке турнікет
Уявіть кожен shielded pool як кімнату з одним дверним проходом, де все підраховується. Щоразу, коли вартість входить у pool ззовні або виходить з нього кудись іще, вона проходить через цей прохід і публічно враховується. Транзакції всередині кімнати залишаються приватними, але накопичуваний підсумок на вході видно всім.
Правило просте: pool ніколи не може випустити більше вартості, ніж у нього зайшло. Ноди відхиляють будь-який блок, який зменшив би баланс pool нижче нуля. Суму, яка, як вважається, перебуває всередині pool, завжди відомо, адже це просто загальний обсяг, що увійшов, мінус загальний обсяг, що вийшов. Цей публічний підрахунок і є турнікетом.
Як це працює
За свою історію Zcash мав кілька shielded pool, зокрема Sprout, Sapling і Orchard. Вартість переміщується між transparent chain і цими pool, а інколи й між самими pool. Турнікет відстежує ці переміщення:
- Коли ZEC переходить у захищений пул, ця сума додається до публічного балансу цього пулу
- Коли ZEC виходить із пулу, ця сума віднімається
- Мережа відхиляє будь-який блок, який зробив би баланс пулу від’ємним, тобто коли з нього вийшло б більше, ніж будь-коли увійшло
- Кожна транзакція показує лише свій чистий потік до пулу або з пулу — свій баланс вартості. Для платежу в межах одного пулу це лише комісія
Мережа таким чином відстежує баланс для кожного value pool, зокрема для Sprout, Sapling, Orchard, нового pool Ironwood, а також transparent і lockbox balances. Завдяки цьому, навіть якщо точний вміст pool прихований, максимум, який може з нього будь-коли вийти, обмежений тим, що в нього зайшло. Прихована інфляція не може потрапити в обіг.
Як перевіряється баланс вартості
Підрахунок на вході заслуговує на довіру лише тому, що кожна транзакція змушена довести: вона перемістила правдиву суму, навіть якщо сама сума залишається прихованою. Кожна shielded transaction публікує одне чесне число: чисту вартість, яку вона переміщує в pool або з нього, — так званий value balance. Додатний value balance означає, що кошти вийшли з pool у transparent side, від’ємний означає, що кошти ввійшли. Приватні деталі залишаються запечатаними, але ця єдина чиста величина є публічною, і саме її підсумовує турнікет.
Хитрість у тому, як саме транзакція доводить чесність цього публічного числа, не розкриваючи приватні суми, що стоять за ним. Механізм різниться залежно від pool, і саме це є справжньою механікою турнікета.
У початковому pool Sprout кожна транзакція використовує JoinSplit. JoinSplit витрачає дві приховані note і створює дві нові, а також містить два публічні поля: vpub_old — вартість, що входить до shielded pool із transparent side, і vpub_new — вартість, що виходить із pool назад у transparent side. Кожен JoinSplit має балансуватися сам по собі, а його zero knowledge proof гарантує, що приховані входи й приховані виходи правильно сходяться. Баланс pool Sprout — це просто накопичувана сума всіх vpub_old мінус усі vpub_new по всьому ланцюгу. Саме тому Sprout пізніше є корисним прикладом: оскільки vpub_old — це єдиний спосіб, яким вартість може потрапити в pool, достатньо одного правила, що вимикає його, аби назавжди запечатати цей pool.
У Sapling, Orchard та Ironwood баланс доводиться розумнішим способом — за допомогою binding signature. Замість того щоб кожен переказ балансувався окремо, уся транзакція фіксує кожну приховану суму через value commitment. Value commitment — це запечатаний конверт для числа, побудований за допомогою гомоморфного Pedersen commitment, який має особливу властивість: ці конверти можна додавати й віднімати, не відкриваючи їх. Мережа підсумовує всі input commitments, віднімає всі output commitments і порівнює результат з єдиною заявленою чистою величиною транзакції — її полем valueBalance. Лише транзакція, чиї приховані суми справді відповідають цьому публічному valueBalance, може створити коректний binding signature над об’єднаними commitments. Якби хтось спробував перемістити більше вартості, ніж заявив, commitments не зійшлися б, binding signature не пройшов би перевірку, і транзакцію було б відхилено. Ironwood використовує той самий протокол Orchard, тож працює так само.
Саме це також робить безпечною перевірку міжpool-ового переказу. Коли кошти переходять з одного shielded pool до іншого, наприклад з Orchard в Ironwood, транзакція не може приховати суми від обліку. Кожен pool має власний value balance, який має бути підтверджений власними proofs: сторона Orchard має показати відповідний відтік через свій binding signature, а сторона Ironwood — відповідний приплив через свій. Вартість, що залишає один pool, і вартість, що входить в інший, кожна доводиться незалежно, тож міжpool-ове переміщення — це фактично два проходи через турнікет в одній транзакції: один назовні, один усередину, і обидва публічно враховуються, хоча самі суми в основі залишаються приватними.
Отже, турнікет — це не питання довіри. Кожна транзакція математично доводить власний чистий ефект, мережа підсумовує ці доведені чисті ефекти для кожного pool, а правило консенсусу (ZIP 209) відхиляє будь-який блок, який зробив би баланс pool від’ємним. Доказ на рівні транзакції, примусове виконання на рівні ланцюга.
Чому це важливо
Турнікет дає Zcash одразу три речі.
По-перше, він ізолює ризик. Криптографічна помилка в одному pool обмежується лише цим pool, тому що турнікет не дозволяє підробленій вартості перейти до ширшої пропозиції.
По-друге, він дозволяє спільноті перевіряти пропозицію ретроспективно. Якщо помилку буде виявлено пізніше, запис турнікета покаже, чи виходило коли-небудь з pool більше вартості, ніж у нього входило. Чистий запис є сильним свідченням того, що підробку не було використано.
По-третє, виконуючи все це, він зберігає приватність платежів усередині pool. Кожна транзакція публікує лише свій чистий потік до pool або з нього, який для платежу всередині одного pool є лише комісією. Переказ між pool, наприклад з Orchard до Ironwood, показує суму, що перетинає межу. Аудійованість і приватність співіснують, що трапляється нечасто і є однією з тихих сильних сторін Zcash.
Турнікет у дії
Турнікет — не новий механізм, і його вже використовували в ключові моменти історії Zcash.
Коли Zcash переходив від початкового pool Sprout до нового pool Sapling, турнікет охороняв цей перехід. Згодом для pool Sprout ввели обмеження, щоб він не міг приймати нові надходження, що заохочувало користувачів до міграції, поки турнікет забезпечував чесність обліку. Через роки той факт, що жодна вартість ніколи не покинула Sprout неналежним чином, слугує доказом того, що його ранню криптографію ніколи не було успішно скомпрометовано.
Той самий дизайн тепер захищає перехід з Orchard до Ironwood. У 2026 році в proving system Orchard було знайдено й виправлено помилку soundness. Немає жодних доказів, що нею колись скористалися, але оскільки shielded activity є приватною, повна певність була неможливою. Відповідь полягає в тому, щоб запечатати старий pool Orchard і змусити всіх мігрувати свої кошти через турнікет у Ironwood — новий pool, який використовує виправлений протокол. Примусовий пропуск коштів через турнікет означає, що будь-які гіпотетичні підроблені монети, залишені позаду, не зможуть піти слідом, а після завершення міграції будь-хто зможе підтвердити, що shielded supply є коректною.
Односпрямоване виведення pool з експлуатації
Турнікет дає змогу безпечно вивести старий pool з експлуатації лише в одному напрямку, ніколи не порушуючи гарантії пропозиції. Хитрість у тому, щоб закрити вхід, залишивши вихід відкритим.
Sprout — найнаочніший приклад. Щоб вивести його з експлуатації, ZIP 211 додав одне правило консенсусу: починаючи з висоти його активації, поле vpub_old у кожному JoinSplit має дорівнювати нулю. Оскільки vpub_old — це єдиний спосіб, яким вартість може ввійти в Sprout, примусове встановлення його в нуль означає, що жодна нова вартість більше не зможе туди потрапити, тоді як вартість і далі може виходити до transparent side або прямувати далі в Sapling. Pool став односпрямованим. Він може лише спорожнюватися, але не наповнюватися. Турнікет увесь цей час продовжує рахувати, тому баланс може зменшуватися, коли кошти виходять, але не може зростати і не може стати від’ємним.
Міграція з Orchard до Ironwood використовує ту саму ідею. Під час оновлення NU6.3 pool Orchard закривають для нових надходжень, а wallet спрямовують на відправлення коштів з Orchard через турнікет у новий pool Ironwood. Orchard стає односпрямованим pool, який може лише спорожнюватися. Оскільки кожен вихід — це проходження через турнікет, яке має бути доведене, будь-яка гіпотетична підроблена вартість, що залишилася в Orchard, не може непомітно вийти слідом за чесними коштами. Вона застрягає в pool, який лише спорожнюється і за яким стежать на вході. З часом це веде старий pool до спустошення й дозволяє будь-кому підтвердити, що вартість, яка з нього вийшла, ніколи не перевищувала вартості, яка чесно туди увійшла.
У цьому й полягає глибша причина важливості турнікета, beyond simple accounting. Це механізм, який дозволяє Zcash виводити shielded pool з експлуатації — чи то для зменшення складності, як у випадку зі Sprout, чи для відновлення після виявленої помилки, як у випадку з Orchard, — зберігаючи при цьому безперервну, публічну й доказову гарантію щодо пропозиції.
Поширені хибні уявлення
- Турнікет не розкриває, хто кому і що надіслав. Він показує суму будь-якої транзакції, що переміщує ZEC між пулами
- Він не викриває фальшивомонетника поіменно. Він обмежує, скільки може вийти з пулу, і саме це захищає пропозицію
- Це не новий винахід для Ironwood. Він захищав кожен великий перехід між захищеними пулами в історії Zcash
- Публічний загальний обсяг пулу не послаблює приватність платежів усередині пулу. Переміщення ZEC між пулами показує переміщену суму, тому ZIP 318 просить гаманці з часом здійснювати міграцію стандартними сумами
Ресурси
- ZIP 209: Заборона виходу balance value pool ланцюга за допустимий діапазон - правило консенсусу, що лежить в основі турнікета
- ZIP 211: Вимкнення додавання нової вартості до chain value pool Sprout - як pool Sprout був закритий для нових депозитів
- ZIP 258: NU6.3 - оновлення, яке вводить pool Ironwood і спрямовує вартість через турнікет
- Застосування турнікета проти підробки - початкове пояснення від Electric Coin Company
- Специфікація протоколу Zcash - дивіться розділи про balance і binding signature для повної деталізації
- Value Pools, книга Zebra - як нода відстежує value balance кожного pool
Пов’язані сторінки
- Shielded Pools - як shielded transactions у Zcash зберігають деталі приватними
- Halo - система доказів, що лежить в основі pool Orchard
- Оновлення мережі - як Zcash активує зміни, такі як нові shielded pool