On-chain оракул цен · ценовые фиды реальных активов
Оракул цен для смарт-контрактов: валюты, золото, индексы и акции on-chain
Получите подписанный ценовой отчёт из нашего API и передайте его в контракт. Наш контракт-верификатор проверяет подпись on-chain, поэтому ваш контракт может доверять цене, не доверяя посреднику.
Как это работает
- Получите подписанный отчёт:
GET /oracle/reportс вашим ключом API. - Отправьте его в своей транзакции: наш контракт-верификатор проверяет подпись через
ecrecover. - Используйте проверенную цену; отклоните её, если она слишком старая для вашей задачи.
Отчёты — это типизированные данные EIP-712 PriceReport(bytes32 feedId,int256 price,uint64 timestamp,uint64 validUntil,uint8 marketStatus,uint32 spreadBps), привязанные к одной сети и одному контракту-верификатору (без повторного использования в другом месте) и принимаемые только до validUntil, примерно через минуту после подписи (выгодные отчёты нельзя копить). Цены — середина между bid и ask с 8 знаками после запятой; spreadBps — спред bid-ask. Когда вы отправляете отчёт в собственной транзакции, вы платите за этот газ. Востребованные фиды также время от времени сохраняются on-chain нашим релейером (чтение бесплатно), но всегда проверяйте возраст сохранённой цены.
Торговые часы
Каждый отчёт указывает статус рынка: OPEN (живая цена не старше 60 секунд), CLOSED (официальная последняя цена перед закрытием, одинаковая для всех, подписывается в любой момент, пока рынок закрыт) или HALTED (торги остановлены). getPriceNoOlderThan возвращает только цены OPEN, поэтому цена закрытия никогда не сойдёт за живую. Токены, обеспеченные активами, должны исполнять ордера, поданные при закрытом рынке, по следующей цене OPEN (форвардное ценообразование, как у фондов и ETF).
Стоп-механизм
Для каждого фида можно задать максимально допустимый скачок. Более сильное движение не сохраняется: фид приостанавливается, пока мы не проверим и не откроем его снова, поэтому неверная или манипулятивная цена никогда не попадёт в ваш контракт.
Фиды
| Символ | feedId |
|---|---|
| AUDUSD | 0x5577fa17b1be8ae0f1517fe1864ea534d6992f3721000cdb6585b11e7046d5ec |
| EURGBP | 0xeaff3420d70d388655273db9b4f3000962445a6f0ea23ec1f04d843e4dbae4b0 |
| EURUSD | 0x0730076c3c0f5da594eb635c5d5a22116233bdb2a9c2977279cc348b8b8ce917 |
| GBPUSD | 0xd30842147b60fe333c2700bcae5eee6815b8529847955d19522858806bca8217 |
| IEF | 0x309dab183458dd939568dca0d68bea45d34aa25d31fa47fc5f12030e8f227f4e |
| OILCash# | 0xe21b90a237aa0663c02092eca221a0098c6c477054a61d05ecd3692f6631f6ff |
| SHY | 0x78f1083af8e72ddefc2e66fad95680c38a953b3136f413c61ab40f99b72991bc |
| SPY | 0xcea23e8f56b5ac447ac08d57e0808e35f468a65f29bb659b3d48934481e7c67a |
| TLT | 0x4abd434857e07567d49487ccf888348e55d5cfc15498c09a9dbcba2820e40ee4 |
| USDCAD | 0xa36f6cf3195abb4e93bf276660acee423f78878e6cfdbad0eab36e455afca97e |
| USDCHF | 0xd85af9ebd6fec6b317a7ac07f6d6455c4fc915cc8e1cfe19471faca002582907 |
| USDJPY | 0x3d6c40e9d821c10e442cb3fc6cb1c589ffd8b906e734a1ab3b3f7d213ac395d6 |
| USDSGD | 0x8a1375bd16e33aff9be7037f83e076defe9df6efea6d39a51d0b08f17ac9bc6d |
| XAGUSD | 0x67107df7f0e95594d9bf8ad8840bbb2ff95617123c227e10aab4d161dd6959b6 |
| XAUUSD | 0xe21c86d8b6a127bfef214d88fdb0c279e55d27dd8c443733e46c8d3de3c98cd6 |
Сети
| Сеть | ID сети | Контракт-верификатор |
|---|---|---|
| Optimism | 10 | 0xaeF7f701acFB42267015D3F593ce17CF536Afd6B |
| Optimism Sepolia тестнет | 11155420 | 0xBBf36E7Cd75494f28E02C5698EaD35fF4960a943 |
Адрес подписанта: 0x83fa2d8836525251FAd214A78A72038D0864f877. Машиночитаемый список: /oracle/feeds.
Интеграция
1. Получите подписанный отчёт
curl -H "Authorization: Bearer $API_KEY" \
"https://api.marketapi.app/v1/oracle/report?symbols=EURUSD&chain_id=10"
Возвращает report (ABI-кодированный кортеж) и signature (65 байт) для каждого символа. Ключу нужна область read:oracle.
2. Проверьте его в своём контракте
interface IMarketApiOracle {
struct PriceReport { bytes32 feedId; int256 price; uint64 timestamp; uint64 validUntil;
uint8 marketStatus; uint32 spreadBps; }
function submit(PriceReport calldata r, bytes calldata sig) external returns (bool); // verifies, stores if newer
function getPriceNoOlderThan(bytes32 feedId, uint256 maxAge)
external view returns (int256 price, uint64 timestamp); // OPEN and fresh only, else reverts
function getPrice(bytes32 feedId) external view
returns (int256 price, uint64 timestamp, uint8 marketStatus, uint32 spreadBps); // incl. CLOSED
}
contract MyVault {
IMarketApiOracle immutable oracle;
bytes32 constant EURUSD = keccak256("EURUSD");
constructor(IMarketApiOracle o) { oracle = o; }
function act(IMarketApiOracle.PriceReport calldata r, bytes calldata sig) external {
oracle.submit(r, sig); // reverts on a bad signature
(int256 price, ) = oracle.getPriceNoOlderThan(EURUSD, 60); // 8 decimals
// ... use price ...
}
}
Потребители в стиле Chainlink могут читать фид через MarketApiFeedAdapter (latestRoundData(), AggregatorV3Interface).
Цены
кредитов за подписанный отчёт: 5, списываются с обычного баланса API. Чтение цен, уже сохранённых on-chain, бесплатно.
Сценарии использования наших on-chain ценовых фидов
- Токенизированные активы и RWA: оценивайте токенизированные акции, токены, обеспеченные золотом, и другие реальные активы по ценовым данным с учётом торговых часов.
- DeFi-кредитование и залоги: оценивайте залоги, обеспеченные валютой и сырьём, по свежим проверяемым ценам с безопасной для ликвидаций проверкой актуальности.
- Синтетические активы и on-chain FX: рассчитывайте синтетические позиции по валютам, индексам и сырью по подписанным справочным ценам.
- Стейблкоины и платежи: конвертируйте валюты on-chain по живым курсам EUR/USD, GBP/USD и другим.
Почему подписанный pull-оракул?
Push-оракулы обновляются по расписанию, и кто-то платит газ за каждое обновление. С pull-оракулом ваш контракт получает свежую криптографически подписанную цену ровно тогда, когда она нужна: ниже затраты, свежее данные и та же on-chain проверка. Статус рынка, спред bid-ask и срок действия входят в каждый подписанный отчёт.
Вопросы об оракуле цен
Что такое блокчейн-оракул цен?
Оракул цен доставляет внесетевые рыночные цены в смарт-контракты. Наш оракул подписывает каждую цену подписью EIP-712; ваш контракт проверяет её on-chain через ecrecover перед использованием, поэтому цену нельзя подделать в пути.
Какие активы охватывают ценовые фиды?
Валютные пары, например EUR/USD, драгоценные металлы, например золото (XAU/USD) и серебро, фондовые индексы и отдельные акции — согласно списку фидов на этой странице. У каждого фида фиксированный feedId (keccak256 от символа).
Подходит ли он для RWA и токенизированных активов?
Да. Отчёты содержат статус рынка (открыт, закрыт, торги остановлены), поэтому токенизированные акции, сырьё и другие реальные активы могут применять форвардное ценообразование вне торговых часов, а не торговаться по устаревшей цене.
Совместим ли оракул с Chainlink?
Каждый фид можно читать через адаптер, реализующий Chainlink AggregatorV3Interface (latestRoundData), поэтому существующий DeFi-код, читающий ценовые фиды в стиле Chainlink, работает с минимальными изменениями.
Как предотвращается манипуляция?
Отчёты истекают примерно через минуту и должны быть новее сохранённой цены, стоп-механизм для каждого фида приостанавливает его после аномального скачка, а при нескольких брокерах цена — это медиана независимых источников без выбросов.
Кто платит за газ?
Это pull-оракул: ваше приложение отправляет подписанный отчёт в собственной транзакции и платит за этот газ. Наш релейер также время от времени сохраняет востребованные фиды on-chain; чтение сохранённых цен бесплатно, но перед использованием проверяйте их возраст.
Какие блокчейны поддерживаются?
Любая EVM-сеть, где развёрнут контракт-верификатор, например Ethereum, Base, Arbitrum, Optimism, BNB Smart Chain и Polygon и их тестнеты; актуальный список приведён выше.
Рекомендуется: pull-схема (всегда свежие цены)
Не полагайтесь на цену, уже сохранённую on-chain. Получите свежеподписанный отчёт и отправьте его в той же транзакции, которая его использует: ваш контракт всегда видит текущую цену, а вы платите только за свои обновления.
// 1) off-chain: GET https://api.marketapi.app/v1/oracle/report?symbols=EURUSD&chain_id=CHAIN_ID (header: Authorization: Bearer KEY)
// 2) on-chain: verify, store and use the report atomically
interface IMarketApiOracle {
struct PriceReport { bytes32 feedId; int256 price; uint64 timestamp; uint64 validUntil; uint8 marketStatus; uint32 spreadBps; }
function submit(PriceReport calldata r, bytes calldata sig) external returns (bool);
function getPriceNoOlderThan(bytes32 feedId, uint256 maxAge) external view returns (int256 price, uint64 timestamp);
}
contract MyVault {
IMarketApiOracle immutable oracle;
bytes32 constant EURUSD = keccak256("EURUSD");
constructor(IMarketApiOracle o) { oracle = o; }
function settle(IMarketApiOracle.PriceReport calldata r, bytes calldata sig) external {
oracle.submit(r, sig); // ignored if an equal/newer price is stored
(int256 price, ) = oracle.getPriceNoOlderThan(EURUSD, 60); // reverts unless OPEN and fresh
// ... use price (8 decimals)
}
}
Поля report и signature отчёта из API — это ровно два аргумента submit. Отчёты действуют около минуты, поэтому получайте их прямо перед отправкой транзакции.
Предупреждение о рисках. Цены — это индикативные рыночные данные из нашего источника, а не площадка исполнения. Смарт-контракты, перемещающие средства на основе любого оракула, должны проверять актуальность, обрабатывать пропущенные обновления и ограничивать влияние неверной цены. Прочтите условия, прежде чем полагаться на оракул в продакшене.