На прошлой неделе разработчик Marigold Пьер-Эммануэль Корньелло объяснил, как работают tickets на Tezos. Мы решили перевести объяснение Пьера-Эммануэля для нашей аудитории и сразу собрать всю доступную информацию о тикетах в одном месте.
Зачем нужны тикеты, если есть токены
В блокчейнах используются два вида токенов: нативные — с механизмом работы заложенным в сам протокол, и обычные — с механизмом работы в смарт-контракте.
tez (XTZ) — нативный токен Tezos. История операций с ним, состояние балансов пользователей, а также методы вроде отправки tez хранятся в самом протоколе.
ctez, kUSD, LP-токены QuipuSwap — обычные токены. Методы для работы с ними, описание (метаданные) и реестр с балансами пользователей (Storage или хранилище) хранятся в их смарт-контрактах.
Технически, кошельки не хранят никаких активов. Они узнают у смарт-контрактов, есть ли в хранилище запись об адресе tz1…, а затем отображают соответствующий баланс. При отправке токена пользователь вызывает соответствующий метод смарт-контракта, чтобы он изменил записи в хранилище.
Например, так выглядит баланс пользователя в смарт-контракте токена PLENTY: addres — публичный ключ, balance — количество токенов.
У токенов есть два недостатка:
- единая точка отказа — смарт-контракт. В теории контракт любого токена можно взломать, а затем их печатать, стирать или заморозить;
- в обновлении Jakarta должно появиться L2-решение Optimistic Rollups. Токены слабо к такому приспособлены: для переноса с L1 на L2 пользователям придется пользоваться мостами для обертывания токенов.
Тикеты решают эти проблемы. Пользователи хранят их на собственных контрактах-кошельках и переносят их между L1 и L2 без обертывания.
Как работают тикеты
Тикеты — это те же токены, но при этом они буквально передаются между контрактами.
Тикет состоит из трех частей:
- ticketer (билетер) — адрес контракта, который создал тикет;
- payload или value (значение) — идентификатор токена. Должен быть сравниваемого типа: nat, int, string и т.д.;
- amount, volume или weight — количество тикетов в записи. Обязательно nat, так как количество не может быть отрицательным.
Значения ticketer и payload фиксируются в момент создания тикета и идентифицируют его. По сути, они работают как адрес и id токена в стандарте FA2.
Значение amount может изменяться методами join (складывание) и split (разделение). Они применяются только к тикетам с одинаковыми значениями payload и ticketer. Например, если применить join к тикетам TICKET(T, P, A1) и TICKET(T, P, A2), получится один тикет TICKET(T, P, A3), где A3 = A1 + A2. Грубо говоря, если два одинаковых контракта выпустят тикеты с одинаковыми payload, Tezos будет считать их совершенно разными тикетами, потому что не совпадает значение ticketer.
Контракт-билетер может хранить в Storage реестр пользователей и принадлежащих им тикетов, как обычный контракт токена. Но билетеру можно добавить метод для создания и отправки тикетов на специальные контракты-кошельки. Таким образом тикеты будут существовать только на кошельках, а дальнейшие операции с ними будут происходить без задействования билетера — больше нет единой точки отказа.
Контракт-кошелек — это контракт, который пользователь самостоятельно создает специально для работы с тикетами. Тикеты нельзя хранить на обычном адресе «tz…», а только на «Kt…». Однако L2-адреса могут хранить тикеты без проблем.
Упрощенно механизм передачи тикетов выглядит так:
- Пользователь создает контракт-кошелек и назначает себя администратором.
- Пользователь вызывает у контракта-билетера функцию затребования тикета и передает ему адрес контракта-кошелька.
- Билетер проверяет, есть ли у пользователя право получить тикет.
- Билетер создает тикет с соответствующим значением.
- Билетер вызывает у кошелька функцию приема и передает тикет в качестве параметра.
- Кошелек добавляет в свое хранилище тикеты.
Кажется, что пользователь может подделать любые тикеты, но это не так. Метод Tezos.create_ticket автоматически записывает в параметр ticketer адрес контракта-минтера. Контракт А не может создать тикеты, которые выглядели бы так, будто их создал контракт В, поэтому передача тикетов между контрактами на деле безопасная.
Как можно использовать тикеты
Эли Генезбургер написал и протестировал пример NFT-аукциона с тикетами вместо FA2, а также пример контракта-кошелька.
Клод Бардо объяснил на примере, как работать с линейными типами и не терять тикеты из-за недоступности команды DUP.
Тикеты можно использовать для репрезентации любых токенов в L2 без постоянного обертывания-развертывания. Например, пользователь отдает uUSD контракту-билетеру и получает такое же количество тикетов типа «uUSD». Он вносит их на депозит в L2, покупает за них другие токены, выводит тикеты и меняет обратно на uUSD.
Тикеты могут заменить мультисиг-контракты. Например, билетер может разрешить доступ к какой-либо функции только при наличии у пользователя определенного тикета.
Почему тикеты еще не используются
Первая причина — сообщество еще не выработало стандарт контракта-кошелька и контракта-тикетера. В стандарт должны входить описание базовых функций: принять тикет, отправить, посмотреть баланс и другие. Без него разработчики приложений и обычных кошельков не смогут хорошо реализовать поддержку тикетов.
Вторая причина — токены FA1.2 и FA2 делают свою работу, у разработчиков есть стандартные имплементации и масса примеров контрактов для работы с токенами. Стоимость газа в Tezos не настолько большая, чтобы сообщество решило перейти на тикеты ради экономии на транзакционных комиссиях.
Подписывайтесь на социальные сети Tezos Ukraine, чтобы ничего не пропустить:
- Telegram-канал
- Facebook.
- Twitter на русском и украинском языках
- Twitter на английском языке
- YouTube-канал
- hub на ForkLog
Изначально мы опубликовали этот материал в блоге Tezos Ukraine.