Создание простого проекта ZK на TON
Эта страница переведена сообществом на русский язык, но нуждается в улучшениях. Если вы хотите принять участие в переводе свяжитесь с @alexgton.
👋 Введение
Доказательства с нулевым разглашением (ZK) — это фундаментальный криптографический примитив, который позволяет одной стороне (доказывающей) доказать другой стороне (проверяюще й), что утверждение истинно, не раскрывая никакой информации, выходящей за рамки действительности самого утверждения. Доказательства с нулевым разглашением — это мощный инструмент для создания систем, сохраняющих конфиденциальность, и использовались в различных приложениях, включая анонимные платежи, анонимные системы обмена сообщениями и не требующие доверия мосты.
До июня 2023 года было невозможно проверить криптографические доказательства на TON. Из-за преобладания сложных вычислений за алгоритмом сопряжения потребовалось расширить функциональность TVM, добавив коды операций TVM для проведения проверки доказательств. Эта функциональность была добавлена в обновлении за июнь 2023 г. и на момент написания статьи доступна только в тестовой сети.
🦄 В этом руководстве будут рассмотрены
- Основы криптографии с нулевым разглашением и, в частности, zk-SNARK (Краткое неинтерактивное подтверждение знаний с нулевым разглашением - Zero-Knowledge Succinct Non-Interactive Argument of Knowledge)
- Инициирование церемонии доверенной установки (с использованием возможностей Tau)
- Написание и компиляция простой схемы ZK (с использованием языка Circom)
- Создание, развертывание и тестирование контракта FunC для проверки образца ZK-доказательства
🟥🟦 Объяснение доказательств ZK на примере с цветовой гаммой
Прежде чем углубиться в детали нулевого разглашения, давайте начнем с простой проблемы. Предположим, вы хотите доказать дальтонику, что можно различать цвета. Мы воспользуемся интерактивным решением для решения этой проблемы. Предположим, дальтоник (проверяющий) находит два одинаковых листка бумаги, один из которых красный 🟥, а другой синий 🟦.
Проверяющий показывает один из листков бумаги вам (доказывающему) и просит запомнить цвет. Затем проверяющий держит этот конкретный листок бумаги за спиной и либо оставляет его прежним, либо меняет его и спрашивает вас, изменился ли цвет или нет. Если вы можете заметить разницу, то вы можете видеть цвета (или вам просто повезло, потому что у вас был 50% шанс угадать правильный цвет).
Теперь, если проверяющий выполнит этот процесс 10 раз, и вы сможете заметить разницу каждый раз, то проверяющий на ~99,90234% (1 - (1/2)^10) уверен, что используются правильные цвета. Таким образом, если верификатор завершит процесс 30 раз, то верифик атор будет уверен на 99,99999990686774% (1 - (1/2)^30).
Тем не менее, это интерактивное решение, и неэффективно иметь DApp, которое просит пользователей отправить 30 транзакций для подтверждения определенных данных. Поэтому необходимо неинтерактивное решение; здесь вступают в дело Zk-SNARK и Zk-STARK.
Для целей этого руководства мы рассмотрим только Zk-SNARK. Однако вы можете прочитать больше о том, как работают Zk-STARK, на сайте StarkWare, а информацию, сравнивающую различия между Zk-SNARK и Zk-STARK, можно найти в этой записи в блоге Panther Protocol.**
🎯 Zk-SNARK: Zero-Knowledge Succinct Non-Interactive Argument of Knowledge
Zk-SNARK — это неинтерактивная система доказательства, в которой доказывающий может продемонстрировать проверяющему, что утверждение истинно, просто предоставив одно доказательство. А проверяющий может проверить доказательство за очень короткое время. Обычно работа с Zk-SNARK состоит из трех основных этапов:
- Проведение доверенной настройки с использованием протокола многосторонних вычислений (MPC) для генерации ключей подтверждения и проверки (с использованием полномочий TAU)
- Генерация доказательства с использованием ключа подтверждающего, открытого ввода и секретного ввода (свидетеля)
- Проверка доказательства
Давайте настроим нашу среду разработки и начнем кодировать!
⚙ Настройка среды разработки
Давайте начнем процесс, выполнив следующие шаги:
- Создайте новый проект под названием «simple-zk» с помощью Blueprint, выполнив следующую команду, после этого введите имя для вашего контракта (например, ZkSimple), а затем выберите п ервый вариант (используя пустой контракт).
npm create ton@latest simple-zk
- Далее мы клонируем репозиторий snarkjs, настроенный для поддержки контрактов FunC
git clone https://github.com/kroist/snarkjs.git
cd snarkjs
npm ci
cd ../simple-zk
- Затем мы установим необходимые библиотеки для ZkSNARKs
npm add --save-dev snarkjs ffjavascript
npm i -g circom
- Далее мы добавим следующий раздел в package.json (обратите внимание, что некоторые из кодов операций, которые мы будем использовать, пока недоступны в выпуске основной сети)
"overrides": {
"@ton-community/func-js-bin": "0.4.5-tvmbeta.1",
"@ton-community/func-js": "0.6.3-tvmbeta.1"
}
- Кроме того, нам нужно будет изменить версию @ton-community/sandbox, чтобы иметь возможность использовать последние обновления TVM
npm i --save-dev @ton-community/[email protected]
Отлично! Теперь мы готовы начать писать наш первый проект ZK на TON!
В настоящее время у нас есть две основные папки, из которых состоит наш проект ZK:
- Папка
simple-zk
: содержит наш шаблон Blueprint, который позволит нам писать схему, контракты и тесты - Папка
snarkjs
: содержит репозиторий snarkjs, который мы клонировали на шаге 2
Схема Circom
Сначала давайте создадим папку simple-zk/circuits
, а затем создадим в ней файл и добавим в него следующий код:
template Multiplier() {
signal private input a;
signal private input b;
//private input means that this input is not public and will not be revealed in the proof
signal output c;
c <== a*b;
}
component main = Multiplier();
Выше мы добавили простую схему умножения. Используя эту схему, мы можем доказать, что знаем два числа, которые при умножении дают определенное число (c), не раскрывая сами соответствующие числа (a и b).
Чтобы узнать больше о языке circom, посетите этот сайт.
Д алее мы создадим папку для наших файлов сборки и переместим туда данные, выполнив следующее (находясь в папке simple-zk
):
mkdir -p ./build/circuits
cd ./build/circuits