Оракулы Chainlink и Pyth: какой протокол выбрать для DeFi
Когда вы интегрируете оракул в DeFi-протокол, первая цифра, которую замечаете в документации, часто касается платы. Pyth Pro: 1 wei за проверку обновления в EVM. Pyth Core: ноль. Chainlink Data Feeds: ноль за чтение.

На этом сравнение можно закончить, если задача состоит в том, чтобы сравнить только стоимость вызова. Но нулевая плата за проверку не означает нулевую стоимость владения: остаются сетевой gas, задержка обновления, свежесть данных и последствия неверной цены. Реальный счёт формируется не одной строкой в документации, а тем, как протокол получает цену и решает, можно ли ей доверять.
Оракулы Chainlink и Pyth для DeFi устроены по-разному, и путаница между моделями потребления обходится дороже, чем разница в комиссии. Chainlink Data Feeds хранят цену on-chain, чтобы контракт мог прочитать её при вызове. Pyth предлагает два подхода: Pyth Core тоже сохраняет цену в сети, а Pyth Pro передаёт подписанные данные для проверки в конкретной транзакции. Выбирать стоит от сценария: цене для расчёта обеспечения в кредитном рынке и цене для исполнения сделки на перпетуальном DEX предъявляют разные требования.
Как Chainlink Data Feeds и Pyth передают цену в смарт-контракт
Chainlink Data Feeds обновляются, когда цена достигает установленного порога отклонения, либо по heartbeat-интервалу. Конкретные значения зависят от feed и доступны в каталоге Chainlink. Контракт обычно читает данные через latestRoundData(). Среди возвращаемых полей есть updatedAt, позволяющее проверить время последнего обновления. Это важно: успешное чтение значения ещё не говорит, насколько оно свежее для конкретной операции.
Data Feed не представляет собой непрерывный поток, который меняется при каждом движении рынка. Это on-chain хранилище агрегированной цены, обновляемое по заданным правилам. Протокол обращается к нему по мере необходимости и сам решает, принимать ли полученное значение. Например, цена может быть пригодна для отображения интерфейсу, но слишком старой для ликвидации позиции с небольшим запасом обеспечения.
У Pyth Core другая последовательность: подписанное обновление отправляется в сеть, проверяется и сохраняется on-chain. После этого контракты могут читать хранимую цену. Для проверки возраста документация показывает getPriceNoOlderThan, где интегратор задаёт допустимую давность. В примере интеграции Pyth EVM используется предел в 60 секунд. Это пример настройки, а не универсальная рекомендация для всех рынков, активов и сетей.
Pyth Pro работает с подписанными данными, переданными в конкретную транзакцию. Обновление проверяется в ходе вызова и не сохраняется как общее хранилище цены для последующих операций. Для интегратора это меняет не только способ чтения, но и ответственность за данные: нужно убедиться, что переданный пакет относится к нужному рынку и соответствует требованиям по времени публикации.
Условно Core можно представить как общую полку с ценой в сети, а Pro как подписанный пакет данных, приложенный к операции. В первом случае контракт читает уже сохранённое значение; во втором получает данные вместе с вызовом и проверяет их. Ни одна из моделей не снимает вопрос о давности. В частности, факт проверки подписанного обновления внутри транзакции сам по себе не доказывает, что цена была опубликована недавно.
Оракул становится частью модели риска протокола: цена влияет на то, кому разрешат занять, закрыть позицию или получить ликвидацию.
Порог обновления, heartbeat и допустимая давность
Свежесть цены нельзя определить одним правилом для всех оракулов и рынков. У Chainlink heartbeat и порог отклонения заданы отдельно для каждого feed. Порог отвечает за реакцию на изменение цены, heartbeat задаёт периодическое обновление, если порог не сработал. Конкретная комбинация зависит от актива и сети, поэтому проверять её нужно для того feed, который будет вызывать ваш контракт.
Поле updatedAt в latestRoundData() даёт on-chain время последнего обновления. Дальше начинается логика самого протокола: он сравнивает возраст данных с собственным допустимым пределом и выбирает действие при превышении. Для рынка с залогом это может означать отказ в открытии или изменении позиции, а для операции ликвидации требования могут быть иными. Важно определить поведение заранее. Если контракт продолжает использовать старую цену без проверки, наличие updatedAt в ответе само по себе ничего не защищает.
У Pyth Core предел давности задаётся вызывающим кодом через getPriceNoOlderThan. При превышении лимита вызов завершится ошибкой, вместо того чтобы молча вернуть цену, которая не соответствует заданному ограничению. Это полезная защита, но число в age limit становится частью риск-параметров протокола. Слишком широкий предел допускает устаревшие данные; слишком узкий может сделать операцию недоступной, если новое обновление не успело попасть в сеть.
В документации Pyth описаны и sponsored feeds, для которых обновления поступают без явного запроса приложения. Доступность и параметры зависят от сети и конкретного feed. Документация предупреждает, что такие обновления иногда задерживаются, поэтому их нельзя считать гарантированным потоком данных. Проекту всё равно нужно определить, что делать, если ожидаемой свежей цены нет.
У Pyth Pro есть отдельный нюанс. Переданная в транзакции цена не становится свежей только потому, что её подпись корректна и проверка прошла в рамках вызова. Проверяйте время публикации и сопоставляйте его с допустимым возрастом для операции. Между публикацией обновления и его использованием может пройти время; транзакция проверяет подпись и данные, но правило свежести должен обеспечивать код интеграции.
Практически полезно рассматривать свежесть как условие допуска к операции, а не как характеристику бренда оракула. Для каждой критичной функции протокола стоит определить предел возраста данных и поведение при его превышении. Это относится к займам, изменению залога, расчёту PnL и ликвидации, хотя сами пределы и последствия отказа у них могут различаться.
Pyth Core для кредитования и vaults, Pyth Pro для perps и RFQ
Документация Pyth приводит кредитные рынки, CDP и vaults как типичные сценарии для Core, а перпетуальные фьючерсы и RFQ-модели как сценарии для Pro. Это не готовый вердикт о пригодности для любого проекта. Разница объясняется прежде всего тем, каким образом приложение хочет получать цену и какое состояние данных ему удобнее поддерживать.
Кредитный протокол обычно рассчитывает стоимость залога и проверяет возможность ликвидации на основе цены, доступной контрактам в сети. Здесь может подойти хранимое значение Pyth Core или Chainlink Data Feed, если оно доступно в нужной сети и проходит требования протокола по свежести. Но хранение не означает, что цена автоматически обновляется к каждому обращению: интеграция должна учитывать возраст последнего обновления.
Для perps или RFQ цена может потребоваться непосредственно при исполнении конкретной операции. Pyth Pro позволяет передать подписанное обновление вместе с вызовом. Это подходящая модель для сценариев, где приложение само получает данные и предъявляет их контракту при выполнении операции. Однако такая схема требует корректно обрабатывать данные в каждой транзакции и отдельно проверять публикационное время. Слова «цена на момент сделки» описывают желаемую логику исполнения, но не гарантируют её без проверки возраста.
| Параметр | Pyth Core | Pyth Pro | Chainlink Data Feeds |
|---|---|---|---|
| Где доступна цена | On-chain после отправки обновления | В данных, переданных с транзакцией | В on-chain feed |
| Модель чтения | getPriceNoOlderThan или чтение сохранённой цены | Проверка подписанных данных в составе вызова | latestRoundData() и проверка updatedAt |
| Типичные сценарии из документации | Кредитование, CDP, vaults | Perps, RFQ | Зависит от сети и типа feed |
| Плата за проверку | 0 для EVM, Solana и Sui | 1 wei в EVM, 1 lamport в Solana | 0 за чтение, сетевой gas оплачивается отдельно |
| Контроль свежести | Интегратор задаёт предел возраста | Интегратор проверяет время публикации и допустимую давность | Интегратор сопоставляет updatedAt с лимитом |
У таблицы есть предел применимости: она сравнивает способы потребления цены, но не отвечает за доступность конкретного актива, задержки в целевой сети и устойчивость выбранного сценария. Даже правильная модель может оказаться неудобной, если нужного feed нет или его параметры не подходят протоколу.
Значение имеет и архитектура самого приложения. Если несколько функций читают общий on-chain источник, хранение цены может упростить вызовы. Если данные должны сопровождать каждую операцию, схема с обновлением в транзакции может лучше соответствовать потоку исполнения. Но во втором случае нельзя полагаться только на подпись: контракту нужны проверки идентификатора рынка, времени публикации и допустимости цены в данном действии.
Децентрализация и интерпретация confidence
Pyth публикует confidence-интервал вместе с ценой. Документация описывает его как отражение разброса цен издателей, то есть степени их согласия. В ней также рекомендуется учитывать число издателей и свежесть обновления: без этих контекстных данных само значение confidence трудно интерпретировать.
Confidence показывает разброс оценок издателей, а не волатильность рынка. Это разные сигналы, и подменять один другим рискованно.
Интегратор может использовать confidence как дополнительную проверку. Например, резкое расширение интервала относительно привычного поведения конкретного feed может стать поводом ограничить отдельные операции или перейти к дополнительной проверке. Но универсального порога, который подошёл бы всем активам и сценариям, из документации не следует. Любое правило должно учитывать свойства рынка и последствия отказа: фильтр, безопасный для одного актива, способен без необходимости остановить операции с другим.
Chainlink Data Feeds не дают confidence-интервал в том же виде. Контракт получает агрегированную цену и связанные с обновлением данные, включая updatedAt. Это не означает, что один подход автоматически надёжнее другого. Речь о разных интерфейсах и разных объёмах информации, которые интегратор может использовать в логике риска.
По документации можно понять, какие данные протокол публикует и как их читает контракт. Этого недостаточно, чтобы вывести универсальный рейтинг децентрализации или сравнить устойчивость двух моделей к манипуляции. Такие выводы потребовали бы сопоставимых данных об источниках, механизмах агрегации и работе в одинаковых условиях. Без них лучше не превращать описание архитектуры в обещание безопасности.
Интеграция в целевой сети: feed, decimals, комиссии и gas
Первый практический вопрос звучит просто: есть ли нужная пара в нужной сети? Общего списка, который позволял бы вывести покрытие всех сетей и активов сразу для обоих протоколов, нет. Наличие продукта в документации не подтверждает, что нужный feed доступен именно в сети, где будет работать контракт. Проверять нужно конкретные адреса, пары и условия использования.
Следом идут decimals. Для новых Chainlink Crypto/USD feeds типичны 8 знаков после запятой, а для Crypto/ETH feeds типичны 18. Значения могут различаться в зависимости от feed и сети, поэтому точность нужно получать через decimals() и корректно учитывать при нормализации цены. Разница между 8 и 18 знаками составляет десять десятичных порядков. Если применить точность Crypto/USD к Crypto/ETH, расчёт может получить неверный масштаб и привести к неправильному учёту залога, долга или цены позиции.
Точность нельзя свести к одному числу, которое однажды скопировали из примера. Контракту нужно знать, в каких единицах приходит значение, как оно приводится к внутреннему формату и как сочетается с точностью токена и расчётными величинами. Ошибка здесь способна пройти тесты на одном feed и проявиться после смены рынка. Поэтому получение decimals при деплое с проверкой или чтение параметра при обращении должны быть частью осознанной схемы, а не случайным хардкодом.
Плата за проверку Pyth Pro составляет 1 wei в EVM и 1 lamport в Solana; для Pyth Core она равна нулю в EVM, Solana и Sui. Эти значения не включают сетевой gas. Его стоимость зависит от сети и конкретного выполнения, а значит, итоговый расход нельзя оценить по одной комиссии оракула. В Chainlink чтение тоже не означает бесплатную транзакцию: вызов контракта расходует gas, хотя отдельной платы за чтение в таблице выше нет.
Поэтому сравнение цены интеграции лучше вести по полному пути операции: нужно учесть, кто передаёт обновление, когда оно появляется в сети, какие вызовы делает контракт и что происходит при отсутствии пригодных данных. Видимая цена проверки полезна как исходный параметр, но не заменяет расчёт стоимости сетевых операций и проектирование отказоустойчивого поведения. В этом смысле выбор провайдера напоминает сравнение предложений, где как выбрать надёжную компанию и избежать скрытых доплат сводится к изучению полного счёта, а не одной цены на витрине.
Наконец, параметры нужно проверять не в отрыве от кода. Для Chainlink это конкретный feed, его decimals, heartbeat, порог отклонения и время последнего обновления. Для Pyth Core это доступность пары, способ отправки обновления и заданный контрактом предел возраста. Для Pro к этому добавляется проверка времени публикации подписанных данных в транзакции. Для всех вариантов важны отдельный сетевой gas и поведение приложения, если цена оказалась слишком старой или недоступной.
Выбор зависит от модели риска
Оракулы Chainlink и Pyth для DeFi нельзя ранжировать по одной комиссии или одному слову в документации. Сначала определите, как контракт будет получать цену. Для общего on-chain значения можно рассматривать Chainlink Data Feeds и Pyth Core. Для передачи подписанных данных с конкретной операцией подходит модель Pyth Pro, если интеграция проверяет не только подпись, но и время публикации.
Затем сопоставьте модель с задачей протокола. Кредитование и vaults требуют чётко заданных правил для оценки залога и ликвидации. Perps и RFQ могут требовать данные в составе исполнения. Это не жёсткое разделение: на окончательное решение влияют конкретная сеть, доступность нужного актива, параметры feed и ваша логика при задержке.
Вопросы, которые определяют выбор, просты по формулировке, но требуют конкретных ответов в коде:
1. Есть ли нужный актив и feed в целевой сети?
2. Как контракт узнаёт возраст цены и что делает при превышении лимита?
3. Совпадают ли decimals фида с тем, что ожидают расчёты протокола?
4. Кто и каким способом доставляет обновление?
5. Какую сумму gas требует полный путь операции, включая обработку отказа?
Сопоставимых данных, которые позволяли бы безоговорочно объявить один протокол лучше другого по задержке, стоимости интеграции, устойчивости к манипуляциям и времени безотказной работы в одинаковых условиях, здесь нет. Поэтому ответ на вопрос, выбирать ли Chainlink или Pyth для ценовых данных, зависит от конкретной сети, feed и сценария. Маркетинговое описание не заменяет проверку свежести, точности и поведения контракта, когда нужной цены нет.