Автор: Павел Найданов 🕵️♂️
Оракул — это сервис(или устройство), который предоставляет набор данных для использования в блокчейн. После размещения данных в сети, они становятся доступны для использования на смарт-контрактах.
По сути, оракулы являются мостом между двумя мирами. Между миром децентрализованным и централизованным. Между смарт-контрактом и сторонним поставщиком данных. Основная задача оракулов - это предоставление надежной информации для смарт-контрактов.
Блокчейн Ethereum спроектирован так, чтобы быть полностью детерминированным. Это означает, что если кто-то загрузит историю сети и будет ее воспроизводить, то сеть всегда будет проигрывать одно и тоже состояние. Детерминизм необходим для того, чтобы узлы блокчейна могли прийти к консенсусу. Для реализации механизма консенсуса сеть является закрытой и не может получать информацию извне.
Таким образом оракулы должны решать следующую проблему - безопасное получение off-chain данных для смарт-контрактов в сети. Важно отметить, что это не должно противоречить основам децентрализации сети.
Подробнее тут.
Можно выделить несколько ключевых предметных областей, где используются оракулы:
- Финансы. Всем продуктам сферы финансов требуются надежные потоки данных для выполнения операций в сети.
- Страхование. Оракулы служат для проверки наступления страховых случаев.
- Грузоперевозки. Например, отслеживание GPS данных.
- Кредитование и стейблкоины. Продуктам этой сферы нужен доступ к информации о стоимости залога для принятия решения о ликвидации.
- Прогнозы. Оракулы служат для расчетов вне сети. Так как для совершения прогноза необходимо обработать огромное количество информации и делать это on-chain дорого.
Подробнее про варианты использования и не только можно и даже нужно прочитать в хорошей статье Julien Thevenard "Decentralized Oracles: a comprehensive overview"
Для реализации прослойки между off-chain и on-chain оракул является составным и обычно включает в себя две части: смарт-контракт и сервис вне сети.
Полный шаблон реализации оракула состоит из четырех основных компонентов:
- Client SC. Смарт-контракт, которому необходимы off-chain данные
- Oracle SC. Смарт-контракт, который будет агрегировать в себе off-chain данные в сети
- Data Source. Поставщик off-chain данных
- Oracle node. Программное решение, которое является вспомогательным связующим звеном между Data Source и on-chain пространством
Общий процесс работы оракула можно описать следующим алгоритмом:
- Исходный смарт-контракт(Client SC) запрашивает набор off-chain данных у смарт-контракта оракула(Oracle SC).
- Оракул(Oracle SC) бросает событие за пределы блокчейна. Событие будет обозначать необходимость получения данных.
- Промежуточное решение нода(Oracle node) постоянно слушает события от Oracle SC и отлавливает событие о необходимости поставки off-chain данных.
- Нода(Oracle node) получает данные из источника данных(Data source) и обновляет данные на смарт-контракте оракула(Oracle SC)
- Обновление данных на смарт-контракте оракула(Oracle SC) автоматически проводит обратный вызов для исходного смарт-контракта(Client SC)
Таким образом мы можем получить off-chain данные, которые будут являться частью сети. За запись таких данных будет отвечать специальный смарт-контракт оракул(Oracle SC). Пример реализации смарт-контракта оракула(Oracle SC) можно посмотреть тут. Пример использования такого оракула в контракте Client SC тут.
Однако, не все так просто! Подумай, какую опасность ты здесь видишь? Что может стать узким местом? Конечно, oracle node. Согласно схеме, в случае непредвиденного отказа oracle node смарт-контракт оракула(Oracle SC) никогда не сможет получить данные, записать их в сеть и передать исходному смарт-контракту(Client SC). Это значит, что запрос на данные останется без ответа. Решить эту проблему можно добавив несколько oracle nodes, которые смогут подстраховать друг друга. Смотри схему ниже.
Теперь мы можем добавить логику на контракте оракула(Oracle SC) и обрабатывать ответ от любого из доверенных узлов оракула(oracle node). Как говорится, кто первый пришлет нам данные, тот молодец. Но на сколько спокойнее тебе стало теперь? Насколько мы можем доверять первому ответившему узлу(Oracle node)? Что если один из узлов(Oracle node) будет присылать данные из неверного источника, как на схеме ниже.
Это можно решить добавив дополнительную логику для контракта оракула(Oracle SC). Сделаем так, чтобы контракт оракула(Oracle SC) ждал ответы от всех узлов(Oracle node). И например, аппроксимировал данные, выбирая среднее или наиболее часто встречающееся значение.
Важно! Такой подход позволяет использовать даже несколько источников данных с целью децентрализации самого источника данных(Data Source).
Однако можно снова возмутиться. Допустим источник данных(Data source) мы децентрализуем, а как же сами узлы оракула(oracle nodes)? Как сделать так, чтобы им можно было доверять на 100%? Ответ на этот вопрос есть. Мы можем сделать децентрализованную сеть оракулов. Название такой сети DON(decentralized oracle networks). Подробнее про DON тут на примере Chainlink.
Важно! Оракулы сами по себе являются потенциально уязвимым местом. Только совокупность мер безопасности может минимизировать риск взлома оракула. Несколько Data Source, сеть oracle nodes, изоляция oracle nodes друг от друга, шифрование передаваемых данных и многие другие приемы и подходы необходимо использовать, чтобы снизить риск злонамеренных действий в отношении оракула.
Важно! Не стоит забывать про операционные расходы на обратный вызов функций смарт-контракта оракул(Oracle SC). Кто-то должен будет покрывать операционные расходы работы оракула.
Можно придумать несколько способов по которым возможно сгруппировать оракулы. Ниже покажу основные подходы.
Всех оракулов можно разделить на две группы по уровню безопасности:
- Централизованные. Часто такими оракулами владеют в рамках одной компании и одного продукта. С таким решением мы доверяем данным, которые будут поставлены таким оракулом.
- Децентрализованные. Используется DON или сеть децентрализованных оракулов.
Также можно разделить оракулов по способу взаимодействия off-chain и on-chain составляющих:
- Immediate read oracles. Оракул всегда владеет актуальной информацией. Информация обновляется с заданной периодичностью. Можно моментально прочитать данные с такого оракула.
- Publish-subscribe oracles. В основе такого оракула лежит паттерн Observer. По сути это механизм подписки. Можно подписаться на данные из оракула и получать данные на момент их обновления в самом оракуле.
- Request-response oracles. Оракул основан на системе запрос-ответ.
По виду работы с данными:
- Input oracles. Такой оракул извлекает off-chain данные и записывает их в сеть для использования на смарт-контрактах. Например, такой оракул может поставлять информацию о стоимости валют в сеть.
- Output oracles. Позволяет отправлять от имени смарт-контрактов команды автономным системам. Эти команды могут запускать определенные действия. Например, информирование банковского сервиса о совершение платежа.
- Cross-chain oracles. Такие оракулы могут считывать и записывать информацию между разными блокчейнами. Например, можно реализовать задачу межсетевого учета объема определенных активов.
- Compute-enabled oracles. Такие оракулы служат для выполнения вычислительной работы вне сети из-за технических, юридических или финансовых ограничений. Например, генерация случайного числа.
Можно ли доверять off-chain данным? Насколько эти данные целостные и всегда доступны? На эти вопросы необходимо ответить прежде чем начать использовать существующий оракул.
При разработке необходимо решить основную проблему, которая заключается в том, что делать, если оракул скомпрометирован. Ведь в таком случае смарт-контракт, на который он опирается, также будет скомпрометирован. Это часто называют главной проблемой Oracle. Нужно любыми доступными способами не допустить подобной ситуации. Хороший опыт собрала компания Chainlink в реализации безопасных и надежных оракулов.
Примеры некоторых популярных уязвимостей можно посмотреть тут.
Как я сказал выше, использование одного оракула — это огромный риск. Со своей стороны chainlink предлагает сеть децентрализованных оракулов, которые образуют фантастическую экосистему для получения данных из-за пределов сети. Сегодня это наиболее широко распространенное решение среди оракулов.
В настоящее время существует большое количество price feeds, которые работают в ряде сетей блокчейнов(Ethereum, Polygon, BSC, Avalanche и т.д.). По мимо price feeds chainlink предоставляет не только децентрализованные потоки данных, но и широкий спектр безопасных сервисов вычислений вне сети. Например, VRF(генерация случайного числа), Keepers(автоматизация) и другие различные формы вычислений вне сети.
Оракулы chainlink могут быть разделены на две группы:
- Проверенные на безопасность командой chainlink с публичными идентификаторами.
- Непроверенные на безопасность. Могут управляться, как известными, так и неизвестными организациями.
Важно! Чтобы стимулировать оракулов вести себя добросовестно в сети разработана специальная система репутации. Система репутации обеспечивает дополнительную безопасность за счет подотчетности действий оракулов. Оракулы с низким рейтингом могут быть удалены из сети.
Внешние адаптеры — это службы, с которыми Chainlink взаимодействует через свой API с применением простой спецификации JSON.
Взаимодействовать с внешними адаптерами можно прямо из solidity кода и не только.
Для взаимодействия из solidity кода необходимо воспользоваться контрактом ChainlinkClient. Наследоваться и использовать функции buildChainlinkRequest()
и sendChainlinkRequest()
function requestPrice(string coin, string market) public returns (bytes32 requestId) {
Chainlink.Request memory req = buildChainlinkRequest(SPEC_ID, this, this.fulfill.selector);
req.add("endpoint", "mwa-historic");
req.add("coin", coin);
req.add("market", market);
req.add("copyPath", "data.-1.1");
req.addInt("times", 100);
requestId = sendChainlinkRequest(req, oraclePayment);
}
Подробнее про внешние адаптеры можно почитать тут.
Базовая модель запроса раскрывает секрет модели взаимодействия с внешними адаптерами, с которыми я познакомил тебя выше.
Согласно схеме от Chainlink базовая модель очень похожа на общие схемы устройства оракулов. Про общую схему я также говорил выше. Отличительной чертой является участие в модели собственного токена Link.
Расшифровать схему можно следующим образом:
- Контракт ChainlinkClient. На контракте инициируется transfer Link токена согласно стандарту ERC-1363(это стандарт про transferAndCall).
- Контракт Oracle. Принимает токены и реализует интерфейс transferAndCall. Согласно интерфейсу вызывает собственную функцию
oracleRequest()
. Эта функция бросает событиеOracleRequest
за пределы блокчейна. Это событие будет отслежено на oracle node. - Oracle node. Проводит вычисление или запрос к данным и вызывает функцию
fulfillOracleRequest()
на контракте Oracle - Контракт Oracle. Делает обратный вызов
callback()
и поставляет запрашиваемые данные контракту ChainlinkClient.
Подробнее про этот процесс можно прочитать в официальной документации chainlink.
Важно! C версии chainlink 0.7 контракт Oracle заменен на контракт Operator и является рекомендованным. Контракт ChainlinkClient в новой версии поддерживает запросы и к Oracle, и к Operator. Для этого реализованы функции sendChainlinkRequest()
и sendOperatorRequest()
.
Преимущества контракта Operator перед Oracle:
- Отменено ограничение размера ответов от oracle node. Раньше ответ был ограничен bytes32.
- Деплой. Чтобы развернуть контракт Oracle для каждого узла необходимо было вручную скомпилировать и задеплоить контракт в сеть. Поэтому для контракта Operator добавили контракт OperatorFactory.
- Гибкая система финансирования своих адресов. Можно использовать несколько EOA аккаунтов на chainlink nodes. Это позволяет настраивать несколько стратегий отправки обратных транзакций.
-
ChainlinkClient. Это родительский контракт, который позволяет смарт-контрактам получать данные от оракулов. Он доступен в библиотеке смарт-контрактов Chainlink. Понадобится наследоваться от этого контракта, чтобы безопасно сделать запрос на получение данных к контракту Oracle или Operator.
-
LINK Token. Это токен, совместимый с ERC-677 для реализации
transferAndCall
механизма. Имеет три основных функции: оплата за работу для chainlink nodes, механизм вознаграждения для оракулов, форма безопасности, когда оракулы оставляют Link токен в качестве залога(гарантия честной работы). -
Oracle Contract. Контракт, который служит мостом для oracle node в мир блокчейн. Принимает запрос от ChainlinkClient контракта и транслирует его для oracle node. После получения данных от oracle node делает вызов клиентского смарт-контракта и доставляет до него данные.
-
Operator Contract. Новая версия контракта Oracle. В основном аналогичен контракту Oracle c небольшими улучшениями.
-
AggregatorV3Interface. Интерфейс при помощи которого можно взаимодействовать с контрактом, который агрегирует данные. Пример использования контракта Aggregator для получения стоимости токена можно посмотреть тут.
Это шаблон оракула, который повышает децентрализацию и масштабируемость сети chainlink. Строится на основе базовой модели запроса(Basic Request Model). Базовая модель позволяет поставить данные из одного chainlink node в сеть. В свою очередь OCR использует несколько chainlink nodes, позволяя им связываться напрямую через одноранговую сеть(P2P) с последующей агрегацией данных вне сети без каких-либо затрат.
Во время реализации процесса получения данных из chainlink nodes запускается облегченный алгоритм консенсуса, который следит за поставкой данных и проверяет подпись каждого узла. Среди всех chainlink nodes выбирается лидирующий узел, который будет управлять протоколом и собирать данные со всех остальных узлов. В конце LEADER сделает одну результирующую транзакцию с агрегированными данными.
Подробнее тут.
Управление chainlink node позволит тебе стать частью сети и поможет создавать гибридные смарт-контракты, предоставляя им доступ к реальным off-chain данным.
Хороший гайд по работе с chainlink node. Ты сможешь развернуть chainlink node локально, развернуть контракт Operator в тестовой сети, сделать первый запрос на локально развернутый узел и получить от него ответ.
Благодаря собственным возможностям сети chainlink предоставляет широкий спектр услуг оракула для смарт-контрактов:
- Price feeds. Источник данных финансового рынка. Включает в себя курсы криптовалют, стейблкоинов, товаров и индексов.
- Любой APY. Позволят интегрировать смарт-контракты с любым API или источником данных вне сети. Например для получения данных о погоде. Подробнее тут.
- Randomness. Verifiable Random Function(VRF) предоставляет безопасную возможность смарт-контрактам интегрировать генерацию случайного числа, которым невозможно манипулировать ни оракулу, ни разработчикам, ни конечным пользовтаелям.
- Asset Collateralization PoR или доказательство резерва позволяет смарт-контрактам проверять информацию о текущем обеспечение активов в сети.
- Chainlink function. Functions предоставляет смарт-контрактам доступ к вычислительной инфраструктуре с минимальным доверием.
- Keepers. Keepers позволяет автоматизировать внутрисетевые транзакции на основе заранее определенных условий.
- Валидаторы 2-го уровня. Могут предоставить услуги проверки для решений масштабирования блокчейнов 2-го уровня. Например Arbitrum Rollups, который включает в себя вычисления вне сети, путем создания пакетов транзакций.
- Межсетевая коммуникация. Могут передавать данные из одной среды блокчейн в другую.
- Witnet. Witnet это децентрализованный оракул для связи смарт-контрактов с реальным миром. Работает на собственной цепочке блоков и полагается на собственный токен WIT.
- UMA Oracle. UMA - оптимистичный оракул, который позволяет смарт-контрактам быстро получать любые данные. Имеет свою собственную систему разрешения споров и механизма проверки данных.
- Tellor - это прозрачный и не требующий разрешений протокол оракула для вашего смарт-контракта, позволяющий легко получать любые данные, когда это необходимо.
- Band Protocol. Это кроссчейн-платформа оракула данных, которая объединяет и связывает реальные данные и API со смарт-контрактами
- Provable. Это протокол, который соединяет децентрализованные приложения блокчейна с любым внешним API и использует доказательства TLSNotary, Trusted Execution Environments (TEE) и безопасные криптографические примитивы, чтобы гарантировать подлинность данных.
- Pyth network. Это оракул, который реализует неклассическую модель поставки данных в каждую сеть. Модель называется "On-Demand Updates". Обновление по запросу. Это подразумевает возможность обновлять данные в сети любым пользователям.
- Paralink. Paralink предоставляет децентрализованную платформу оракула с открытым исходным кодом для смарт-контрактов, работающих на Ethereum и других популярных блокчейнах.
Рейтинг оракулов можно посмотреть на coinmarketcap. При выборе оракула глубоко изучи функциональные возможности сервиса. Но советую обратить внимание на Volume и Market Cap параметры в рейтинге оракулов. Это должно тебя подтолкнуть сделать правильный выбор в пользу Chainlink.
- Compound use chainlink
- Средневзвешенные цены от Uniswap. Подробнее про это можно найти в нашей отдельной небольшой статье
- Oracle module
Если тебе все еще недостаточно примеров, то можно найти больше 77+ вариантов использования тут.
- Oracles
- Сборник шаблонов и лучших практик для языка программирования смарт-контрактов Solidity
- Implementing a Blockchain Oracle on Ethereum
- Smart Contract Security Guidelines #3: The Dangers of Price Oracles. Я бы не сказал, что эта статья про безопасность. Здесь ставятся требования к оракулу и разбираются общие принципы популярных вариантов оракулов.
- Completing The God Protocols: A Comprehensive Overview of Chainlink in 2021. Это большая статья, ее можно прочитать всю, но здесь неплохо рассказано про оракулы от chainlnk.