Швидкий старт з Oracle

Вступ

Смарт-контракти, які вимагають зовнішніх даних або подій в режимі реального часу, вимагають довіреної oracle, тобто довіреного смарт-контракту, який надає дані в ланцюжку.
Для чого це корисно?
  • Оракул, який надає ціни XTZ / USD, може дозволити користувачам вносити кошти, які негайно конвертуються в будь-який актив в ланцюжку і представляються як вказівку до дії.
  • Оракул, який надає дані про погоду, може дозволити укласти договір страхування від цунамі: користувачі купують покриття за контрактом, яке виплачується, коли в їхньому районі з'явиться досить сильне цунамі
  • Комбінація різних оракулів може використовуватися для досягнення консенсусу, наприклад, де тільки результати, опубліковані більшістю оракулів, вважаються дійсними.

Встановлення

CLI

❯❯❯ lorentz-contract-oracle Oracle --help
Usage: lorentz-contract-oracle Oracle COMMAND
Oracle contract CLI interface
Available options:
-h,--help Show this help text
Available commands:
print Dump the Oracle contract in form of Michelson code
print-timestamped Dump the Timestamped Oracle contract in form of
Michelson code
init Initial storage for the Oracle contract
get-value get value
update-value update value
update-admin update admin

Створення контракту

Друк контракту

Команда друку приймає єдиний аргумент: valueType, тип значення, наданого оракулом.
Примітка. Поки проблема №6 в репозиторії не буде виправлена, інструмент CLI видаватиме помилку, якщо valueType не є nat при друку контракту або в timestamped версії.
Наприклад, якщо nat значення передані:
❯❯❯ lorentz-contract-oracle Oracle print --valueType "nat"
parameter (or (pair %getValue unit
(contract nat))
(or (nat %updateValue)
(address %updateAdmin)));
storage (pair nat
address);
code { CAST (pair (or (pair unit (contract nat)) (or nat address)) (pair nat address));
DUP;
CAR;
DIP { CDR };
IF_LEFT { DUP;
CAR;
DIP { CDR };
DIP { DIP { DUP };
SWAP };
PAIR;
CDR;
CAR;
DIP { AMOUNT };
TRANSFER_TOKENS;
NIL operation;
SWAP;
CONS;
PAIR }
{ IF_LEFT { DIP { DUP;
CAR;
DIP { CDR } };
DIP { DROP;
DUP;
DIP { SENDER;
COMPARE;
EQ;
IF { }
{ PUSH string "only admin may update";
FAILWITH } } };
PAIR;
NIL operation;
PAIR }
{ DIP { DUP;
CAR;
DIP { CDR };
DIP { SENDER;
COMPARE;
EQ;
IF { }
{ PUSH string "only admin may update";
FAILWITH } } };
SWAP;
PAIR;
NIL operation;
PAIR } } };

Початкове зберігання

❯❯❯ lorentz-contract-oracle Oracle init --help
Usage: lorentz-contract-oracle Oracle init --initialValueType Michelson Type
--initialValue Michelson Value
--admin ADDRESS
Initial storage for the Oracle contract
Available options:
-h,--help Show this help text
--initialValueType Michelson Type
The Michelson Type of initialValue
--initialValue Michelson Value
The Michelson Value: initialValue
--admin ADDRESS Address of the admin.
-h,--help Show this help text
Оскільки ми використовуємо nat, initialValueType має значення nat, а initialValue може бути 0:
❯❯❯ lorentz-contract-oracle Oracle init \
--initialValueType "nat" \
--initialValue 3 \
--admin $ALICE_ADDRESS
Pair 3 "tz1R3vJ5TV8Y5pVj8dicBR23Zv8JArusDkYr"

Запуск старту контракту

