Автоматическое исполнение приходит в мир смарт-контрактов

В прошлом месяце я посетил Саммит смарт-контрактов №1 (который до сих пор был для меня величайшим событием года!), Где много обсуждались Хранители цепей, новое решение, предоставленное Chainlink.

Согласно их веб-сайту, «Chainlink Keepers позволяет интеллектуальным контрактам автоматизировать ключевые функции и задачи, управляемые событиями, высоконадежным, децентрализованным и экономичным способом».

Вкратце, процесс работает следующим образом: вы создаете смарт-контракт, совместимый с хранителем, регистрируете задание по обслуживанию в веб-приложении Chainlink Keepers, затем Chainlink Keepers выполняют ваши задания по обслуживанию через указанные интервалы без какого-либо дополнительного участия с вашей стороны. В этой статье мы рассмотрим, как создать смарт-контракт, совместимый с хранителем, и зарегистрировать задание на содержание, и как все это работает за кулисами.

Использование держателей звеньев цепи

Итак, как мы можем обеспечить совместимость с нашим хранителем контрактов? Первый шаг - импортировать KeeperCompatibleInterface из Chainlink в наш контракт. Я предполагаю, что у вас уже настроена среда разработки и вы знаете, как импортировать пакеты (если не просто проверить одно из учебных пособий по Solidity для начинающих).

// SPDX-License-Identifier: MIT
pragma solidity ^0.6.7;

import "@chainlink/contracts/src/v0.6/interfaces/KeeperCompatibleInterface.sol";

Этот интерфейс имеет две функции: checkUpkeep и performUpkeep. Первый будет отвечать за проверку того, есть ли в контракте какие-либо работы, которые необходимо выполнить. Требуется параметр bytes с именем checkData, который будет передан вашему контракту, и поскольку вы устанавливаете это значение только один раз, при регистрации вашего обслуживания, здесь всегда будет передаваться одно и то же значение. Вы можете использовать это значение в своей логике, чтобы определить, нуждается ли ваш контракт в содержании или нет. Он возвращает bool, называемый upkeepNeed, который определяет, будет ли performUpkeep вызываться или нет, и bytes, который будет передан в performUpkeep.

function checkUpkeep(
    bytes calldata checkData
  )
    external
    returns (
        bool upkeepNeeded,
        bytes memory performData
    );

Далее у нас есть performUpkeep. Если мы получили true для upkeepNeeded из предыдущей функции, узел-хранитель теперь вызовет эту функцию в нашем контракте за нас. Он принимает параметр bytes из предыдущей функции. Здесь вы хотели бы реализовать изменения состояния в своем контракте. Хороший совет из документации Chainlink относительно этой функции: performUpkeep должен изменить состояние, чтобы при повторном вызове checkUpkeep он не возвращал true для уже завершенной работы.

function performUpkeep(
    bytes calldata performData
  ) external;

Написание совместимого смарт-контракта

Теперь, когда мы изучили интерфейс, который нам нужно реализовать, давайте создадим пример контракта. Этот простой контракт будет отвечать за автоматические платежи по указанным адресам. В реальной жизни это может быть трудовой договор, по которому работнику автоматически выплачивается заработная плата при соблюдении заранее определенных и согласованных условий. Примером такого условия является то, что указанный объем работы был завершен, что, в свою очередь, также можно проверить с помощью оракулов Chainlink. Другой пример - договор о государственной субсидии, по которому субсидия автоматически выплачивается бенефициару.

Однако важно отметить, что это всего лишь простой контракт, демонстрирующий работу Chainlink Keepers. Реальный производственный контракт потребует гораздо больше работы, включая проверки безопасности и гарантии.

Давайте рассмотрим логику контракта. Как видите, я начинаю с импорта KeeperCompatibleInterface в контракт.

Небольшое примечание: если вы используете Remix, а не свою локальную среду, вы можете импортировать интерфейс следующим образом:

import "https://github.com/smartcontractkit/chainlink/blob/master/contracts/src/v0.6/interfaces/KeeperCompatibleInterface.sol";

Общая логика контракта проста:

  • После развертывания владелец может установить интервал между выплатами субсидии и размер субсидии, выплачиваемой при каждом исполнении.
  • Если кто-то хочет быть бенефициаром, он / она должен зарегистрироваться, и его / ее адрес указывается в качестве ожидающего бенефициара. (Если уже есть ожидающий бенефициар, никто другой не сможет зарегистрироваться.)
  • Запрос бенефициара должен быть одобрен владельцем контракта.
  • Если он будет одобрен, checkUpkeep вернет истину по истечении указанного интервала, а performUpkeep обработает перевод субсидии.

У нас есть несколько значений и модификаторов, которые, как мне кажется, вместе с комментариями говорят сами за себя. У нас есть функция для проверки текущего баланса контракта и вывода денег, если мы являемся собственниками.

У нас есть функции для управления получателем (регистрация и утверждение), а также функция depositSubsidy, которая будет вызываться владельцем для перевода денег, подлежащих выплате получателю.

В функции checkUpkeep мы проверяем, установлен ли beneficiary и прошел ли уже указанный интервал с момента установки lastTimeStamp. В этом примере мы не используем свойство checkData, но мы могли бы передать туда значение из нашего приложения Keepers и провести с ним некоторую проверку.

В нашей performUpkeep функции мы обновляем lastTimeStamp и проверяем, достаточно ли в нашем контракте денег для продолжения платежа. Если это так, стоимость переводится на адрес получателя.

Регистрация в приложении Chainlink Keepers

Как только у нас будет готов к работе наш красивый маленький контракт, мы можем развернуть его и перейти в Приложение Keepers, чтобы зарегистрировать нашу работу.

Сначала войдите в приложение с помощью MetaMask, затем нажмите «Зарегистрировать новое обслуживание». Это работает следующим образом: вы указываете здесь набор данных, связанных с вашей задачей, например:

  • адрес вашего контракта, совместимого с хранителем
  • адрес администратора (для отмены работы и вывода средств)
  • Максимальный объем газа, предоставляемый по контракту
  • checkData для функции checkUpkeep (должно быть в шестнадцатеричном формате)
  • начальный LINK баланс Поддержки

Попробуйте добавить, например, 200 000 для лимита газа и 50 LINK для начального баланса. Вы всегда можете изменить это позже, когда увидите, сколько съедает работа.

Когда вы закончите, ваша служба поддержки должна быть развернута и готова автоматически выполнять работу от вашего имени. Думаю, это довольно здорово, не правда ли?

Как это работает за кулисами

Хранители - это в основном узлы Chainlink, которые вызывают функции вашего смарт-контракта от вашего имени. Они не конкурируют друг с другом, скорее, они по очереди выполняют обслуживание.

Все операции по обслуживанию делятся на сегменты в зависимости от количества узлов. Эти ведра передаются между узлами на каждом ходу, поэтому, если узел выходит из строя, ведро просто переходит к следующему хранителю в очереди, а обслуживание все еще выполняется.

Обслуживание не может быть выполнено дважды узлом. Он может выполнить его только после того, как хотя бы один другой узел выполнил это обслуживание. Это отличная функция безопасности сети, защищающая от злоумышленников.

Заключение

Спасибо, что оставались со мной до конца, надеюсь, вам понравилось это короткое руководство так же, как и мне. Мне не терпится увидеть, какие интересные сценарии использования наша экосистема найдет для этой замечательной технологии.

Если вы любите блокчейн и смарт-контракты, вам могут быть интересны некоторые из моих статей:







Присоединяйтесь к Coinmonks Telegram Channel и узнайте о криптовалютной торговле и инвестировании

Также прочтите