FA1.2 Lorentz
Створення контракту на базі стандарту токену FA1.2 Tezos блокчейна
Встановіть інструменти
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
:$ 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.
$ 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_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
заглушку.Визначивши функцію
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)
Якщо ви використовуєте 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
.Почнемо з відкриття
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'
>>> 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()
Нарешті, використовуючи схему параметрів, ми можемо виконати передачу, використовуючи наступні кроки:
- Выпуск
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
є ключовим словом і не може використовуватися для вказівки аргументу, тому ми використовуємо **{..}
для перетворення словника в аргументи ключового слова.Ця помилка виникає, коли залежна операція ще не включена, і може приймати одну з наступних форм:
$ 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]`
Ця помилка може виникнути, якщо параметр
--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
)Last modified 2yr ago