ПРИМІТКА: щоб використовувати анотовану (timestamped) версію, наприклад для nat:
❯❯❯ tezos-client --wait none originate contract NatOracle \
transferring 0 from $ALICE_ADDRESS running \
"$(lorentz-contract-oracle Oracle print-timestamped --valueType "nat")" \
--init "$(lorentz-contract-oracle Oracle init \
--initialValueType "pair timestamp nat" --initialValue 'Pair "2019-12-10T17:43:53Z" 26871' \
--admin $ALICE_ADDRESS)" --burn-cap 0.859 --force
ПРИМІТКА: контракт nat_oracle.tz можна знайти тут
Інакше:
❯❯❯ tezos-client --wait none originate contract NatOracle \
transferring 0 from $ALICE_ADDRESS running \
"$(lorentz-contract-oracle Oracle print --valueType "nat")" \
--init "$(lorentz-contract-oracle Oracle init \
--initialValueType "nat" --initialValue 3 \
--admin $ALICE_ADDRESS)" --burn-cap 0.612
Waiting for the node to be bootstrapped before injection...
Current head: BLE8kx6VhXbk (timestamp: 2020-04-03T15:28:43-00:00, validation: 2020-04-03T15:29:02-00:00)
Node is bootstrapped, ready for injecting operations.
Estimated gas: 20483 units (will add 100 for safety)
Estimated storage: 683 bytes added (will add 20 for safety)
Operation successfully injected in the node.
Operation hash is 'onsEwbbm71wpzgnk6baBGacDzsnKceypEL841STJ6B5V9cA4swr'
NOT waiting for the operation to be included.
Use command
tezos-client wait for onsEwbbm71wpzgnk6baBGacDzsnKceypEL841STJ6B5V9cA4swr to be included --confirmations 30 --branch BLE8kx6VhXbka6FGjXmKxnH56iypJLYZ9pM5mM3HLKvoVDBiMeS
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.002729
Expected counter: 623928
Gas limit: 20583
Storage limit: 703 bytes
Balance updates:
tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHm ............. -ꜩ0.002729
fees(tz1Ke2h7sDdakHJQh8WX4Z372du1KChsksyU,154) ... +ꜩ0.002729
Origination:
From: tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHm
Credit: ꜩ0
Script:
{...}
Initial storage: (Pair 3 "tz1R3vJ5TV8Y5pVj8dicBR23Zv8JArusDkYr")
No delegate for this contract
This origination was successfully applied
Originated contracts:
KT1LVLUsC1WCo4yHzeoDEE8FxxoC7EW6bSyp
Storage size: 426 bytes
Paid storage size diff: 426 bytes
Consumed gas: 20483
Balance updates:
tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHm ... -ꜩ0.426
tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHm ... -ꜩ0.257
New contract KT1LVLUsC1WCo4yHzeoDEE8FxxoC7EW6bSyp originated.
Contract memorized as NatOracle.
Створіть псевдонім для отриманої адреси:
❯❯❯ ORACLE_ADDRESS="KT1LVLUsC1WCo4yHzeoDEE8FxxoC7EW6bSyp"

Отримання значення

Підготовка до перегляду контракту

Старт контракту:
❯❯❯ tezos-client --wait none originate contract nat_storage transferring 0 \
from $ALICE_ADDRESS running "$(lorentz-contract print --name NatStorageContract)" \
--init 0 --burn-cap 0.295
Створіть псевдонім для отриманої адреси:
❯❯❯ NAT_STORAGE_ADDRESS="KT1ShW17HERZgjUTxSxSc4W3tuWrfLCqBmEi"
Див. FA1.2 для отримання додаткової інформації.

Створення параметра

❯❯❯ lorentz-contract-oracle Oracle get-value --help
Usage: lorentz-contract-oracle Oracle get-value --callbackContract ADDRESS
get value
Available options:
-h,--help Show this help text
--callbackContract ADDRESS
Address of the callbackContract.
-h,--help Show this help text
❯❯❯ lorentz-contract-oracle Oracle get-value --callbackContract $NAT_STORAGE_ADDRESS
Left (Pair Unit "KT1ShW17HERZgjUTxSxSc4W3tuWrfLCqBmEi")

Отримання значення

