Links

FA1.2 Lorentz

Создание контракта на базе стандарта токена FA1.2 Tezos блокчейна

Введение в lorentz-contract-param

lorentz-contract-metadata - является версией FA1.2 с метаданными FA2.
Больше информации по стандарту метаданных FA2 может быть найдено в TZIP-12.
Установите инструменты lorentz-contract-metadata следуя iинструкциям по установке lorentz-contract-metadata.

Создание смарт-контракта

Контракт стандарта FA1.2 должен быть инициализирован со следующими параметрами хранения:
Pair
{} -- Empty ledger big_map
(Pair
"$ALICE_ADDRESS" -- Administrator address
(Pair
False -- Is all activity currently paused? (no)
0 -- Total supply of tokens
)
)
А также иметь встроенные мета-параметры:
  • symbol: string
  • name: string
  • decimals: nat, количество цифр после десятичной точки при выводе.
  • extras: map string string, все остальные мета-параметры
Важно отметить: метаданные FA2 также включают natзначение : token_id которое определено как 0 для контрактов с единственным токеном, таких как FA1.2
В этом примере мы будем использовать:
  • symbol: TOK
  • name: Token
  • decimals: 0
  • extras: {}
Вместо того, чтобы предоставлять параметры контракта в сыром виде на языке Michelson, мы можем использовать lorentz-contract-metadata, чтобы сгенерировать их.
Чтобы создать контракт, запустите следующий код:
$ tezos-client --wait none originate contract ManagedLedger \
transferring 0 from $ALICE_ADDRESS running \
"$(lorentz-contract-metadata Metadata print \
--token-symbol "TOK" \
--token-name "Token" \
--token-decimals 0 \
--oneline)" \
--init "$(lorentz-contract-metadata Metadata init \
--admin $ALICE_ADDRESS \
--initial-ledger '[]')" --burn-cap 5.033 --force
Waiting for the node to be bootstrapped before injection...
Current head: BLoWu4vMmzZb (timestamp: 2020-03-31T19:35:39-00:00, validation: 2020-03-31T19:36:23-00:00)
Node is bootstrapped, ready for injecting operations.
Estimated gas: 142649 units (will add 100 for safety)
Estimated storage: 5033 bytes added (will add 20 for safety)
Operation successfully injected in the node.
Operation hash is 'onnLanKjRG4E64eevGpPP2TFteheNoDEyy8uDMdZGHPgy18YWkC'
NOT waiting for the operation to be included.
Use command
tezos-client wait for onnLanKjRG4E64eevGpPP2TFteheNoDEyy8uDMdZGHPgy18YWkC to be included --confirmations 30 --branch BLoWu4vMmzZbwYkJG8VimgkLis2xS3YSFAMFi4jEuWJ9mHVmKP5
and/or an external block explorer to make sure that it has been included.
This sequence of operations was run:
Manager signed operations:
From: tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHm
Fee to the baker: ꜩ0.001259
Expected counter: 623911
Gas limit: 10000
Storage limit: 0 bytes
Balance updates:
tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHm ............. -ꜩ0.001259
fees(tz1Ke2h7sDdakHJQh8WX4Z372du1KChsksyU,150) ... +ꜩ0.001259
Revelation of manager public key:
Contract: tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHm
Key: edpkuPTVBFtbYd6gZWryXypSYYq6g7FvyucwphoU78T1vmGkbhj6qb
This revelation was successfully applied
Consumed gas: 10000
Manager signed operations:
From: tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHm
Fee to the baker: ꜩ0.019169
Expected counter: 623912
Gas limit: 142749
Storage limit: 5053 bytes
Balance updates:
tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHm ............. -ꜩ0.019169
fees(tz1Ke2h7sDdakHJQh8WX4Z372du1KChsksyU,150) ... +ꜩ0.019169
Origination:
From: tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHm
Credit: ꜩ0
Script:
{...}
Initial storage:
(Pair {} (Pair "tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHm" (Pair False 0)))
No delegate for this contract
This origination was successfully applied
Originated contracts:
KT18apu7iDnqnUeXdMv3ZVjs81DTPWK6f1Me
Storage size: 4776 bytes
Updated big_maps:
New map(735) of type (big_map address (pair nat (map address nat)))
Paid storage size diff: 4776 bytes
Consumed gas: 142649
Balance updates:
tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHm ... -ꜩ4.776
tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHm ... -ꜩ0.257
New contract KT18apu7iDnqnUeXdMv3ZVjs81DTPWK6f1Me originated.
Обратите внимание, что мы сокращаем большое содержимое скрипта с помощью {...}
Создайте переменную для нового адреса контракта:
FA12_ADDRESS=KT18apu7iDnqnUeXdMv3ZVjs81DTPWK6f1Me
Обратите внимание, что на включение наших операций в сеть блокчейнов может потребоваться некоторое время (обычно не более нескольких минут). Чтобы проверить статус операции, используйте её хеш для получения квитанции:
$ tezos-client get receipt for onnLanKjRG4E64eevGpPP2TFteheNoDEyy8uDMdZGHPgy18YWkC
Operation found in block: BLBBGyNZKoi7hrZeszBUmjtfeg8JcjdZMxpUyVTPj24cyyRJQeF (pass: 3, offset: 1)
Manager signed operations:
From: tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHm
Fee to the baker: ꜩ0.001259
Expected counter: 623911
Gas limit: 10000
Storage limit: 0 bytes
Balance updates:
tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHm ............. -ꜩ0.001259
fees(tz1RomaiWJV3NFDZWTMVR2aEeHknsn3iF5Gi,150) ... +ꜩ0.001259
Revelation of manager public key:
Contract: tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHm
Key: edpkuPTVBFtbYd6gZWryXypSYYq6g7FvyucwphoU78T1vmGkbhj6qb
This revelation was successfully applied
Consumed gas: 10000
Manager signed operations:
From: tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHm
Fee to the baker: ꜩ0.019169
Expected counter: 623912
Gas limit: 142749
Storage limit: 5053 bytes
Balance updates:
tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHm ............. -ꜩ0.019169
fees(tz1RomaiWJV3NFDZWTMVR2aEeHknsn3iF5Gi,150) ... +ꜩ0.019169
Origination:
From: tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHm
Credit: ꜩ0
Script:
{...}
Initial storage:
(Pair {} (Pair "tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHm" (Pair False 0)))
No delegate for this contract
This origination was successfully applied
Originated contracts:
KT18apu7iDnqnUeXdMv3ZVjs81DTPWK6f1Me
Storage size: 4776 bytes
Updated big_maps:
New map(735) of type (big_map address (pair nat (map address nat)))
Paid storage size diff: 4776 bytes
Consumed gas: 142649
Balance updates:
tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHm ... -ꜩ4.776
tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHm ... -ꜩ0.257

