> For the complete documentation index, see [llms.txt](https://docs.chiliz.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.chiliz.com/ko/gaebal/goseup/on-chain-gaseukaemul-pidi/choeuseon-silmu.md).

# 모범 사례

## 가격 사용 전 항상 검증하기

`latestRoundData()`는 round가 존재하지 않을 경우 `NoDataAvailable()`로 revert하지만, 오래된 데이터나 일시 정지 여부는 확인하지 않으며 저장된 값을 그대로 반환합니다. 가격 값을 사용하기 전에 항상 다음 세 가지를 확인하세요:

1. **일시 정지 확인**: `paused()`를 호출하고 피드가 일시 정지된 경우 거부합니다.
2. **양수 확인**: `answer > 0`을 요구합니다.
3. **오래된 데이터 확인**: `getHealthStatus().isHealthy`를 기준으로 검증합니다.

[가격 읽기](/ko/gaebal/goseup/on-chain-gaseukaemul-pidi/gagyeok-ilggi.md)의 `getSafePrice()` 예제가 세 가지를 모두 구현합니다.

## Health Status API

각 `PriceFeed`는 단일 호출로 최신성 정보를 집계하는 `getHealthStatus()` 뷰를 제공합니다:

```solidity
function getHealthStatus()
    external view
    returns (
        uint256 lastUpdateTimestamp,
        uint256 totalRounds,
        uint256 timeSinceLastUpdate,
        bool isHealthy
    );
```

| 필드                    | 설명                                                                  |
| --------------------- | ------------------------------------------------------------------- |
| `lastUpdateTimestamp` | 가장 최근 round의 `updatedAt`                                            |
| `totalRounds`         | 기록된 총 round 수                                                       |
| `timeSinceLastUpdate` | `block.timestamp - lastUpdateTimestamp` (데이터 없으면 `block.timestamp`) |
| `isHealthy`           | `timeSinceLastUpdate <= updateInterval × healthFactor`이면 `true`     |

health factor는 기본값 `2`로 초기화되지만 오라클 관리자가 `setHealthFactor()`를 통해 피드별로 설정할 수 있습니다. `2`를 하드코딩하지 말고 컨트랙트에서 직접 읽으세요:

```solidity
uint80 factor = priceFeed.healthFactor(); // per-feed; do NOT assume the default of 2 (live feeds use 720)
```

health 윈도우는 `updateInterval × healthFactor`이며, 둘 다 피드별로 설정됩니다 — `updateInterval`은 작은 온체인 최소 간격이지, heartbeat가 아닙니다. 피드별로 다릅니다: CHZ/USDC는 `5s × 720 = 1시간` 윈도우, PEPPER/CHZ는 `10s × 720 = 2시간` 윈도우를 사용하며, 오프체인 파이프라인은 약 1시간 heartbeat로 게시합니다. `updateInterval`만으로 오래된 데이터 기준을 삼지 마세요 — `isHealthy`를 기준으로 하세요 — 전체 패턴은 [가격 읽기](/ko/gaebal/goseup/on-chain-gaseukaemul-pidi/gagyeok-ilggi.md)의 `getSafePrice()`를 참고하세요.

시스템의 모든 피드를 한 번에 모니터링하려면 `OracleFactoryReader`의 `getAllOracleHealthStatus()`를 사용하세요 — 오프체인 대시보드와 알림에 유용합니다.

## `decimals()` 캐싱

각 쌍은 고유한 소수점 정밀도를 가집니다 — 가격 값을 해석하기 전에 항상 `decimals()`를 호출하여 확인하세요. Decimals는 배포 시 설정되며 변경되지 않으므로, 매번 가격 조회 시마다 읽지 말고 컨트랙트 초기화 시 한 번만 읽으세요:

```solidity
uint8 public immutable feedDecimals;

constructor(address _feed) {
    priceFeed = IChilizPriceFeed(_feed);
    feedDecimals = priceFeed.decimals();
}
```

## 일시 정지 상태 올바르게 처리하기

긴급 상황에서 오라클 관리자는 피드를 일시 정지할 수 있습니다. 잘못된 값을 조용히 사용하지 말고 발생하는 revert를 깔끔하게 처리하세요:

```solidity
require(!priceFeed.paused(), "Feed paused");
```

## 개발 중 트래커 활용하기

[Price Oracle Tracker](https://price-oracle-tracker.vercel.app/?network=mainnet)를 사용하면 온체인 가격을 CoinMarketCap 및 CoinGecko와 실시간으로 비교하여 통합 중 피드 정확도를 쉽게 검증할 수 있습니다. 또한 모든 쌍의 실시간 상태, heartbeat 파라미터, 개별 컨트랙트 주소도 표시합니다.

## 통합 체크리스트

* [ ] 트래커, `pairToOracle()`, 또는 `getActiveOracles()`를 통해 `PriceFeed` 주소 확인
* [ ] `description()`과 `decimals()`로 쌍 설명 및 소수점 확인
* [ ] 컨트랙트 초기화 시 `decimals()` 캐싱
* [ ] `latestRoundData()`를 통해 가격 조회 (round가 아직 없으면 `NoDataAvailable()`로 revert)
* [ ] 가격 사용 전 `paused()` 확인
* [ ] `answer > 0` 검증
* [ ] 오래된 데이터 확인을 위해 `getHealthStatus().isHealthy` 기준으로 검증 (`updateInterval`만으로 자체 임계값 산출 금지)
* [ ] 필요한 경우 내부 정밀도로 가격 정규화(예: 18 decimals)
* [ ] Mainnet 배포 전 Spicy Testnet에서 테스트


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.chiliz.com/ko/gaebal/goseup/on-chain-gaseukaemul-pidi/choeuseon-silmu.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