❯❯❯ tezos-client --wait none transfer 0 from $ALICE_ADDRESS to $ORACLE_ADDRESS \
--arg "$(lorentz-contract-oracle Oracle get-value \
--callbackContract $NAT_STORAGE_ADDRESS)" --burn-cap 0.000001
Waiting for the node to be bootstrapped before injection...
Current head: BL7fbZE3Gs2V (timestamp: 2020-04-03T15:33:25-00:00, validation: 2020-04-03T15:33:45-00:00)
Node is bootstrapped, ready for injecting operations.
Estimated gas: 31566 units (will add 100 for safety)
Estimated storage: no bytes added
Operation successfully injected in the node.
Operation hash is 'opWqWvkJczWzq5m99svSDzW7HmWY5nCUB1rerDn6utLLH5NJ1dS'
NOT waiting for the operation to be included.
Use command
tezos-client wait for opWqWvkJczWzq5m99svSDzW7HmWY5nCUB1rerDn6utLLH5NJ1dS to be included --confirmations 30 --branch BL7fbZE3Gs2VkmziY11S4biX9cfuLVnQmLr8r7ALbJukxD4tRSY
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.00347
Expected counter: 623930
Gas limit: 31666
Storage limit: 0 bytes
Balance updates:
tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHm ............. -ꜩ0.00347
fees(tz1Ke2h7sDdakHJQh8WX4Z372du1KChsksyU,154) ... +ꜩ0.00347
Transaction:
Amount: ꜩ0
From: tz1bDCu64RmcpWahdn9bWrDMi6cu7mXZynHm
To: KT1LVLUsC1WCo4yHzeoDEE8FxxoC7EW6bSyp
Parameter: (Left (Pair Unit "KT1ShW17HERZgjUTxSxSc4W3tuWrfLCqBmEi"))
This transaction was successfully applied
Updated storage:
(Pair 3 0x00003b5d4596c032347b72fb51f688c45200d0cb50db)
Storage size: 426 bytes
Consumed gas: 20242
Internal operations:
Transaction:
Amount: ꜩ0
From: KT1LVLUsC1WCo4yHzeoDEE8FxxoC7EW6bSyp
To: KT1ShW17HERZgjUTxSxSc4W3tuWrfLCqBmEi
Parameter: 3
This transaction was successfully applied
Updated storage: 3
Storage size: 38 bytes
Consumed gas: 11324

Зміна значення

Створення параметра

❯❯❯ lorentz-contract-oracle Oracle update-value --help
Usage: lorentz-contract-oracle Oracle update-value --newValueType Michelson Type
--newValue Michelson Value
update value
Available options:
-h,--help Show this help text
--newValueType Michelson Type
The Michelson Type of newValue
--newValue Michelson Value
The Michelson Value: newValue
-h,--help Show this help text

Зміна значення

Щоб змінити значення на 4:
Waiting for the node to be bootstrapped before injection...
Current head: BMLjQ5pgcmxd (timestamp: 2020-04-03T15:35:39-00:00, validation: 2020-04-03T15:35:44-00:00)
Node is bootstrapped, ready for injecting operations.
Estimated gas: 19463 units (will add 100 for safety)
Estimated storage: no bytes added
Operation successfully injected in the node.
Operation hash is 'ooEf7sgpvhMcUBcn66iMLaWNzs4TEAxb4icjXKF27xM2QPMTGQP'
NOT waiting for the operation to be included.
Use command
tezos-client wait for ooEf7sgpvhMcUBcn66iMLaWNzs4TEAxb4icjXKF27xM2QPMTGQP to be included --confirmations 30 --branch BMLjQ5pgcmxdN11kfhA2NS4igfSdJeL5HbopDn8LyAckBroWZhi
and/or an external block explorer to make sure that it has been included.
This sequence of operations was run:
Manager signed operations:
From: tz1R3vJ5TV8Y5pVj8dicBR23Zv8JArusDkYr
Fee to the baker: ꜩ0.001259
Expected counter: 632294
Gas limit: 10000
Storage limit: 0 bytes
Balance updates:
tz1R3vJ5TV8Y5pVj8dicBR23Zv8JArusDkYr ............. -ꜩ0.001259
fees(tz1Ke2h7sDdakHJQh8WX4Z372du1KChsksyU,154) ... +ꜩ0.001259
Revelation of manager public key:
Contract: tz1R3vJ5TV8Y5pVj8dicBR23Zv8JArusDkYr
Key: edpkvCHgVArnZo9RTP4P6euLTyhE89u73CYjBgsP4wEJbj4quao9oR
This revelation was successfully applied
Consumed gas: 10000
Manager signed operations:
From: tz1R3vJ5TV8Y5pVj8dicBR23Zv8JArusDkYr
Fee to the baker: ꜩ0.002123
Expected counter: 632295
Gas limit: 19563
Storage limit: 0 bytes
Balance updates:
tz1R3vJ5TV8Y5pVj8dicBR23Zv8JArusDkYr ............. -ꜩ0.002123
fees(tz1Ke2h7sDdakHJQh8WX4Z372du1KChsksyU,154) ... +ꜩ0.002123
Transaction:
Amount: ꜩ0
From: tz1R3vJ5TV8Y5pVj8dicBR23Zv8JArusDkYr
To: KT1LVLUsC1WCo4yHzeoDEE8FxxoC7EW6bSyp
Parameter: (Right (Left 4))
This transaction was successfully applied
Updated storage:
(Pair 4 0x00003b5d4596c032347b72fb51f688c45200d0cb50db)
Storage size: 426 bytes
Consumed gas: 19463

Налаштування сервера

Хоча у нас є все необхідне для створення і адміністрування контракту оракула, ми хотіли б автоматично відправляти овлення в контракт.
Нижче наведені два простих приклади того, як ви можете періодично отримувати деякі дані і автоматично передавати їх в контракт оракула.

Мінімальний сервер на Bash

Мінімальний сервер, написаний на Bash, може складатися з:
  • Bash скрипта update_value.sh який отримує NEW_VALUE і викликає точку входу
    update-value:
##!/bin/bash
## update_value.sh
NEW_VALUE="$(my_get_new_value_script)
tezos-client --wait none transfer 0 from $ALICE_ADDRESS to $ORACLE_ADDRESS \
--arg "$(lorentz-contract-oracle Oracle update-value \
--newValueType "nat" --newValue $NEW_VALUE)" --burn-cap 0.000001
  • crontab налаштування update_value.sh що періодично запускається
    (в прикладі: щоденно в 5:03 pm):
03 05 * * * update_value.sh

Сервер Docker Flask

Існує реалізація зазначеного вище сервера Bash на Python, упакована як образ Docker, яка:
  • Отримує останню інформацію про ціни на акції від Alpha Vantage
  • Запускає "завдання cron", щоб відправити оновлення в контракт оракула з pytezos кожні 30 секунд
  • Обслуговує веб-сторінку для налагодження
Він робить те ж саме, що і скрипт Bash, де my_get_new_value_script витягує останню ціну з Alpha Vantage.
Ви можете знайти проект на Github тут або переглянути однофайловий код Python тут.
Щоб отримати зображення зі сховищ DockerHub, запустіть:
❯❯❯ docker pull tqtezos/oracle-stock-ticker:2.1
Сервер налаштовується за використанням змінних середовища:
  • щоб згенерувати TEZOS_USER_KEY, виконайте: echo "$(base64 MY_KEY_FILE.json | tr -d '\n')",
    де MY_KEY_FILE.json це ваш файл Tezos виделки (див. тут, щоб отримати файл).
  • Ви можете отримати безкоштовний ALPHA_VANTAGE_API_KEY від Alpha Vantage
  • Search Endpoint від Alpha Vantage можна використовувати, щоб знайти значенняALPHA_VANTAGE_TICKER_SYMBOL
TEZOS_USER_KEY=".."
ORACLE_ADDRESS="KT1CUTjTqf4UMf6c9A8ZA4e1ntWbLVTnvrKG"
ALPHA_VANTAGE_API_KEY=".."
ALPHA_VANTAGE_TICKER_SYMBOL="AAPL"
FLASK_APP="tq/oracles/ticker.py"
Щоб запустити контейнер Docker:
❯❯❯ docker run -d -p 5000:5000 \
--env TEZOS_USER_KEY=".."
--env ORACLE_ADDRESS="KT1.." \
--env ALPHA_VANTAGE_API_KEY=".." \
--env ALPHA_VANTAGE_TICKER_SYMBOL="AAPL" \
--env FLASK_APP="tq/oracles/ticker.py" \
oracle-stock-ticker
Як тільки він буде запущений, він буде обслуговувати сторінку налагодження і оновлювати контракт оракула приблизно кожні 30 секунд.
Тепер ви повинні мати можливість переглядати екран налагодження за адресою localhost:5000, отримувати останні значення за допомогою get-value і використовувати провідник блоків для перевірки контракту.
Ви можете знайти діючий приклад контракту на Carthage.
Матеріали розроблені TQ Tezos перекладені українською мовою Tezos Ukraine
Copy link
Outline
Вступ
Встановлення
CLI
Створення контракту
Друк контракту
Початкове зберігання
Запуск старту контракту
Отримання значення
Підготовка до перегляду контракту
Створення параметра
Отримання значення
Зміна значення
Створення параметра
Зміна значення
Налаштування сервера
Мінімальний сервер на Bash
Сервер Docker Flask