Просмотры

Когда параметр контракта имеет не единичный тип возврата, например Get Total Supply, который возвращает общее количество токенов, сам контракт должен иметь возможность сохранять результат в каком-то месте. Например, другой контракт может принимать значение результата.
Для следующих примеров нам нужны контракты, принимающие значения address, natи token_metadata:

Для nat

$ tezos-client --wait none originate contract nat_storage transferring 0 \
from $ALICE_ADDRESS running "{ parameter nat ; storage nat ; code { CAR ; NIL operation ; PAIR } }" \
--init 0 --burn-cap 0.295
Waiting for the node to be bootstrapped before injection...
Current head: BKspjAccRQML (timestamp: 2020-03-31T19:40:49-00:00, validation: 2020-03-31T19:41:12-00:00)
Node is bootstrapped, ready for injecting operations.
Estimated gas: 10909 units (will add 100 for safety)
Estimated storage: 295 bytes added (will add 20 for safety)
Operation successfully injected in the node.
Operation hash is 'onfjhheM6UMKwGYbr93a1XiJMEFUa4GyCgxfWJUvZrdGQVrL5RC'
NOT waiting for the operation to be included.
Use command
tezos-client wait for onfjhheM6UMKwGYbr93a1XiJMEFUa4GyCgxfWJUvZrdGQVrL5RC to be included --confirmations 30 --branch BKspjAccRQMLX8JFRtGUzRzenRnBStZiyPWigNihmUmWq3nwyf1
and/or an external block explorer to make sure that it has been included.
This sequence of operations was run:
Manager signed operations:
From: tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHm
Fee to the baker: ꜩ0.001368
Expected counter: 623913
Gas limit: 11009
Storage limit: 315 bytes
Balance updates:
tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHm ............. -ꜩ0.001368
fees(tz1Ke2h7sDdakHJQh8WX4Z372du1KChsksyU,150) ... +ꜩ0.001368
Origination:
From: tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHm
Credit: ꜩ0
Script:
{ parameter nat ; storage nat ; code { CAR ; NIL operation ; PAIR } }
Initial storage: 0
No delegate for this contract
This origination was successfully applied
Originated contracts:
KT1CTP1Bm1DvWCfeDibe8p5EDAAUa4XX4c34
Storage size: 38 bytes
Paid storage size diff: 38 bytes
Consumed gas: 10909
Balance updates:
tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHm ... -ꜩ0.038
tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHm ... -ꜩ0.257
New contract KT1CTP1Bm1DvWCfeDibe8p5EDAAUa4XX4c34 originated.

Для address

