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(PairFalse -- 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 --forceWaiting 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 commandtezos-client wait for onnLanKjRG4E64eevGpPP2TFteheNoDEyy8uDMdZGHPgy18YWkC to be included --confirmations 30 --branch BLoWu4vMmzZbwYkJG8VimgkLis2xS3YSFAMFi4jEuWJ9mHVmKP5and/or an external block explorer to make sure that it has been included.This sequence of operations was run:Manager signed operations:From: tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHmFee to the baker: ꜩ0.001259Expected counter: 623911Gas limit: 10000Storage limit: 0 bytesBalance updates:tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHm ............. -ꜩ0.001259fees(tz1Ke2h7sDdakHJQh8WX4Z372du1KChsksyU,150) ... +ꜩ0.001259Revelation of manager public key:Contract: tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHmKey: edpkuPTVBFtbYd6gZWryXypSYYq6g7FvyucwphoU78T1vmGkbhj6qbThis revelation was successfully appliedConsumed gas: 10000Manager signed operations:From: tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHmFee to the baker: ꜩ0.019169Expected counter: 623912Gas limit: 142749Storage limit: 5053 bytesBalance updates:tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHm ............. -ꜩ0.019169fees(tz1Ke2h7sDdakHJQh8WX4Z372du1KChsksyU,150) ... +ꜩ0.019169Origination:From: tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHmCredit: ꜩ0Script:{...}Initial storage:(Pair {} (Pair "tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHm" (Pair False 0)))No delegate for this contractThis origination was successfully appliedOriginated contracts:KT18apu7iDnqnUeXdMv3ZVjs81DTPWK6f1MeStorage size: 4776 bytesUpdated big_maps:New map(735) of type (big_map address (pair nat (map address nat)))Paid storage size diff: 4776 bytesConsumed gas: 142649Balance updates:tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHm ... -ꜩ4.776tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHm ... -ꜩ0.257New contract KT18apu7iDnqnUeXdMv3ZVjs81DTPWK6f1Me originated.
Зверніть увагу, що ми скорочуємо великий вміст скрипта за допомогою {...}
Створіть змінну для нової адреси контракту:
FA12_ADDRESS=KT18apu7iDnqnUeXdMv3ZVjs81DTPWK6f1Me
Зверніть увагу, що на включення наших операцій в мережу блокчейнов може знадобитися деякий час (зазвичай не більше кількох хвилин). Щоб перевірити статус операції, використовуйте її хеш для отримання квитанції:
$ tezos-client get receipt for onnLanKjRG4E64eevGpPP2TFteheNoDEyy8uDMdZGHPgy18YWkCOperation found in block: BLBBGyNZKoi7hrZeszBUmjtfeg8JcjdZMxpUyVTPj24cyyRJQeF (pass: 3, offset: 1)Manager signed operations:From: tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHmFee to the baker: ꜩ0.001259Expected counter: 623911Gas limit: 10000Storage limit: 0 bytesBalance updates:tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHm ............. -ꜩ0.001259fees(tz1RomaiWJV3NFDZWTMVR2aEeHknsn3iF5Gi,150) ... +ꜩ0.001259Revelation of manager public key:Contract: tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHmKey: edpkuPTVBFtbYd6gZWryXypSYYq6g7FvyucwphoU78T1vmGkbhj6qbThis revelation was successfully appliedConsumed gas: 10000Manager signed operations:From: tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHmFee to the baker: ꜩ0.019169Expected counter: 623912Gas limit: 142749Storage limit: 5053 bytesBalance updates:tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHm ............. -ꜩ0.019169fees(tz1RomaiWJV3NFDZWTMVR2aEeHknsn3iF5Gi,150) ... +ꜩ0.019169Origination:From: tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHmCredit: ꜩ0Script:{...}Initial storage:(Pair {} (Pair "tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHm" (Pair False 0)))No delegate for this contractThis origination was successfully appliedOriginated contracts:KT18apu7iDnqnUeXdMv3ZVjs81DTPWK6f1MeStorage size: 4776 bytesUpdated big_maps:New map(735) of type (big_map address (pair nat (map address nat)))Paid storage size diff: 4776 bytesConsumed gas: 142649Balance updates:tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHm ... -ꜩ4.776tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHm ... -ꜩ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.295Waiting 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 commandtezos-client wait for onfjhheM6UMKwGYbr93a1XiJMEFUa4GyCgxfWJUvZrdGQVrL5RC to be included --confirmations 30 --branch BKspjAccRQMLX8JFRtGUzRzenRnBStZiyPWigNihmUmWq3nwyf1and/or an external block explorer to make sure that it has been included.This sequence of operations was run:Manager signed operations:From: tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHmFee to the baker: ꜩ0.001368Expected counter: 623913Gas limit: 11009Storage limit: 315 bytesBalance updates:tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHm ............. -ꜩ0.001368fees(tz1Ke2h7sDdakHJQh8WX4Z372du1KChsksyU,150) ... +ꜩ0.001368Origination:From: tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHmCredit: ꜩ0Script:{ parameter nat ; storage nat ; code { CAR ; NIL operation ; PAIR } }Initial storage: 0No delegate for this contractThis origination was successfully appliedOriginated contracts:KT1CTP1Bm1DvWCfeDibe8p5EDAAUa4XX4c34Storage size: 38 bytesPaid storage size diff: 38 bytesConsumed gas: 10909Balance updates:tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHm ... -ꜩ0.038tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHm ... -ꜩ0.257New 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.32Waiting 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 commandtezos-client wait for oo8CFWkqaRuV4UGm6Ng87WJNYnU3q4YjC1txQcngF4BiF2URQ1V to be included --confirmations 30 --branch BKveReSTZqs9u1hCQzubvS2zm5c3vpeRjxNHnphpsULhNgwjgAZand/or an external block explorer to make sure that it has been included.This sequence of operations was run:Manager signed operations:From: tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHmFee to the baker: ꜩ0.001448Expected counter: 623914Gas limit: 11414Storage limit: 340 bytesBalance updates:tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHm ............. -ꜩ0.001448fees(tz1Ke2h7sDdakHJQh8WX4Z372du1KChsksyU,150) ... +ꜩ0.001448Origination:From: tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHmCredit: ꜩ0Script:{ parameter address ;storage address ;code { CAR ; NIL operation ; PAIR } }Initial storage: "tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHm"No delegate for this contractThis origination was successfully appliedOriginated contracts:KT1LHvWNJhjGBehhNjd6BeNd1bzJkxhDd4fJStorage size: 63 bytesPaid storage size diff: 63 bytesConsumed gas: 11314Balance updates:tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHm ... -ꜩ0.063tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHm ... -ꜩ0.257New 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 --forceWaiting 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 commandtezos-client wait for opBNgPdvWG6siEEZTFdZXJgpm6gVF6SeZLjR7HJwab2BFjoPoWY to be included --confirmations 30 --branch BLFoMNaKmThye5b5qa5yJA2hzNWNhtu6c1wvz84xCg3d3oaa3Pgand/or an external block explorer to make sure that it has been included.This sequence of operations was run:Manager signed operations:From: tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHmFee to the baker: ꜩ0.001961Expected counter: 623925Gas limit: 14959Storage limit: 513 bytesBalance updates:tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHm ............. -ꜩ0.001961fees(tz1Ke2h7sDdakHJQh8WX4Z372du1KChsksyU,150) ... +ꜩ0.001961Origination:From: tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHmCredit: ꜩ0Script:{ 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 contractThis origination was successfully appliedOriginated contracts:KT1MRPDw2zXGPdL8CrzSaFS9jiqUDM8tpPNnStorage size: 236 bytesPaid storage size diff: 236 bytesConsumed gas: 14859Balance updates:tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHm ... -ꜩ0.236tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHm ... -ꜩ0.257New 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-runWaiting 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_ADDRESS0$ 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 addedOperation successfully injected in the node.Operation hash is 'oothedERdD6hkD45S9ncrnS3u6ienY3px92iSyfjAd4ijLtUjqs'NOT waiting for the operation to be included.Use commandtezos-client wait for oothedERdD6hkD45S9ncrnS3u6ienY3px92iSyfjAd4ijLtUjqs to be included --confirmations 30 --branch BLkmHajH44cYRFJzTqmdBnh3efUHGQnjZyKbjAmBB6bgeQbuXzVand/or an external block explorer to make sure that it has been included.This sequence of operations was run:Manager signed operations:From: tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHmFee to the baker: ꜩ0.013564Expected counter: 623915Gas limit: 132542Storage limit: 0 bytesBalance updates:tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHm ............. -ꜩ0.013564fees(tz1Ke2h7sDdakHJQh8WX4Z372du1KChsksyU,150) ... +ꜩ0.013564Transaction:Amount: ꜩ0From: tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHmTo: KT18apu7iDnqnUeXdMv3ZVjs81DTPWK6f1MeParameter: (Left (Right (Right (Right (Pair Unit "KT1CTP1Bm1DvWCfeDibe8p5EDAAUa4XX4c34")))))This transaction was successfully appliedUpdated storage:(Pair 735 (Pair 0x0000aad02222472cdf9892a3011c01caf6407f027081 (Pair False 0)))Storage size: 4776 bytesConsumed gas: 121125Internal operations:Transaction:Amount: ꜩ0From: KT18apu7iDnqnUeXdMv3ZVjs81DTPWK6f1MeTo: KT1CTP1Bm1DvWCfeDibe8p5EDAAUa4XX4c34Parameter: 0This transaction was successfully appliedUpdated storage: 0Storage size: 38 bytesConsumed gas: 11317
Всі команди в разі успіху дають однаковий вивід, тому ми опускаємо його в наступних прикладах.
Значення загальної кількості токенів буде записано в просте сховище контракту за адресою NAT_STORAGE_ADDRESS
, яку ми можемо побачити за допомогою наступної команди (як тільки мережа tezos включить наші операції):
$ tezos-client get contract storage for $NAT_STORAGE_ADDRESS0
Щоб отримати адресу поточного адміністратора, спочатку помістіть його в контракт 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_ADDRESStz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHm
Щоб отримати баланс токенів для певної адреси (зберігається в контракті NAT_STORAGE_ADDRESS
) використовуйте:
$ fa12 getBalance --owner $ALICE_ADDRESS --callback-contract $NAT_STORAGE_ADDRESS
Потім ми можемо отримати доступ до результату, використовуючи:
$ tezos-client get contract storage for $NAT_STORAGE_ADDRESS0
Щоб отримати метадані токена для конкретного контракту в стилі 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_ADDRESS0
З 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_ADDRESS2
Щоб Аліса дозволила Бобу зняти до 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_ADDRESS2
Якщо ми спробуємо встановити інший дозвіл (4
) для зняття Бобом токенов з рахунку Аліси, ми зазнаємо невдачі:
$ fa12 approve --value 4 --spender $BOB_ADDRESS...At line 294 characters 85 to 93,script reached FAILWITH instructionwith (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_ADDRESS4
Щоб випустити 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_ADDRESS5
Якщо ви покроково йшли по цьому керівництву, на даний момент в обліковому запису Боба повинно бути 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_ADDRESS5
Нарешті, ми можемо спалити 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_ADDRESS3
Щоб призупинити контракт:
$ fa12 setPause --paused True
Ми можемо перевірити, чи призупинено контракт, використовуючи:
$ tezos-client get contract storage for $FA12_ADDRESSPair 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: tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHmFee to the baker: ꜩ0Expected counter: 32Gas limit: 800000Storage limit: 60000 bytesTransaction:Amount: ꜩ0From: tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHmTo: KT1P33YQj5LQGBAYxvpXCsa6v2BXJ8N4i6PFParameter: (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 instructionwith (Pair "TokenOperationsArePaused" Unit)Fatal error:transfer simulation failed
Щоб відновити контракт:
$ fa12 setPause --paused False
$ tezos-client get contract storage for $FA12_ADDRESSPair 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_ADDRESStz1RwoEdg4efDQHarsw6aKtMUYvg278Gv1ir
Наша функція оболонки fa12
налаштована для виклику операцій з використанням $ALICE_ADDRESS
, так що тепер, коли $ALICE_ADDRESS
більше не є перевіреним адміністратором, спроби викликати точки входу адміністратора з цієї адреси зазнають невдачі:
$ fa12 mint --value 5 --to $ALICE_ADDRESS...586: PAIR } } } } } }At line 447 characters 86 to 94,script reached FAILWITH instructionwith (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-libsecp256k1brew 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
вашого гаманця.
$ python3Python 3.7.4 (default, Sep 7 2019, 18:27:02)[Clang 10.0.1 (clang-1001.0.46.4)] on darwinType "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_operationraise 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 addedUnregistred error:{ "kind": "generic","error":"Error while applying operation op1imCEMKFm7bTN9cwX4uoKPb6FjHJDv6NCkWKGVE7srh4XN6UP:\nbranch refused (Error:\nCounter 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
)
Матеріали розроблені TQ Tezos перекладені українською мовою Tezos Ukraine