Быстрый старт с Oracle
Смарт-контракты, которые требуют внешних данных или событий в режиме реального времени, требуют доверенного oracle, то есть доверенного смарт-контракта, который предоставляет данные в цепочке.
Для чего это полезно?
- Оракул, который предоставляет цены XTZ / USD, может позволить пользователям вносить средства, которые немедленно конвертируются в какой-либо актив в цепочке и представляются как указание к действию.
- Оракул, который предоставляет данные о погоде, может позволить заключить договор страхования от цунами: пользователи покупают покрытие по контракту, которое выплачивается, когда в их районе появится достаточно сильное цунами
- Комбинация различных оракулов может использоваться для достижения консенсуса, например, где только результаты, опубликованные большинством оракулов, считаются действительными.
- Следуйте инструкциям в настройке клиента, чтобы установить
tezos-client
и создать тестовый сетевой кошелек - Клонируйте
lorentz-contract-oracle
репозиторий из GitHub и постройте билд из исходного кода, используяstack
.
❯❯❯ 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
Иначе:
❯❯❯ 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"
❯❯❯ 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 скрипта
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
Существует реализация указанного выше сервера Bash на Python, упакованная как образ Docker, которая:
- Получает последнюю информацию о ценах на акции от Alpha Vantage
- Обслуживает веб-страницу для отладки
Он делает то же самое, что и скрипт Bash, где
my_get_new_value_script
извлекает последнюю цену из Alpha Vantage.❯❯❯ docker pull tqtezos/oracle-stock-ticker:2.1
Сервер настраивается с использованием переменных среды:
- Чтобы сгенерировать
TEZOS_USER_KEY
, выполните:echo "$(base64 MY_KEY_FILE.json | tr -d '\n')"
, 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
и использовать проводник блоков для проверки контракта.