$ tezos-client --wait none originate contract address_storage transferring 0 \
from $ALICE_ADDRESS running "{ parameter address ; storage address ; code { CAR ; NIL operation ; PAIR } }" \
--init "\"$ALICE_ADDRESS\"" --burn-cap 0.32
Waiting for the node to be bootstrapped before injection...
Current head: BKveReSTZqs9 (timestamp: 2020-03-31T19:46:17-00:00, validation: 2020-03-31T19:46:29-00:00)
Node is bootstrapped, ready for injecting operations.
Estimated gas: 11314 units (will add 100 for safety)
Estimated storage: 320 bytes added (will add 20 for safety)
Operation successfully injected in the node.
Operation hash is 'oo8CFWkqaRuV4UGm6Ng87WJNYnU3q4YjC1txQcngF4BiF2URQ1V'
NOT waiting for the operation to be included.
Use command
tezos-client wait for oo8CFWkqaRuV4UGm6Ng87WJNYnU3q4YjC1txQcngF4BiF2URQ1V to be included --confirmations 30 --branch BKveReSTZqs9u1hCQzubvS2zm5c3vpeRjxNHnphpsULhNgwjgAZ
and/or an external block explorer to make sure that it has been included.
This sequence of operations was run:
Manager signed operations:
From: tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHm
Fee to the baker: ꜩ0.001448
Expected counter: 623914
Gas limit: 11414
Storage limit: 340 bytes
Balance updates:
tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHm ............. -ꜩ0.001448
fees(tz1Ke2h7sDdakHJQh8WX4Z372du1KChsksyU,150) ... +ꜩ0.001448
Origination:
From: tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHm
Credit: ꜩ0
Script:
{ parameter address ;
storage address ;
code { CAR ; NIL operation ; PAIR } }
Initial storage: "tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHm"
No delegate for this contract
This origination was successfully applied
Originated contracts:
KT1LHvWNJhjGBehhNjd6BeNd1bzJkxhDd4fJ
Storage size: 63 bytes
Paid storage size diff: 63 bytes
Consumed gas: 11314
Balance updates:
tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHm ... -ꜩ0.063
tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHm ... -ꜩ0.257
New contract KT1LHvWNJhjGBehhNjd6BeNd1bzJkxhDd4fJ originated.

Для token_metadata

Сначала определим:
TOKEN_METADATA_TYPE="(list (pair (nat %token_id) (pair (string %symbol) (pair (string %name) (pair (nat %decimals) (map %extras string string))))))"
$ tezos-client --wait none originate contract metadata_storage transferring 0 \
from $ALICE_ADDRESS running "{ parameter $TOKEN_METADATA_TYPE ; storage $TOKEN_METADATA_TYPE ; code { CAR ; NIL operation ; PAIR } }" \
--init '{Pair 0 (Pair "SYMBOL" (Pair "NAME" (Pair 0 {})))}' --burn-cap 0.493 --force
Waiting for the node to be bootstrapped before injection...
Current head: BLFoMNaKmThy (timestamp: 2020-03-31T20:40:53-00:00, validation: 2020-03-31T20:41:04-00:00)
Node is bootstrapped, ready for injecting operations.
Estimated gas: 14859 units (will add 100 for safety)
Estimated storage: 493 bytes added (will add 20 for safety)
Operation successfully injected in the node.
Operation hash is 'opBNgPdvWG6siEEZTFdZXJgpm6gVF6SeZLjR7HJwab2BFjoPoWY'
NOT waiting for the operation to be included.
Use command
tezos-client wait for opBNgPdvWG6siEEZTFdZXJgpm6gVF6SeZLjR7HJwab2BFjoPoWY to be included --confirmations 30 --branch BLFoMNaKmThye5b5qa5yJA2hzNWNhtu6c1wvz84xCg3d3oaa3Pg
and/or an external block explorer to make sure that it has been included.
This sequence of operations was run:
Manager signed operations:
From: tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHm
Fee to the baker: ꜩ0.001961
Expected counter: 623925
Gas limit: 14959
Storage limit: 513 bytes
Balance updates:
tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHm ............. -ꜩ0.001961
fees(tz1Ke2h7sDdakHJQh8WX4Z372du1KChsksyU,150) ... +ꜩ0.001961
Origination:
From: tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHm
Credit: ꜩ0
Script:
{ parameter
(list (pair (nat %token_id)
(pair (string %symbol)
(pair (string %name) (pair (nat %decimals) (map %extras string string)))))) ;
storage
(list (pair (nat %token_id)
(pair (string %symbol)
(pair (string %name) (pair (nat %decimals) (map %extras string string)))))) ;
code { CAR ; NIL operation ; PAIR } }
Initial storage: { Pair 0 (Pair "SYMBOL" (Pair "NAME" (Pair 0 {}))) }
No delegate for this contract
This origination was successfully applied
Originated contracts:
KT1MRPDw2zXGPdL8CrzSaFS9jiqUDM8tpPNn
Storage size: 236 bytes
Paid storage size diff: 236 bytes
Consumed gas: 14859
Balance updates:
tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHm ... -ꜩ0.236
tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHm ... -ꜩ0.257
New contract KT1MRPDw2zXGPdL8CrzSaFS9jiqUDM8tpPNn originated.
Примечание: вам может потребоваться установить/увеличить предел записи, чтобы разрешить создание контракта(ов), например:
$ tezos-client --wait none originate contract address_storage transferring 0 \
from $ALICE_ADDRESS running "{ parameter address ; storage address ; code { CAR ; NIL operation ; PAIR } }" \
--init "\"$ALICE_ADDRESS\"" --burn-cap 0.0001 --dry-run
Waiting for the node to be bootstrapped before injection...
Current head: BLY4388F8VTU (timestamp: 2019-08-30T17:03:46-00:00, validation: 2019-08-30T17:04:08-00:00)
Node is bootstrapped, ready for injecting operations.
Fatal error:
The operation will burn ꜩ0.32 which is higher than the configured burn cap (ꜩ0.0001).
Use `--burn-cap 0.32` to emit this operation.
Затем с помощью tezos-client get receipt for [Operation hash] для каждого хеша операции, сохранить адреса контрактов в переменных:
NAT_STORAGE_ADDRESS="KT1.."
ADDRESS_STORAGE_ADDRESS="KT1.."
METADATA_STORAGE_ADDRESS="KT1.."
Затем вы можете получить доступ к сохраненным значениям с помощью следующих двух команд для natи addressсоответственно:
$ tezos-client get contract storage for $NAT_STORAGE_ADDRESS
0
$ tezos-client get contract storage for $ADDRESS_STORAGE_ADDRESS
"tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHm"

Взаимодействия с помощью тезос-клиента

Команды для взаимодействия с нашим экземпляром контракта ManagedLedger с использованием tezos-client и lorentz-contract-param следуют одному и тому же шаблону с изменением только нескольких параметров в зависимости от того, какую точку входа в контракт мы вызываем. На примере getTotalSupply вызов будет выглядеть так:
$ tezos-client --wait none transfer 0 from $ALICE_ADDRESS to $FA12_ADDRESS \
--arg "$(lorentz-contract-metadata \
Metadata getTotalSupply \
--callback-contract $NAT_STORAGE_ADDRESS)"
Давайте запишем шаблон в функцию оболочки:
$ fa12(){tezos-client --wait none transfer 0 from $ALICE_ADDRESS to $FA12_ADDRESS --burn-cap 0.5 --arg "$(lorentz-contract-metadata Metadata [email protected];)"}
Обратите внимание, что здесь мы также устанавливаем --burn-cap заглушку.

Получение общего предложения через getTotalSupply

Определив функцию fa12, мы можем теперь вызвать точку входа контракта getTotalSupply следующим образом:
$ fa12 getTotalSupply --callback-contract $NAT_STORAGE_ADDRESS
Вывод этой команды выглядит так:
Waiting for the node to be bootstrapped before injection...
Current head: BLkmHajH44cY (timestamp: 2020-03-31T19:51:39-00:00, validation: 2020-03-31T19:52:00-00:00)
Node is bootstrapped, ready for injecting operations.
Estimated gas: 132442 units (will add 100 for safety)
Estimated storage: no bytes added
Operation successfully injected in the node.
Operation hash is 'oothedERdD6hkD45S9ncrnS3u6ienY3px92iSyfjAd4ijLtUjqs'
NOT waiting for the operation to be included.
Use command
tezos-client wait for oothedERdD6hkD45S9ncrnS3u6ienY3px92iSyfjAd4ijLtUjqs to be included --confirmations 30 --branch BLkmHajH44cYRFJzTqmdBnh3efUHGQnjZyKbjAmBB6bgeQbuXzV
and/or an external block explorer to make sure that it has been included.
This sequence of operations was run:
Manager signed operations:
From: tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHm
Fee to the baker: ꜩ0.013564
Expected counter: 623915
Gas limit: 132542
Storage limit: 0 bytes
Balance updates:
tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHm ............. -ꜩ0.013564
fees(tz1Ke2h7sDdakHJQh8WX4Z372du1KChsksyU,150) ... +ꜩ0.013564
Transaction:
Amount: ꜩ0
From: tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHm
To: KT18apu7iDnqnUeXdMv3ZVjs81DTPWK6f1Me
Parameter: (Left (Right (Right (Right (Pair Unit "KT1CTP1Bm1DvWCfeDibe8p5EDAAUa4XX4c34")))))
This transaction was successfully applied
Updated storage:
(Pair 735 (Pair 0x0000aad02222472cdf9892a3011c01caf6407f027081 (Pair False 0)))
Storage size: 4776 bytes
Consumed gas: 121125
Internal operations:
Transaction:
Amount: ꜩ0
From: KT18apu7iDnqnUeXdMv3ZVjs81DTPWK6f1Me
To: KT1CTP1Bm1DvWCfeDibe8p5EDAAUa4XX4c34
Parameter: 0
This transaction was successfully applied
Updated storage: 0
Storage size: 38 bytes
Consumed gas: 11317
Все команды в случае успеха дают одинаковый вывод, поэтому мы опускаем его в следующих примерах.
Значение общего количества токенов будет записано в простом хранилище контракта по адресу NAT_STORAGE_ADDRESS, который мы можем увидеть с помощью следующей команды (как только сеть tezos включит наши операции):
$ tezos-client get contract storage for $NAT_STORAGE_ADDRESS
0

