Давайте разберём принцип работы более сложной модели пользовательского токена на блокчейне Aleo. Ранее мы разбирались, как можно реализовать работу простейшего токена. В этой статье мы рассмотрим пример токена, в котором мы можем управлять нашей анонимностью, т.е. узнаем, как можно разделить публичные и приватные переводы.
Начнём с конструктора контракта:
Важно отметить, что в отличие от простейшей версии токена, в этот раз мы пользуемся mapping для возможности вывода некоторой информации публично. В нашем случае — это связка адрес-баланс.
Далее будем определять функции для чеканки и перевода. Всего у нас будет 6 функций: приватная и публичная чеканка, приватный и публичный переводы, затем перевод от секретного отправителя публичному получателю, и наконец перевод от публичного отправителя секретному получателю.
Начнём с чеканки:
В публичной чеканке мы сразу переходим к блоку finalize и там добавляем баланс к адресу в mapping account
. Отметим, что функция mint сработает только в случае, когда аккаунт-получатель имеет нулевой баланс (не имеет записей).
В приватной чеканке всё происходит немного по другому. Поскольку контент, выполненный в “finalize” будет виден всем пользователям блокчейна, мы ограничиваемся лишь transition (off-chain часть контракта):
Публичный трансфер: всё то же самое, что и в публичной чеканке, однако не забываем вычесть баланс отправителя. Функция не сработает в случае, когда у отправителя недостаточно средств для перевода.
В приватном переводе мы так же придерживаемся блока transition. Первой операцией мы вычисляем остаток средств на балансе отправителя после перевода (и пруф не сможет сгенерироваться для этой функции в случае, если число difference зайдёт за пределы unsigned int (здесь это u64), т.е. если попробует стать отрицательным).
Затем следует обновление баланса отправителя, после — обновление баланса получателя:
Перевод от секретного отправителя публичному получателю: здесь мы видим почти всё то же самое, что и в предыдущей функции. Мы вычитаем баланс отправителя в transition, но добавляем баланс получателю в finalize, применяя increment к маппингу account:
Перевод от публичного к секретному — то же самое, но наоборот: