В этом руководстве показано, как взаимодействовать с «FA2-SmartPy» реализацией стандарта FA2 в некоторых распространенных сценариях использования. В первой части используются команды tezos-client для работы с основными передачами и запросами. Вторая часть идет дальше: она использует интерфейс командной строки fatoo для пакетной передачи и использует механизм «оператора» для делегирования прав передачи.
Базовое использование с tezos-client
Это предполагает, что у вас правильно настроен tezos-client для взаимодействия с Carthagenet или с «полной» песочницей.
Для этой части требуется 4 аккаунта, с несколькими импортироваными в tezos-client ꜩ . Аккаунты: administrator, originator, alice иbob.
Согласно нашему руководству по песочнице мы используем alice также как originator и administrator:
FA2-SmartPy использует средства метапрограммирования SmartPy для предоставления более одного контракта Майкельсона. Такие контракты также известны как «сборки». Некоторые сборки доступны по адресу https://gitlab.com/smondet/fa2-smartpy/-/tree/master/michelson, далее в руководстве будет описание различных сборок.
Создание работает так же, как и для любого контракта, нам нужен приведенный выше код, несколько ꜩ и выражение Майкельсона для инициализации хранилища. В нашем случае это должно выглядеть так:
Ожидается, что <nb-of-tokens> является кардиналом карты <tokens-big-map>, а в <ledger-big-map> используются только «известные» токены. Чтобы правильно поддерживать все инварианты, рекомендуется инициализировать хранилище пустым и использовать точку входа %mint для заполнения контракта.
Создадим такой не приостановленный пустой контракт при установке адреса administrator:
$tezos-clientoriginatecontractmyfa2 \transferring0fromoriginator \runningfa2_default.tz \ --init '(Pair (Pair "tz1VSUr8wwNhLAzempoch5d6hLRiTh8Cjcjb" (Pair 0 {})) (Pair (Pair Unit {}) (Pair False {})))' \
--burn-cap10 \--force--no-print-source┃Nodeisbootstrapped.┃Estimatedgas:130373units (will add100forsafety)┃Estimatedstorage:4447bytesadded (will add20forsafety)┃Operationsuccessfullyinjectedinthenode.┃Operationhashis'onosZKPHVN5dGy7LGKX2NV3Tyy3Dyg7qMNeGAn1Eqp7Mwx8sazk'┃Waitingfortheoperationtobeincluded...┃Operationfoundinblock:BM31KMRfkmiDDBMfaq9tCQe5TM6Xhxp3D8XseDWMynG7k81S9q8 (pass: 3,offset:0)┃┃...┃┃tz1VSUr8wwNhLAzempoch5d6hLRiTh8Cjcjb...-ꜩ0.257┃NewcontractKT1Wf2sNVoosmXZqXEppsPZkS4BNAUL7hjTLoriginated.┃Theoperationhasonlybeenincluded0blocksago.┃Werecommendtowaitmore.┃Usecommand┃ tezos-client wait for onosZKPHVN5dGy7LGKX2NV3Tyy3Dyg7qMNeGAn1Eqp7Mwx8sazk to be included --confirmations 30 --branch BMHcbMLmK3avi1ntw9rtcMgyPFjzyUxXhf5a8zDdjKM8eqJHenx
┃and/oranexternalblockexplorer.┃Contractmemorizedasmyfa2.
Выпуск
Здесь мы хотим сделать перевод в качестве administrator, установленного в предыдущем разделе.
Точка входа для выпуска не имеет жесткой стандартизации в спецификации FA2, для fa2-smartpy она должна выглядеть так:
Сборка по умолчанию предполагает, что идентификаторы токенов являются последовательными натуральными числами (0, 1, 2, ...), если из-за какого-то конкретного ограничения пользователю требуются произвольные идентификаторы токенов, в FA2-SmartPy есть опция сборки для создания такого контракта ( см. документацию).
Например, давайте, как administrator, выпустим 100 TK0 токенов на счет alice:
$tezos-clienttransfer0fromadministratortomyfa2 \--entrypointmint \--arg'(Pair (Pair "tz1VSUr8wwNhLAzempoch5d6hLRiTh8Cjcjb" 100) (Pair "TK0" 0))' \--burn-cap3┃Nodeisbootstrapped.┃Estimatedgas:113946units (will add100forsafety)┃Estimatedstorage:163bytesadded (will add20forsafety)┃Operationsuccessfullyinjectedinthenode.┃Operationhashis'onpcARPLVMjXqRfjFxyaZFGnpbCdsP2uSVKQwMiBHie4ujRf7fe'┃Waitingfortheoperationtobeincluded...┃Operationfoundinblock:BMCwBfn9B2E5zmrNfAu3z4rwoTo3h2DhDjTFgsn4BvTB21Xguff (pass: 3,offset:0)┃┃...┃┃Consumedgas:113946┃Balanceupdates:┃tz1VSUr8wwNhLAzempoch5d6hLRiTh8Cjcjb...-ꜩ0.163┃Theoperationhasonlybeenincluded0blocksago.┃Werecommendtowaitmore.┃Usecommand┃ tezos-client wait for onpcARPLVMjXqRfjFxyaZFGnpbCdsP2uSVKQwMiBHie4ujRf7fe to be included --confirmations 30 --branch BM31KMRfkmiDDBMfaq9tCQe5TM6Xhxp3D8XseDWMynG7k81S9q8
┃and/oranexternalblockexplorer.
Перевод
Точка входа передачи в FA2 «группируется» на двух уровнях, т.е. один контрактный вызов содержит список элементов передачи, каждый элемент передачи является «адресом отправителя» и списком исходящих транзакций:
Здесь мы, как alice, переводим 5 из наших 100 TK0 на аккаунт bob:
$tezos-clienttransfer0fromalicetomyfa2 \--entrypointtransfer \ --arg '{ Pair "tz1VSUr8wwNhLAzempoch5d6hLRiTh8Cjcjb" {Pair "tz1aSkwEot3L2kmUvcoxzjMomb9mvBNuzFK6" (Pair 0 5)} }' \
--burn-cap3┃Nodeisbootstrapped.┃Estimatedgas:116015units (will add100forsafety)┃Estimatedstorage:67bytesadded (will add20forsafety)┃Operationsuccessfullyinjectedinthenode.┃Operationhashis'ontGCqsFh1uSDp5vmucU6EJxkivXw6bto2DN8LRekhXdo6WSTjK'┃Waitingfortheoperationtobeincluded...┃Operationfoundinblock:BLgT1CrszWaeEnxo4ncHWHwRZ1g39ig1NxT2zQB8AtCaFKhijnn (pass: 3,offset:0)┃Thissequenceofoperationswasrun:┃┃...┃┃Consumedgas:116015┃Balanceupdates:┃tz1VSUr8wwNhLAzempoch5d6hLRiTh8Cjcjb...-ꜩ0.067┃Theoperationhasonlybeenincluded0blocksago.┃Werecommendtowaitmore.┃Usecommand┃ tezos-client wait for ontGCqsFh1uSDp5vmucU6EJxkivXw6bto2DN8LRekhXdo6WSTjK to be included --confirmations 30 --branch BMCwBfn9B2E5zmrNfAu3z4rwoTo3h2DhDjTFgsn4BvTB21Xguff
┃and/oranexternalblockexplorer.
Получение баланса вне сети
В качестве примера взаимодействия с big-картами в хранилище контрактов с помощью Michelson и tezos-client мы получаем баланс Алисы в токенах TK0.
Нам нужен скрипт, который принимает тип хранилища контракта в качестве параметра (буквально копирует и вставляет) и использует Майкельсон для извлечения значения в карту %ledger; в этом случае мы просто отображаем его с инструкцией FAILWITH, но можно было бы сделать гораздо больше, включая помещение в память (оставлено как упражнение для читателя ☺). Сохраним его как get-balance.tz:
parameter (pair (pair (address %administrator) (pair (nat %all_tokens) (big_map %ledger (pair address nat) nat))) (pair (pair (unit %version_20200724_tzip_a57dfe86_contract) (big_map %operators (pair (address %owner) (address %operator)) unit)) (pair (bool %paused) (big_map %tokens nat (pair (nat %token_id) (pair (string %symbol) (pair (string %name) (pair (nat %decimals) (map %extras string string))))))))) ;storage unit;code { CAR ; # Get parameter CAR ; # Get the pair (admin , _) CDR ; # Get the pair (all_token, ledger) CDR ; # Get %ledger PUSH (pair address nat) (Pair "tz1VSUr8wwNhLAzempoch5d6hLRiTh8Cjcjb" 0); GET ; # Get the value in the ledger at the above key FAILWITH };
В этом случае мы ожидаем сбоя команды tezos-client, поскольку мы хотим прочитать сообщение об ошибке:
$tezos-clientrunscriptget-balance.tzonstorageUnit \andinput \"$(tezos-clientgetcontractstorageformyfa2)"‖‖...‖‖20:GET ; # Get the value in the ledger at the above key‖21:FAILWITH‖22:};‖Atline21characters4to12,‖scriptreachedFAILWITHinstruction‖with (Some 95)‖Fatalerror:‖errorrunningscript
Мы можем отчетливо видеть в значении ошибки (переданном в FAILWITH), что баланс aliceсоставляет 95 TK0 (100 выпущено минус 5 переведено в аккаунт bob).
Приложение fatoo
Получение и настройка клиента
В этом разделе мы используем интерфейс командной строки fatoo для некоторых сборок FA2-SmartPy. Вам нужно установить fatoo по вашему $PATH, или вы можете использовать Docker:
В приложении fatoo есть много команд, см. fatoo [subcommand] --help. В то же время он находится в стадии разработки, поэтому не стесняйтесь отправлять вопросы и запросы функций в основном репозитории.
Для настройки могут использоваться две переменные среды:
fatoo_root_path: логи, вывод
fatoo_client: более важный - это URI, описывающий, как настроить tezos-client и взаимодействовать с узлом
Смотрите команду fatoo show-client-uri-documentation:
URI следует обычному шаблону: <scheme>://<host>:<port>/<path>?<options>:
<scheme> может быть http или http (--tls вариант);
<host>:<port> определяет подключение к узлу;
<path> это закрытый ключ (URI) для учетной записи «спонсора», используется для оплаты горючего и хранения
Доступные <options> это:
bake=true: используйте аккаунт funder запекать блоки после операций инъекции (полезно для «ручных» песочниц);
wait=<INT>: установите опцию --wait для tezos-client (сколько блоков нужно ждать после инъекции операции);
command=<STRING>: используйте альтернативную команду для tezos-client.
См., например, текущее значение по умолчанию: http://:2020/unencrypted:edsk3S7mCwuuMVS21jsYTczxBU4tgTbQp98J3YmTGcstuUxsrZxKYd?bake=true.
Предполагая, что мы используем песочницу, мы можем настроить клиента, используя закрытый ключ alice следующим образом:
Можно сбросить код Майкельсона в файл (см. fatoo get-code --help), но в этом нет необходимости, поскольку можно напрямую создавать контракты из приложения. Давайте создадим mutran_contract, полномасштабную реализацию FA2 с дополнительной точкой входа, которая позволяет администратору переводить средства, которые потенциально могут оказаться на балансе контракта.
$fatoooriginatemutran_contract \--administrator"${admin_pkh}" \--output-addresskt1_mutran_contract.txt‖ [FA2->Info]:‖Originations:‖*Success:mutran_contract (The defaultwithmuteztransferentry-point)‖ ->KT1MSQj5BUmuuDMqoz4jpwabAcuxmhnUjhd9
Чтобы выпускать токены, администратор должен иметь возможность вызывать контракт в цепочке, для этого нам нужно передать как минимум несколько μꜩ на этот адрес. Можно использовать tezos-client, но у fatoo есть команда быстрого доступа для перевода с настроенной учетной записи «спонсора» (суммы указаны в mutez):
$fatoofund-address \"${admin_pkh}" \10_000_000‖ [FA2->Info]: Balance for tz1ZnxqPNMXyiZLTANYJLJ9ZTBpQ5Qu16BXe is now‖1019633807mutez.
Обратите внимание, что на данный момент owner0 не существует в цепочке, мы все еще выпускаем для них токены:
Посмотрим на хранилище; мы видим новые токены TQ0 и TQ1, и, поскольку мы указываем «известного владельца токена» в командной строке, мы можем видеть их балансы:
Сборка контракта, которую мы создали выше, имеет дополнительную точку входа, чтобы иметь возможность перенести баланс контракта, например на случай, если кто-то случайно переведет μꜩ на контракт.
Итак, давайте представим, что после вышеупомянутого ограбления operator хочет публично дать чаевые/подкупить администратора(ов) контракта, пройдя через сам контракт (это может быть запутанным предлогом для включения XTZ в контракт…). Мы вызываем точку входа transfer с пустым списком элементов передачи, но с несколькими XTZ в качестве суммы:
$tezos-clientimportsecretkeyoperator \"${operator_sk}"--forcetezos-clienttransfer1_000fromoperator \to"$(catkt1_mutran_contract.txt)" \--entrypointtransfer \--arg'{}'--burn-cap1┃┃...┃┃Balanceupdates:┃tz1NkpWhHsBSZHPg2Ljz2hycRiZvcYdcyu85...-ꜩ1000┃KT1MSQj5BUmuuDMqoz4jpwabAcuxmhnUjhd9...+ꜩ1000┃Theoperationhasonlybeenincluded0blocksago.┃Werecommendtowaitmore.┃Usecommand┃ tezos-client wait for op2Cibz8jgB2Djb8MEqUg8X7mfKLzywo9SuQxxR2nDMVJZMH14N to be included --confirmations 30 --branch BMWfkKTCCWBatJ3rRXjp2H7DW3cwU4dr8cmP2ddccvnFi1z4geT
┃and/oranexternalblockexplorer.
Мы видим, что теперь fatoo показывает ненулевой баланс контракта:
Давайте заставим admin забрать эти деньги себе; точка входа называется mutez_transfer и принимает пару mutez × address:
$tezos-clientimportsecretkeyadmin \"${admin_sk}"--forcetezos-clienttransfer0fromadmin \to"$(catkt1_mutran_contract.txt)" \--entrypointmutez_transfer \--arg"Pair 1000000000 \"${admin_pkh}\"" \--burn-cap1┃┃...┃┃Balanceupdates:┃KT1MSQj5BUmuuDMqoz4jpwabAcuxmhnUjhd9...-ꜩ1000┃tz1ZnxqPNMXyiZLTANYJLJ9ZTBpQ5Qu16BXe...+ꜩ1000┃Theoperationhasonlybeenincluded0blocksago.┃Werecommendtowaitmore.┃Usecommand┃ tezos-client wait for ooQZfBpcar3jevFxpbvUkdgZPJ67kSrtQ4DAaFDUpkoNAnrV7ji to be included --confirmations 30 --branch BLKDsTiAm4sdSGiKnTuiwmyaSo6NoaVgChPPab3voLoiuvwFfRV
┃and/oranexternalblockexplorer.
Будем надеяться, в этом руководстве достаточно ясно представлена FA2-SmartPy реализация FA2 с точки зрения пользователя. Пожалуйста, поделитесь своим мнением, используя раздел проблемы репозитория. Дополнительные материалы для чтения: