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