Получение данных администратора

Чтобы получить адрес текущего администратора, сначала поместите его в контракт ADDRESS_STORAGE_ADDRESS:
$ fa12 getAdministrator --callback-contract $ADDRESS_STORAGE_ADDRESS
Как и в случае с NAT_STORAGE_ADDRESS, мы можем получить доступ к результату, используя get contract storage for и убедиться, что он соответствует адресу Алисы, используя echo $ ALICE_ADDRESS:
$ tezos-client get contract storage for $ADDRESS_STORAGE_ADDRESS
"tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHm"
$ echo $ALICE_ADDRESS
tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHm

Получение баланса

Чтобы получить баланс токенов для определенного адреса (хранится в контракте NAT_STORAGE_ADDRESS) используйте:
$ fa12 getBalance --owner $ALICE_ADDRESS --callback-contract $NAT_STORAGE_ADDRESS
Затем мы можем получить доступ к результату, используя:
$ tezos-client get contract storage for $NAT_STORAGE_ADDRESS
0

Получение метаданных

Чтобы получить метаданные токена для конкретного контракта в стиле FA1.2 + FA2 (хранящегося в METADATA_STORAGE_ADDRESS) используйте:
$ fa12 getMetadata --callback-contract $METADATA_STORAGE_ADDRESS
Затем мы можем получить доступ к результату, используя:
$ tezos-client get contract storage for $METADATA_STORAGE_ADDRESS
{ Pair 0 (Pair "TOK" (Pair "Token" (Pair 0 {}))) }

Получение разрешений

Чтобы получить разрешение Боба на снятие средств со счета Алисы, где адрес Боба - BOB_ADDRESS используйте:
$ fa12 getAllowance --owner $ALICE_ADDRESS --spender $BOB_ADDRESS --callback-contract $NAT_STORAGE_ADDRESS
Затем мы можем получить доступ к результату, используя:
$ tezos-client get contract storage for $NAT_STORAGE_ADDRESS
0

Перевод

Из GetBalanceвыше мы знаем, что у Aliceнет токенов.
Чтобы передать токены от Алисы Бобу, нам сначала нужно дать Алисе несколько токенов. Мы можем сделать это, выпустив 5 токенов и назначив их Алисе (см. Подраздел «Выпуск токена» ниже):
$ fa12 mint --value 5 --to $ALICE_ADDRESS
Чтобы передать 2 токена от Алисы Бобу:
$ fa12 transfer --value 2 --from $ALICE_ADDRESS --to $BOB_ADDRESS
Проверьте баланс Боба:
$ fa12 getBalance --owner $BOB_ADDRESS --callback-contract $NAT_STORAGE_ADDRESS
$ tezos-client get contract storage for $NAT_STORAGE_ADDRESS
2

Подтверждение операций

Чтобы Алиса разрешила Бобу снять до 2 токена с ее адреса:
$ fa12 approve --value 2 --spender $BOB_ADDRESS
Затем мы можем проверить полученное разрешение, используя:
$ fa12 getAllowance --owner $ALICE_ADDRESS --spender $BOB_ADDRESS --callback-contract $NAT_STORAGE_ADDRESS
$ tezos-client get contract storage for $NAT_STORAGE_ADDRESS
2
Если мы попытаемся установить другое разрешение (4) для снятия Бобом токенов со счета Алисы, мы потерпим неудачу:
$ fa12 approve --value 4 --spender $BOB_ADDRESS
...
At line 294 characters 85 to 93,
script reached FAILWITH instruction
with (Pair "UnsafeAllowanceChange" 2)
Контракт FA1.2 запрещает прямое изменение разрешения с ненулевого значения на другое ненулевое значение, чтобы предотвратить известную уязвимость к изменению разрешений.
Итак, чтобы сделать такое изменение разрешения возможным, нам нужно сначала установить его в 0:
$ fa12 approve --value 0 --spender $BOB_ADDRESS
а затем установить новое значение 4:
$ fa12 approve --value 4 --spender $BOB_ADDRESS
теперь операция не приведет к провалу.
Обратите внимание, что, в целом, это не совсем безопасно, потому что Боб мог потратить часть полученного от Алисы в промежутке времени между транзакцией, когда мы сначала установили разрешение на 2, и той, где оно было установлено в 0.
Чтобы правильно рассчитать новое значение, отличное от 0, нам нужно было бы просканировать все транзакции, произошедшие между этими двумя, но здесь мы, для простоты, предположим, что их не было.
Теперь мы можем снова проверить разрешение и увидеть, что оно изменилось:
$ fa12 getAllowance --owner $ALICE_ADDRESS --spender $BOB_ADDRESS --callback-contract $NAT_STORAGE_ADDRESS
$ tezos-client get contract storage for $NAT_STORAGE_ADDRESS
4

