> 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/vi/phat-trien/nang-cao/nguon-gia-on-chain/thuc-hanh-tot-nhat.md).

# Thực hành tốt nhất

## Luôn Xác Thực Trước Khi Sử Dụng Giá

`latestRoundData()` revert với `NoDataAvailable()` nếu không có round nào tồn tại, nhưng không thực thi kiểm tra staleness hoặc tạm dừng — nó trả về các giá trị đã lưu trữ như nguyên bản. Trước khi sử dụng bất kỳ giá trị giá nào, luôn thực hiện ba kiểm tra sau:

1. **Kiểm tra tạm dừng**: gọi `paused()` và từ chối nếu nguồn giá bị tạm dừng.
2. **Giá trị dương**: yêu cầu `answer > 0`.
3. **Kiểm tra staleness**: kiểm soát bằng `getHealthStatus().isHealthy`.

Ví dụ `getSafePrice()` trong [Đọc Giá](/vi/phat-trien/nang-cao/nguon-gia-on-chain/doc-gia.md) triển khai cả ba.

## API Trạng Thái Sức Khỏe

Mỗi `PriceFeed` cung cấp một view `getHealthStatus()` tổng hợp thông tin về độ tươi mới trong một lần gọi:

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

| Trường                | Mô tả                                                                                 |
| --------------------- | ------------------------------------------------------------------------------------- |
| `lastUpdateTimestamp` | `updatedAt` của round gần nhất                                                        |
| `totalRounds`         | Tổng số round đã ghi                                                                  |
| `timeSinceLastUpdate` | `block.timestamp - lastUpdateTimestamp` (hoặc `block.timestamp` nếu không có dữ liệu) |
| `isHealthy`           | `true` nếu `timeSinceLastUpdate <= updateInterval × healthFactor`                     |

Health factor được khởi tạo là `2` theo mặc định nhưng có thể cấu hình theo từng nguồn giá bởi quản trị viên oracle qua `setHealthFactor()`. Không hardcode `2` — đọc trực tiếp từ hợp đồng:

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

Cửa sổ sức khỏe là `updateInterval × healthFactor`, cả hai được cấu hình theo từng nguồn giá — `updateInterval` là khoảng cách tối thiểu on-chain nhỏ, không phải heartbeat. Nó thay đổi theo từng nguồn giá: CHZ/USDC sử dụng cửa sổ `5s × 720 = 1 giờ`, PEPPER/CHZ sử dụng cửa sổ `10s × 720 = 2 giờ`, trong khi pipeline off-chain đẩy theo heartbeat khoảng 1 giờ. Đừng bao giờ dùng `updateInterval` một mình làm cơ sở staleness — kiểm soát bằng `isHealthy` — xem `getSafePrice()` trong [Đọc Giá](/vi/phat-trien/nang-cao/nguon-gia-on-chain/doc-gia.md) để biết mẫu đầy đủ.

Sử dụng `getAllOracleHealthStatus()` trên `OracleFactoryReader` để theo dõi mọi nguồn giá trong hệ thống cùng một lúc — hữu ích cho dashboard và cảnh báo off-chain.

## Cache `decimals()`

Mỗi cặp có độ chính xác thập phân riêng — luôn gọi `decimals()` để xác nhận trước khi diễn giải giá trị giá. Decimals được thiết lập khi triển khai và không bao giờ thay đổi, vì vậy hãy đọc chúng một lần khi khởi tạo hợp đồng thay vì mỗi lần đọc giá:

```solidity
uint8 public immutable feedDecimals;

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

## Xử Lý Trạng Thái Tạm Dừng Một Cách Thanh Lịch

Trong trường hợp khẩn cấp, quản lý oracle có thể tạm dừng một nguồn giá. Xử lý revert kết quả một cách rõ ràng thay vì âm thầm sử dụng giá trị xấu:

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

## Sử Dụng Tracker Trong Quá Trình Phát Triển

[Price Oracle Tracker](https://price-oracle-tracker.vercel.app/?network=mainnet) cho phép bạn so sánh giá on-chain với CoinMarketCap và CoinGecko theo thời gian thực, giúp dễ dàng xác thực độ chính xác của nguồn giá trong quá trình tích hợp. Nó cũng hiển thị trạng thái sức khỏe trực tiếp, thông số heartbeat, và địa chỉ hợp đồng riêng lẻ cho mọi cặp.

## Danh Sách Kiểm Tra Tích Hợp

* [ ] Lấy địa chỉ `PriceFeed` qua tracker, `pairToOracle()`, hoặc `getActiveOracles()`
* [ ] Xác nhận mô tả cặp và decimals bằng `description()` và `decimals()`
* [ ] Cache `decimals()` khi khởi tạo hợp đồng
* [ ] Đọc giá qua `latestRoundData()` (revert với `NoDataAvailable()` nếu chưa có round nào)
* [ ] Kiểm tra `paused()` trước khi sử dụng giá
* [ ] Xác thực `answer > 0`
* [ ] Kiểm soát bằng `getHealthStatus().isHealthy` cho staleness (không tự tính ngưỡng từ `updateInterval` một mình)
* [ ] Chuẩn hóa giá về độ chính xác nội bộ của bạn (ví dụ: 18 decimals) nếu cần
* [ ] Kiểm tra trên Spicy Testnet trước khi triển khai lên Mainnet


---

# 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/vi/phat-trien/nang-cao/nguon-gia-on-chain/thuc-hanh-tot-nhat.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.
