Для разработчиков / Реальные активы
Слой RWA
Этот слой - слой цен. 33 фида, 19 из них на реальные активы, публикуются внутри протокола и читаются одним вызовом. Эта страница о том, как получить список; следующая - о том, как прочитать цену.
Что существует
Документация на простом языке описывает три слоя. Ровно у одного из них есть код в этом репозитории, и эта справка описывает именно его.
| Слой | Состояние |
|---|---|
| A price, published in the protocol | built, and documented here33 feeds written by block production into a registry predeploy, with one Chainlink-shaped adapter per feed |
| Exposure to a priced asset | designed, not present in this repositorya margin system denominated by a feed, with crypto collateral and crypto settlement. There is no contract to call |
| A registry admitting third-party tokenised assets as collateral | designed, not present in this repositorywith risk parameters and haircuts. Pickle would admit such a token, not issue one |
Итак: есть цены, и есть контракты, которые их держат и отдают. Нет ни маржинального движка, ни реестра обеспечения, ни контракта позиции, который можно было бы вызвать. Когда они появятся, они будут описаны здесь как поверхности вызова, а не как намерения.
Цена, а не актив
A feed is the PRICE of a real-world asset. It is not the asset.
The chain publishes a number describing what something trades at somewhere else. It issues no tokenised share, holds no underlying instrument, offers no redemption and keeps no custody. Exposure measured against one of these prices is a claim on a margin system, not on an issuer, and this reference does not call it a tokenised asset. Nothing about a feed confers a shareholder right, and there is nothing to redeem.
Name it accordingly in your own interface. A contract reading XAU/USD is reading the price of gold; it is not holding gold, and a user who reads otherwise has been told something untrue.
Это утверждение о том, что делает сеть, а не оговорка, привинченная к нему сверху. Ничто в реестре не ссылается ни на эмитента, ни на хранителя, ни на резерв, потому что их нет: Pickle не выпускает ни одного реального актива и ни одного не держит. Фид с именем AAPL/USD - это число, описывающее, по какой цене эта акция торгуется на рынке в другом месте, опубликованное в этой сети, и ничего больше.
Получение списка активов
Три способа, и первый почти всегда правильный. Ему не нужны ни ABI, ни адрес, ни ключ.
| Способ | Вызов |
|---|---|
| Over JSON-RPC | pickle_pricesno params. Answers the whole registry: every feed with its symbol, feedId, adapter, decimals, class, policy, latest answer and age. One call, no ABI, no address |
| From a contract | feedCount() then feeds(offset, limit)on the price registry. limit is capped at 256; an offset past the end returns an empty array rather than reverting, so a reader can page blindly |
| From the source | oracle/catalog.jsonthe live feed set in the repository: what the oracle service prints and what l2-feeds-init (scripts/sync-feeds.sh) reconciles the registry to. The authority for what the chain should hold after a sync, not proof of what it holds now |
| The genesis input | oracle/catalog-genesis.jsonthe frozen copy the genesis allocation was generated from, and the authority for what the chain was born with. It is never edited on its own: a change to it is a genesis regeneration, a new chain |
# Every feed the chain carries, with its adapter, decimals, answer and age.
curl -s $RPC_URL \
-H 'content-type: application/json' \
-d '{"jsonrpc":"2.0","id":1,"method":"pickle_prices","params":[]}' \
| jq '.result.feeds[] | {symbol, feedId, adapter, decimals, price, statusName, staleOnchain}'
# The count alone, when you only want to know whether the catalog changed.
curl -s $RPC_URL \
-H 'content-type: application/json' \
-d '{"jsonrpc":"2.0","id":1,"method":"pickle_prices","params":[]}' \
| jq '.result.feeds | length'$RPC_URL - это адрес из параметров сети. Ответ несёт также blockNumber, timestamp, а ещё publisher и owner, которых называет реестр - читайте их, если хотите знать, кто мог написать то, что вы только что прочитали.
Набор генезиса ниже - тот, с которым сеть родилась. Фиды могут быть добавлены позже ролью владельца, поэтому клиент, зашивший список в код, их не увидит. Листайте реестр постранично или вызывайте pickle_prices и работайте с ответом.
33 фида
| Класс активов | Количество |
|---|---|
| crypto | 14 feedsclass 1. ETH, BTC, SOL, XRP, DOGE, LINK, ADA, XLM, BCH, TRX, BNB, HYPE, ZEC, XMR - all quoted in USD |
| equity | 9 feedsclass 2. AAPL, MSFT, NVDA, AMZN, GOOGL, META, TSLA, SPY, JPM |
| commodity | 2 feedsclass 3. XAU/USD and XAG/USD - gold and silver |
| fx | 5 feedsclass 4. EUR/USD, GBP/USD, USD/JPY, USD/CHF, USD/CNH |
| index | 3 feedsclass 5. PYTHOIL/USD, BRENT/USD, NATGAS/USD - energy indices, which trade around the clock |
19 из 33 - реальные активы. Разделение, которое имеет значение на практике, другое: 13 фидов опираются на спотовые площадки, а 20 приходят от одного только Pyth - и это все фиды реальных активов плюс XMR/USD, единственная крипто-пара без ноги площадки.
| Символ | Класс | Источники | Политика публикации | Рынок |
|---|---|---|---|---|
| ETH/USD | крипто | 5 площадок + Pyth | everyBlock | всегда открыт |
| BTC/USD | крипто | 5 площадок + Pyth | everyBlock | всегда открыт |
| SOL/USD | крипто | 5 площадок + Pyth | everyBlock | всегда открыт |
| XRP/USD | крипто | 5 площадок + Pyth | everyBlock | всегда открыт |
| DOGE/USD | крипто | 5 площадок + Pyth | everyBlock | всегда открыт |
| LINK/USD | крипто | 5 площадок + Pyth | everyBlock | всегда открыт |
| ADA/USD | крипто | 5 площадок + Pyth | 10 bps / 60 s | всегда открыт |
| XLM/USD | крипто | 5 площадок + Pyth | 10 bps / 60 s | всегда открыт |
| BCH/USD | крипто | 5 площадок + Pyth | 10 bps / 60 s | всегда открыт |
| TRX/USD | крипто | 5 площадок + Pyth | 10 bps / 60 s | всегда открыт |
| BNB/USD | крипто | 5 площадок + Pyth | everyBlock | всегда открыт |
| HYPE/USD | крипто | 5 площадок + Pyth | everyBlock | всегда открыт |
| ZEC/USD | крипто | 5 площадок + Pyth | 10 bps / 60 s | всегда открыт |
| XMR/USD | крипто | только Pyth | 10 bps / 60 s | всегда открыт |
| AAPL/USD | акции | только Pyth | everyBlock | часы NYSE |
| MSFT/USD | акции | только Pyth | 10 bps / 300 s | часы NYSE |
| NVDA/USD | акции | только Pyth | everyBlock | часы NYSE |
| AMZN/USD | акции | только Pyth | everyBlock | часы NYSE |
| GOOGL/USD | акции | только Pyth | 10 bps / 300 s | часы NYSE |
| META/USD | акции | только Pyth | everyBlock | часы NYSE |
| TSLA/USD | акции | только Pyth | everyBlock | часы NYSE |
| SPY/USD | акции | только Pyth | 10 bps / 300 s | часы NYSE |
| JPM/USD | акции | только Pyth | 10 bps / 300 s | часы NYSE |
| XAU/USD | сырьё | только Pyth | everyBlock | сессия с ежедневным перерывом |
| XAG/USD | сырьё | только Pyth | 5 bps / 300 s | сессия с ежедневным перерывом |
| PYTHOIL/USD | индекс | только Pyth | 10 bps / 300 s | всегда открыт |
| BRENT/USD | индекс | только Pyth | 10 bps / 300 s | всегда открыт |
| NATGAS/USD | индекс | только Pyth | 10 bps / 300 s | всегда открыт |
| EUR/USD | валюты | только Pyth | 2 bps / 300 s | валютная неделя |
| GBP/USD | валюты | только Pyth | 2 bps / 300 s | валютная неделя |
| USD/JPY | валюты | только Pyth | 2 bps / 300 s | валютная неделя |
| USD/CHF | валюты | только Pyth | 2 bps / 300 s | валютная неделя |
| USD/CNH | валюты | только Pyth | 2 bps / 300 s | сессия с ежедневным перерывом |
- 5 площадок + Pyth. five spot venues, with a Pyth feed alongside as a cross-check and a stand-in
- Только Pyth. Pyth only - no venue is listed for this feed, so an absent Pyth credential leaves it unpublished
Колонка Рынок: всегда открыт - open every day, all day; часы NYSE - 09:30-16:00 New York, Monday to Friday, with the exchange holiday list; валютная неделя - continuous Monday to Friday afternoon New York, closed Saturday, reopening Sunday evening; сессия с ежедневным перерывом - a nearly-continuous session with a daily break and a closed Saturday. Расписания - предмет часов работы рынков, и обрабатывать их не опционально.
Пять политик публикации, а не тридцать три
| Политика | Фиды |
|---|---|
| everyBlock, no step cap | ETH/USD, BTC/USD, SOL/USD, XRP/USD, DOGE/USD, LINK/USD, BNB/USD, HYPE/USDwritten on every EVM block the publisher can fill. No deviation trigger, no heartbeat, no step cap - the whole crypto class carries a step cap of 0 whether or not it is on this policy. Ring capacity 16,384 for ETH/USD and BTC/USD, 1,024 for the other six |
| everyBlock, with step cap | AAPL/USD, NVDA/USD, AMZN/USD, META/USD, TSLA/USD, XAU/USDthe six real-world feeds moved onto everyBlock still carry their class's step cap (2,000 bps for the equities, 1,000 bps for gold), so a move wider than that is skipped unless the market status changed in the same update. Ring capacity 1,024 |
| 10 bps / 60 s | the other 6 crypto feedsrepublished on a 10 bps move or after 60 s, whichever is first. No step cap. Ring capacity 1,024 |
| 10 bps / 300 s, step 2,000 bps | the 4 remaining equities and the 3 energy indicesa move wider than 20 % is skipped by the contract unless the market status changed in the same update |
| 5 bps / 300 s, step 1,000 bps | XAG/USDthe metal moves less, so the trigger is tighter and the implausible-move cap is 10 %. XAU/USD kept the same trigger shape until it moved to everyBlock |
| 2 bps / 300 s, step 500 bps | the 5 FX pairsthe tightest trigger in the set, and a 5 % cap - an FX pair that moves further in one update is not moving, it is wrong |
Потолок шага - строка, которую читают неверно чаще всего. Он равен 0, а значит отключён, на каждом крипто-фиде, и работает на каждом фиде реального актива - поэтому обновление реального актива, которое за один шаг уходит дальше потолка, контракт пропускает, а не записывает, если только в том же обновлении не изменился статус рынка. Именно это исключение и позволяет приземлиться разрыву выходных.
Что несёт запись фида
| Поле | Значение в наборе генезиса |
|---|---|
| symbol | BASE/QUOTE^[A-Z0-9.]+/[A-Z]+$, at most 32 bytes, unique. The contract enforces the same shape |
| description | free textthe Chainlink-style spaced form, "ETH / USD"; description() returns it and symbol() returns the canonical one |
| assetClass | crypto | equity | commodity | fx | indexstored as 1-5 |
| decimals | 8every feed in the catalog. The field allows 0-18, so read it rather than assuming |
| capacity | ring length in rounds16,384 for ETH/USD and BTC/USD, 1,024 for every other feed - including the twelve other feeds now on everyBlock. Rounds older than this are overwritten |
| policy | paused | everyBlock | deviationstored as 0, 1, 2. A paused feed is skipped rather than refused |
| deviationBps | 10, 5 or 2the move that triggers a republish. 0 on an everyBlock feed, which needs no trigger |
| heartbeatSecs | 60 or 300republish even without a move. 0 on an everyBlock feed |
| maxStepBps | 0, 500, 1,000 or 2,000the contract skips a move wider than this. 0 disables the check and is what every crypto feed carries; every real-world feed has it live. Bypassed whenever the status changed |
| minSources | 3 on an exchange-backed feed, 1 on a Pyth-only feedthe floor below which nothing is published |
| sources | { exchanges: {venue: productId}, pyth: id }the venue-native product id per venue, and the Pyth feed id without its 0x |
Те же поля составляют конфигурацию фида на цепочке, поэтому то, что вы читаете из pickle_prices или из feeds(offset, limit), - это данная запись плюс последний раунд. decimals сегодня равен 8 на каждом фиде, а поле допускает от 0 до 18: читайте его, а не предполагайте, потому что цена ошибки - цена, промахнувшаяся на восемь порядков величины.
Идентификаторы фидов
Фид индексируется хешем своего символа, а не индексом и не адресом:
bytes32 feedId = keccak256(bytes("ETH/USD"));The canonical symbol, upper case, with a single slash - keccak256("ETH/USD"), not "ETH-USD" and not "eth/usd". The same 32 bytes key the contract's mappings, name the feed on the RPC, and appear as the indexed topic of every FeedUpdated log. You can compute it offline with any keccak-256 implementation; nothing has to be fetched to know it.
The node and the service both accept ETH/USD, ETH-USD, eth-usd or 0x<64 hex feed id and normalise before looking up, so a URL-safe spelling costs nothing.
Разрешение адресов
Эта справка не печатает ни одного адреса контракта
Реестр и адаптеры на каждый фид - канонические предустановленные контракты, зафиксированные в генезисе на всю жизнь сети, - а это ровно тот случай, когда публиковать литерал хуже всего. EVM-вызов CALL к счёту без кода проходит: адрес с опечаткой не делает revert, он ничего не возвращает и читается как цена ноль. Поэтому этот сайт вместо адресов описывает механизм разрешения.
The price registry and one adapter per feed are predeploys: their addresses are fixed at genesis and canonical for the life of the chain. That is precisely why this reference resolves them instead of printing them.
- pickle_prices answers with the registry's address in core and each feed's adapter in feeds[].adapter, checksummed. That is the shortest path and it needs no ABI.
- pickle_price(feed) carries that feed's adapter; pickle_ethUsdPrice carries the adapter, the registry and, under contract, the adapter again, which is what a Chainlink reader should be pointed at.
- On chain, adapterOf(feedId) returns the deployed adapter and adapterAddress(feedId) recomputes it: the adapter is CREATE2 from the registry with salt = feedId, so its address is a pure function of the registry address and the symbol.
- The first-party applications resolve every address they use at runtime rather than compiling one in - shared-ui/config.js merges the deployment's address files into config.addresses at load.
- The explorer shows that address as an account, with its code and its activity, which is the human-readable cross-check that something is deployed there. It publishes no source and no ABI: the repository is not public yet, and the explorer verifies no contract.
# The registry and one feed's adapter, resolved from the chain itself.
curl -s $RPC_URL \
-H 'content-type: application/json' \
-d '{"jsonrpc":"2.0","id":1,"method":"pickle_price","params":["ETH-USD"]}' \
| jq '{adapter: .result.adapter, feedId: .result.feedId}'
# Then prove the address has code before you call it.
curl -s $RPC_URL \
-H 'content-type: application/json' \
-d '{"jsonrpc":"2.0","id":1,"method":"eth_getCode","params":["<adapter>","latest"]}'Verify a resolved address with an eth_getCode before your first call. A CALL to an account with no code succeeds and returns nothing, so a wrong address does not revert - it reads as a price of zero.