Выпуск токена

Чтобы выпустить 5 токенов и назначить их Алисе:
$ fa12 mint --value 5 --to $ALICE_ADDRESS
$ fa12 getBalance --owner $ALICE_ADDRESS --callback-contract $NAT_STORAGE_ADDRESS
$ tezos-client get contract storage for $NAT_STORAGE_ADDRESS
5

Сжигание токена

Если вы пошагово следовали этому руководству, на данный момент в учетной записи Боба должно быть 3 токена. Если этого не произошло, добавьте хотя бы 1 с помощью Transfer или Mint.
Перед сжиганием мы сначала добавляем 2 токена на аккаунт Боба:
$ fa12 mint --value 2 --to $BOB_ADDRESS
Мы можем гарантировать, что у Боба есть как минимум 3 токена, используя:
$ fa12 getBalance --owner $BOB_ADDRESS --callback-contract $NAT_STORAGE_ADDRESS
$ tezos-client get contract storage for $NAT_STORAGE_ADDRESS
5
Наконец, мы можем сжечь 2 токена Боба, используя:
$ fa12 burn --value 2 --from $BOB_ADDRESS
И тогда мы можем подтвердить, что два токена были вычтены из аккаунта Боба:
$ fa12 getBalance --owner $BOB_ADDRESS --callback-contract $NAT_STORAGE_ADDRESS
$ tezos-client get contract storage for $NAT_STORAGE_ADDRESS
3

Приостановка контракта

Чтобы приостановить контракт:
$ fa12 setPause --paused True
Мы можем проверить, приостановлен ли контракт, используя:
$ tezos-client get contract storage for $FA12_ADDRESS
Pair 0 (Pair "tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHm" (Pair True 7))
Значение True указывает, что он приостановлен, значение False указывает, что он не приостановлен.
Передачи и подтверждения отключены, пока контракт приостановлен. Попробуйте:
$ fa12 transfer --value 1 --from $ALICE_ADDRESS --to $BOB_ADDRESS
Команда выдает следующий результат (для краткости опуская включенный в контракт код Майкельсона):
Node is bootstrapped, ready for injecting operations.
This simulation failed:
Manager signed operations:
From: tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHm
Fee to the baker: ꜩ0
Expected counter: 32
Gas limit: 800000
Storage limit: 60000 bytes
Transaction:
Amount: ꜩ0
From: tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHm
To: KT1P33YQj5LQGBAYxvpXCsa6v2BXJ8N4i6PF
Parameter: (Left (Left (Left (Pair "tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHm"
(Pair "tz1aSkwEot3L2kmUvcoxzjMomb9mvBNuzFK6" 1)))))
This operation FAILED.
Runtime error in contract KT1P33YQj5LQGBAYxvpXCsa6v2BXJ8N4i6PF:
001: { parameter
...
585: NIL operation ;
586: PAIR } } } } } }
At line 23 characters 87 to 95,
script reached FAILWITH instruction
with (Pair "TokenOperationsArePaused" Unit)
Fatal error:
transfer simulation failed
Чтобы возобновить контракт:
$ fa12 setPause --paused False
$ tezos-client get contract storage for $FA12_ADDRESS
Pair 0 (Pair "tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHm" (Pair False 7))

Установка нового администратора

Чтобы сделать Боба новым администратором:
$ fa12 setAdministrator --new-administrator-address $BOB_ADDRESS
Мы можем убедиться, что администратор был обновлен, используя:
$ fa12 getAdministrator --callback-contract $ADDRESS_STORAGE_ADDRESS
$ tezos-client get contract storage for $ADDRESS_STORAGE_ADDRESS
"tz1RwoEdg4efDQHarsw6aKtMUYvg278Gv1ir"
$ echo $BOB_ADDRESS
tz1RwoEdg4efDQHarsw6aKtMUYvg278Gv1ir
Наша функция оболочки fa12 настроена для вызова операций с использованием $ALICE_ADDRESS, так что теперь, когда $ALICE_ADDRESS больше не является администраторским, попытки вызвать точки входа администратора с этого адреса потерпят неудачу:
$ fa12 mint --value 5 --to $ALICE_ADDRESS
...
586: PAIR } } } } } }
At line 447 characters 86 to 94,
script reached FAILWITH instruction
with (Pair "SenderIsNotAdmin" Unit)

Взаимодействие с использованием PyTezos

Установка PyTezos

Если вы используете Debian или Ubuntu Linux, установите зависимости с помощью apt:
sudo apt install libsodium-dev libsecp256k1-dev libgmp-dev
В Arch Linux установите эти пакеты с помощью pacman:
sudo pacman libsodium libsec256k1 gmp
Вам также может потребоваться установить python-wheel
В противном случае, если у вас Mac OS, установите пакеты с помощью brew:
brew tap cuber/homebrew-libsecp256k1
brew install libsodium libsecp256k1 gmp
Затем установите PyTezos с помощью pip3:
pip3 install pytezos

Создание контракта

Предполагая, что $ALICE_ADDRESS определен, мы можем создать копию FA1.2 почти так же, как с lorentz-contracts.
Примечание: См. Руководство по настройке клиента, чтобы создать кошелек и определить $ALICE_ADDRESS.
Начнем с открытия python3, установки key и shell и указания fa12 в качестве контракта:
Примечание: замените ~/Downloads/tz1R3vJ5TV8Y5pVj8dicBR23Zv8JArusDkYr.json на путь к файлу .json вашего кошелька.
$ python3
Python 3.7.4 (default, Sep 7 2019, 18:27:02)
[Clang 10.0.1 (clang-1001.0.46.4)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from pytezos import pytezos
>>> pytezos = pytezos.using(key='~/Downloads/tz1R3vJ5TV8Y5pVj8dicBR23Zv8JArusDkYr.json', shell='babylonnet')
>>> alice_address = 'tz1R3vJ5TV8Y5pVj8dicBR23Zv8JArusDkYr'
>>> bob_address = 'tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHm'
>>> nat_storage_address = 'KT1J4mhVAaMYAPC4aPEkhC9i48PHBHxavkJ2'
Затем мы определяем Contract из копии ManagedLedger.tz с аннотациями:
>>> from pytezos import Contract
>>> import requests
>>> contract_url = 'https://gitlab.com/tzip/tzip/raw/16ca4fbb60f2ab52958136b76a1d12b342beba58/Proposals/TZIP-0007/ManagedLedger.tz'
>>> fa12src = Contract.from_michelson(requests.get(contract_url).text)
Нам нужно создать начальное хранилище для создания контракта.
Чтобы помочь с этим, мы можем просмотреть схему хранилища контракта:
>>> fa12src.storage
<pytezos.michelson.contract.ContractStorage object at 0x10d984590>
$storage:
{
"ledger": { $address : $ledger_item , ... } /* big_map */,
"admin": $address,
"paused": bool,
"totalSupply": $nat
}
$ledger_item:
{
"balance": $nat,
"approvals": { $address : $nat , ... }
}
$nat:
int /* Natural number */
$address:
string /* Base58 encoded `tz` or `KT` address */
Helpers
.big_map_decode()
.big_map_diff_decode()
.big_map_diff_encode()
.big_map_id()
.big_map_init()
.big_map_query()
.decode()
.default()
.encode()
Затем мы выбираем начальные значения хранилища и кодируем их для подготовки к созданию контракта:
>>> init_storage = fa12src.storage.encode({
...: "ledger": {},
...: "admin": pytezos.key.public_key_hash(),
...: "paused": False,
...: "totalSupply": 0
...: } )
Затем мы создаем контракт:
>>> origination_op = pytezos.origination(script=dict(code=fa12src.code, storage=init_storage)).autofill().sign().inject()
>>> origination_hash = origination_op['hash']
>>> origination_hash
'opXxLwE3j9ZY9Rv99Pomh6u7SonKAoywzpU6KkdWtFryUhBbXdP'
Однако создание контракта не возвращает адрес полученного контракта, поэтому нам нужно найти нашу завершенную операцию в сети и получить из нее адрес контракта:
>>> opg = pytezos.shell.blocks[-5:].find_operation(origination_hash)
>>> contract_id = opg['contents'][0]['metadata']['operation_result']['originated_contracts'][0]
>>> contract_id
'KT1GV7wkUgZpEznQ48VR1UUSgXAU5Lk1SfpH'
>>> fa12 = pytezos.contract(contract_id)
Примечание: команда find_operation может завершиться ошибкой, если операция еще не была обработана:
>>> opg = pytezos.shell.blocks[-5:].find_operation(origination_op)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/lib/python3.7/site-packages/pytezos/tools/docstring.py", line 67, in __call__
return method(self.class_instance, *args, **kwargs)
File "/usr/local/lib/python3.7/site-packages/pytezos/rpc/search.py", line 207, in find_operation
raise StopIteration(operation_group_hash)
StopIteration: oonhxpbH9Jc7fpbjfzvfbetppEBnjUTFmkbziVFV3B5KhjVdzpd

Просмотр схемы контракта

Мы можем просмотреть схему параметров контракта, чтобы узнать, какие точки входа поддерживает контракт и каковы их аргументы:
>>> fa12.contract.parameter
<pytezos.michelson.contract.ContractParameter object at 0x10ce5d910>
$parameter:
{ "transfer": $transfer } ||
{ "approve": $approve } ||
{ "getAllowance": [ $address , $address , $contract (nat) ] } ||
{ "getBalance": [ $address , $contract (nat) ] } ||
{ "getTotalSupply": [ $unit , $contract (nat) ] } ||
{ "setPause": bool /* setPause */ } ||
{ "setAdministrator": $address /* setAdministrator */ } ||
{ "getAdministrator": [ $unit , $contract (address) ] } ||
{ "mint": $mint } ||
{ "burn": $burn }
$burn:
{
"from": $address,
"value": $nat
}
$mint:
{
"to": $address,
"value": $nat
}
$approve:
{
"spender": $address,
"value": $nat
}
$transfer:
{
"from": $address,
"to": $address,
"value": $nat
}
$contract:
string /* Base58 encoded `KT` address */
$nat:
int /* Natural number */
$address:
string /* Base58 encoded `tz` or `KT` address */
$unit:
None /* Void */
Helpers
.decode()
.encode()
.entries()

Взаимодействие с FA1.2

Наконец, используя схему параметров, мы можем выполнить передачу, используя следующие шаги:
  • Выпуск 5 токенав на alice_address
  • Перевод 3 токенов от alice_address к bob_address
  • Хранение баланса bob_address в nat_storage_address
  • Получить значение, которое храниться в nat_storage_address
>>> op = fa12.mint(to=alice_address, value=5).inject()
>>> op['hash']
'opDS6FUYmzXBRpX1DxpnucWBrcyEvCmAsSdjmHJMNpf7xQhGsRW'
>>> op = fa12.transfer(**{'from': alice_address, 'to': bob_address, 'value': 3}).inject()
>>> op['hash']
'ooQRsxqkV3vEtaDdarMzvzFuZLeKe6qfJkZEx9PntzqHGxVo8FU'
>>> op = fa12.getBalance(bob_address, nat_storage_address).inject()
>>> op['hash']
'opUVaphfSFgeUTACVmspr6bXrY82RLJ4mSf4DgT2kNZ6SiEcuh6'
>>> pytezos.contract(nat_storage_address).storage()
3
Примечание. Почему .transfer(**{'from': ..}) вместо .transfer(from=..)? В Python from является ключевым словом и не может использоваться для указания аргумента, поэтому мы используем **{..} для преобразования словаря в аргументы ключевого слова.

Исправление проблем

Counter _ already used

Эта ошибка возникает, когда зависимая операция еще не включена, и может принимать одну из следующих форм:
$ tezos-client --wait none transfer 0 from $ALICE_ADDRESS to $FA12_ADDRESS --arg ..
Waiting for the node to be bootstrapped before injection...
Current head: BMe8VmYBa1Ye (timestamp: 2019-08-12T15:34:56-00:00, validation: 2019-08-12T15:35:00-00:00)
Node is bootstrapped, ready for injecting operations.
Counter 565668 already used for contract tz1QLne6uZFxPRdRfJG8msx5RouENpJoRsfP (expected 565669)
Fatal error:
transfer simulation failed
$ tezos-client --wait none transfer 0 from $ALICE_ADDRESS to $FA12_ADDRESS --arg ..
Waiting for the node to be bootstrapped before injection...
Current head: BL7QrQjGhkut (timestamp: 2019-08-12T15:39:26-00:00, validation: 2019-08-12T15:39:45-00:00)
Node is bootstrapped, ready for injecting operations.
Estimated gas: 212314 units (will add 100 for safety)
Estimated storage: no bytes added
Unregistred error:
{ "kind": "generic",
"error":
"Error while applying operation op1imCEMKFm7bTN9cwX4uoKPb6FjHJDv6NCkWKGVE7srh4XN6UP:\nbranch refused (Error:\n
Counter 565670 already used for contract tz1QLne6uZFxPRdRfJG8msx5RouENpJoRsfP (expected 565671)\n)" }
Fatal error:
transfer simulation failed
Чтобы исправить эту ошибку вы можете предпринять одно из двух:
  • Дождитесь включения операции
  • Запустите tezos-client wait for [Operation Hash] to be includedс зависимыми операциями Operation Hash прежде чем продолжить
    • В качестве альтернативы вы можете запустить: `tz get receipt for
      [Operation Hash]`

Higher than the configured burn cap

Эта ошибка может возникнуть, если параметр --burn-cap не указан или установлен слишком низким для текущей операции:
$ tezos-client --wait none transfer 0 from $ALICE_ADDRESS to $FA12_ADDRESS --arg ..
Waiting for the node to be bootstrapped before injection...
Current head: BLBsvLowXAPf (timestamp: 2019-08-12T15:41:56-00:00, validation: 2019-08-12T15:42:45-00:00)
Node is bootstrapped, ready for injecting operations.
Fatal error:
The operation will burn ꜩ0.021 which is higher than the configured burn cap (ꜩ0).
Use `--burn-cap 0.021` to emit this operation.
Чтобы исправить, замените или добавьте --burn-cap с данной рекомендацией (в данном случае --burn-cap 0.021)
Материалы разработаны TQ Tezos переведены на русский язык Tezos Ukraine