# WINkLink 價格服務
集成前請參考 開發者使用須知。
# 概覽
# WINkLink 價格服務介紹
為確保智能合約能反映真實世界的代幣價格,需經常對合約的價格信息進行更新。 其中,DeFi 資產的價格尤其需要和現實世界資產緊密掛鉤, 否則可能導致套利或合約攻擊,給用戶和開發者造成損失。
WINkLink 價格服務專註於數字貨幣價格對,為去中心化應用(DApp)提供準確穩定的外部世界數字貨幣價格信息。 WINkLink 打造了聚合多個預言機節點價格數據的解決方案,從而提供穩定的價格服務,稱作餵價合約(Price Feed Contract)。
上述合約稱為聚合器(Aggregator) —— 持有 WINkLink 預言機節點聚合價格數據的鏈上合約。每個價格餵價(如 BTC/USD)由一個聚合器合約實現,消費合約通過它讀取價格。
# 支持的價格對列表及配置
# 主網
# Nile 測試網
- WIN 代幣合約地址:
TNDSHKGBmgRx9mDYA9CnxPx55nu672yQw2 - WinkMid 合約地址:
TLDU7C8K3Gd3pXrAj9gtpVVNRHZHuHHZ8P
價格服務合約地址列表:
# 申請新價格對
如您想在 WINkLink 申請添加新價格對,請填寫並提交此表格。 (opens new window)
# 使用現有的 WINkLink 價格服務
# 獲取最新價格
以下示例演示如何通過 AggregatorV3Interface 讀取 WINkLink 餵價:使用 latestRoundData() 讀取最新價、按 heartbeat 校驗時效性、調用 decimals() 處理精度。
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
/**
* @title AggregatorV3Interface (WINkLink Price Feed)
* @notice Interface for reading WINkLink price feeds.
*/
interface AggregatorV3Interface {
function decimals() external view returns (uint8);
function description() external view returns (string memory);
function getRoundData(uint80 _roundId)
external view
returns (
uint80 roundId,
int256 answer,
uint256 startedAt,
uint256 updatedAt,
uint80 answeredInRound
);
function latestRoundData()
external view
returns (
uint80 roundId,
int256 answer,
uint256 startedAt,
uint256 updatedAt,
uint80 answeredInRound
);
}
/**
* THIS IS AN EXAMPLE CONTRACT THAT USES UN-AUDITED CODE.
* DO NOT USE THIS CODE IN PRODUCTION.
*/
contract PriceConsumer {
AggregatorV3Interface internal priceFeed;
uint256 public constant MAX_PRICE_AGE = 1 hours; // Adjust to your business tolerance
/**
* Network: TRON Mainnet / Nile Testnet
* Pass the feed address for the price pair you want to read.
* Find supported pairs and addresses in the Price Feed Service documentation.
*/
constructor(address feedAddress) {
priceFeed = AggregatorV3Interface(feedAddress);
}
/// @notice Returns the latest price together with its decimals.
/// @dev Reverts if the round is incomplete or the price is stale.
function getLatestPrice() public view returns (int256 answer, uint8 decimals) {
uint256 updatedAt;
(
/* uint80 roundId */,
answer,
/* uint256 startedAt */,
updatedAt,
/* uint80 answeredInRound */
) = priceFeed.latestRoundData();
require(updatedAt > 0, "Round not complete");
require(block.timestamp - updatedAt <= MAX_PRICE_AGE, "Price too stale");
decimals = priceFeed.decimals();
}
}
若你只需在鏈下讀取價格(如前端、後端或腳本),無需部署任何合約 —— 用 TronWeb 直接讀取代理:
// Off-chain read with TronWeb — no contract deployment required.
// npm install tronweb
const { TronWeb } = require('tronweb');
// Mainnet: https://api.trongrid.io | Nile testnet: https://nile.trongrid.io
// For production, use a free TronGrid API key to avoid rate limits:
// new TronWeb({ fullHost: 'https://api.trongrid.io', headers: { 'TRON-PRO-API-KEY': 'your-key' } })
const tronWeb = new TronWeb({ fullHost: 'https://api.trongrid.io' });
// A constant (read-only) call still needs a from-address set; any valid address works:
tronWeb.setAddress('T9yD14Nj9j7xAB4dbGeiX9h8unkKHxuWwb');
// Proxy address of the price pair you want to read (see Supported Price Pairs List).
const FEED_ADDRESS = 'TXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX';
async function getLatestPrice() {
const feed = await tronWeb.contract().at(FEED_ADDRESS);
const data = await feed.latestRoundData().call();
const decimals = await feed.decimals().call();
// Normalize the price as answer / 10 ** decimals
console.log('answer:', data.answer.toString());
console.log('updatedAt:', data.updatedAt.toString());
console.log('decimals:', decimals.toString());
}
getLatestPrice();
或用 tronpy(Python):
# Off-chain read with tronpy — no contract deployment required.
# pip install tronpy
from tronpy import Tron
# Mainnet: Tron() | Nile testnet: Tron(network='nile')
# For production, use a free TronGrid API key to avoid rate limits:
# from tronpy.providers import HTTPProvider
# client = Tron(HTTPProvider(api_key='your-key'))
client = Tron()
# Proxy address of the price pair you want to read (see Supported Price Pairs List).
FEED_ADDRESS = 'TXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
feed = client.get_contract(FEED_ADDRESS)
round_id, answer, started_at, updated_at, answered_in_round = feed.functions.latestRoundData()
decimals = feed.functions.decimals()
# Normalize the price as answer / 10 ** decimals
print('answer:', answer)
print('updatedAt:', updated_at)
print('decimals:', decimals)
# 獲取價格歷史
Round / RoundId —— 每次價格更新形成一個新的 Round(輪次),由唯一的 RoundId(uint80)標識。任意歷史輪次的價格可通過 getRoundData(roundId) 查詢。
以下代碼演示如何通過 getRoundData() 按 roundId 讀取歷史價。
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
/**
* DO NOT USE THIS CODE IN PRODUCTION.
*
* Continued from the AggregatorV3Interface defined above.
*/
contract HistoricalPriceConsumer {
AggregatorV3Interface internal priceFeed;
constructor(address feedAddress) {
priceFeed = AggregatorV3Interface(feedAddress);
}
/// @notice Returns the historical price for a specific roundId.
/// @param _roundId The round to query (must be a valid completed round).
function getHistoricalPrice(uint80 _roundId)
public view
returns (int256 answer, uint256 updatedAt)
{
(
/* uint80 roundId */,
answer,
/* uint256 startedAt */,
updatedAt,
/* uint80 answeredInRound */
) = priceFeed.getRoundData(_roundId);
require(updatedAt > 0, "Round not complete");
}
}
# 設置餵價合約
# 部署合約
WINkLink 生態採用去中心化架構,所有智能合約開源,任何組織和個人都可以部署自己的 WINkLink 預言機合約, 並對外公布所提供的服務。
用戶可以從各個公開 WINkLink 服務中選擇自己所需的組合,創建自己的聚合數據合約,享受去中心化機制帶來的便利。
項目合約可點此查看:https://github.com/tron-oracle/winklink-libocr/tree/main/tvm-contracts (opens new window) - 連接您的 Github 賬戶
您可以使用以下任一工具或程序庫進行合約部署和調用測試::
- TronScan: Mainnet (opens new window), Nile Testnet (opens new window)
- Official wallet-cli (opens new window)
- Tron IDE (opens new window)
- TronBox (opens new window)
- tronweb (opens new window)
# 聚合器合約
聚合器合約部署在波場 TRON 公鏈上,具有以下功能:
- 接受來自 WINkLink 節點的鏈下聚合傳輸
- 計算數據請求的 WIN 代幣費用,準許預言機節點領取獎勵;
- 實現 Owned 接口, 進而對聚合器合約暴露的不同方法提供權限控制。
合約代碼可於 AccessControlledOCRAggregator.sol 查看。
# 為節點添加任務
節點的任務代表其所支持的數據服務,每個任務都有一個 32 字節的唯一 ID。 對終端用戶而言, (預言機地址,任務 ID) 唯一標識了一個 WINkLink 節點提供的數據服務。 每個 WINkLink 節點都可以提供多項數據服務。
WINkLink 節點正常運行後,就可以通過 Operator UI 為節點添加任務:
示例:(將下列參數修改為上述步驟中部署的預言機合約地址)
TIP
如涉及引導節點,請在配置文件中設置 DefaultBootstrapPeers。
Example: DefaultBootstrapPeers = ['/ip4/127.0.0.1/tcp/6788/p2p/12D3KooWMrKGdnH6nBrf7hDz25NXFSFNk7vgsTxj9bHskWEct4xh']
# 引導節點
type = "offchainreporting"
schemaVersion = 1
tvmChainID = 1
name = "TUSD-TRX"
contractAddress = "ACCESS-CONTROLLED-OCR-AGGREGATOR-ADDRESS"
p2pBootstrapPeers = [
"/ip4/127.0.0.1/tcp/6788/p2p/P2P-PEER-ID",
]
isBootstrapPeer = true
keyBundleID = "NODE-KEY-BUNDLE"
forwardingAllowed = false
maxTaskDuration = "0s"
TIP
確保引導節點和預言機節點被配置為單獨的實體,每個實體鏈接到其唯一的數據庫實例。 在本地進行操作時,通過修改 config.toml 文件為每個實例指定不同的端口號,以便訪問每個實例各自的 Operator UI。
[WebServer]
HTTPPort = 3000
SecureCookies = false # Default
# 預言機節點
type = "offchainreporting"
schemaVersion = 1
tvmChainID = 2
name = "OCR: TUSD-TRX"
contractAddress = "ACCESS-CONTROLLED-OCR-AGGREGATOR-ADDRESS"
p2pBootstrapPeers = [
"/ip4/127.0.0.1/tcp/6788/p2p/P2P-PEER-ID",
]
isBootstrapPeer = false
keyBundleID = "NODE-KEY-BUNDLE"
transmitterAddress = "THE-CURRENT-NODE-EIP55-ADDRESS"
observationTimeout = "10s"
blockchainTimeout = "20s"
contractConfigTrackerSubscribeInterval = "2m"
contractConfigTrackerPollInterval = "1m"
contractConfigConfirmations = 3
observationSource = """
ds_http [type="http" method=GET url="https://www.okx.com/api/v5/market/index-tickers?instId=TUSD-USD"]
ds_parse [type="jsonparse" path="data,0,idxPx"]
ds_converttrx [type="converttrx" url="https://www.okx.com/api/v5/market/index-tickers?instId=TRX-USD" path="data.0.idxPx"]
ds_multiply [type="multiply" times=1000000]
ds_http -> ds_parse -> ds_converttrx -> ds_multiply
"""
# 查詢任務
開發者可以在 Operator UI 的任務選項卡下檢索任務。
子選項卡如下:
- 概覽:最近的運行任務和任務流列表
- 定義:任務規範
- 錯誤:自任務創建以來累計遇到的不同錯誤
- 運行:所有任務運行的列表

# API 參考
集成 WINkLink 價格餵價時,通過 AggregatorV3Interface 接口 + 代理(proxy)合約地址讀取餵價。如需獲取代理背後的聚合器信息,可調用 AccessControlledOffchainAggregator 合約中的變量與函數。
代理對外提供一個穩定地址,其底層聚合器可無縫升級而不影響你的集成。
# AggregatorV3Interface
在你的合約中導入本接口並指向代理地址使用(在上文「支持的價格對列表」中查詢可用價格對與代理地址)。示例:
/**
* Network: TRON Mainnet / Nile Testnet
* Pass the proxy address of the price pair you want to read.
*/
constructor(address feedAddress) {
priceFeed = AggregatorV3Interface(feedAddress);
}
使用示例見上文「獲取最新價格」段。
| 方法名 | 說明 |
|---|---|
| decimals | 響應值的小數位數 |
| description | 代理指向的聚合器描述 |
| getRoundData | 獲取指定輪次的數據 |
| latestRoundData | 獲取最新輪次的數據 |
| version | 代理指向的聚合器版本號 |
decimals
獲取響應值的小數位數。
function decimals() external view returns (uint8);
- 返回:小數位數
description
獲取代理指向的底層聚合器的描述。
function description() external view returns (string memory);
- 返回:底層聚合器的描述文本
getRoundData
按 roundId 獲取指定輪次的數據。
function getRoundData(
uint80 _roundId
) external view returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound);
參數:
_roundId:輪次 ID
返回:
roundId:輪次 IDanswer:本輪聚合後的價格startedAt:本輪起始時間戳updatedAt:本輪完成時間戳answeredInRound:已棄用 —— 此前用於答案需跨多輪計算的場景;在 WINkLink 餵價上恒等於roundId
latestRoundData
獲取最新輪次的數據。
function latestRoundData()
external
view
returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound);
返回:
roundId:輪次 IDanswer:本餵價為所配置價格對提供的聚合價格startedAt:本輪起始時間戳updatedAt:本輪完成時間戳;請結合該餵價的 heartbeat 校驗時效性answeredInRound:已棄用 —— 此前用於答案需跨多輪計算的場景;在 WINkLink 餵價上恒等於roundId
WINkLink OCR 餵價說明:每次上報都會把
startedAt與updatedAt寫為該次上報的區塊時間戳,兩者相同。代理會把 phase 編碼進roundId高位(phaseId << 64 | aggregatorRoundId),因此 roundId 並非從1連續遞增,且在底層聚合器升級時會跳號。調用getRoundData()時請傳入帶 phase 的roundId(例如latestRoundData()返回的那個)。
version
代理指向的聚合器版本號。
function version() external view returns (uint256);
- 返回:版本號。WINkLink 價格餵價當前返回
4。
# AccessControlledOffchainAggregator
這是聚合器(aggregator)合約本身。最佳實踐是通過 AggregatorV3Interface 代理調用,避免聚合器升級時影響你的應用。僅在需要代理未暴露的方法時才直接調用聚合器合約。
聚合器合約提供了若干對應用可能有用的變量與函數。各餵價的聚合器結構相似,但部分聚合器的變量有所不同。可調用聚合器的 typeAndVersion() 函數確認其類型與版本。
集成時請實地查看合約源碼與配置,了解具體餵價的運作方式。參考合約:TU5dpGzXAZwrpFfCrFzDBPWNxPm4diREqu (opens new window)(TronScan)。
本合約導入了 OffchainAggregator 與 SimpleReadAccessController(二者又各自有導入項)。下面的變量與函數列表包含這些被導入合約中可公開訪問的項。
讀取這些變量或函數的簡便方式:從區塊瀏覽器(TronScan)獲取 ABI,並將 ABI 指向聚合器地址。
變量:
| 名稱 | 說明 |
|---|---|
| checkEnabled | 布爾值,是否僅允許內部白名單地址訪問 |
| maxAnswer | 聚合器允許上報的價格上限;中位數高於此值的上報會被合約拒絕 |
| minAnswer | 聚合器允許上報的價格下限;中位數低於此值的上報會被合約拒絕 |
| owner | 聚合器合約的擁有者地址,決定哪些地址可執行特定函數 |
函數:
| 名稱 | 說明 |
|---|---|
| billingAccessController | billingAccessController 地址,限制聚合器 billing 配置的訪問權限 |
| decimals | 返回價格的精度位數(定點格式) |
| description | 返回本餵價的描述(因價格對而異) |
| getAnswer | 已棄用 —— 不要使用 |
| getBilling | 獲取當前 billing 配置 |
| getRoundData | 獲取指定輪次的完整信息(價格 + 時間戳) |
| getTimestamp | 已棄用 —— 不要使用 |
| getWinToken | 獲取支付預言機所用 WIN 代幣合約的地址 |
| hasAccess | 檢查地址是否有內部訪問權限 |
| latestAnswer | 返回最新價格(無時間戳,無法校驗時效性) |
| latestConfigDetails | 返回當前 OCR 協議配置信息 |
| latestRound | 已棄用 —— 不要使用 |
| latestRoundData | 獲取最新輪次的完整信息 |
| latestTimestamp | 已棄用 —— 不要使用 |
| latestTransmissionDetails | 獲取最新價格的詳細信息 |
| oracleObservationCount | 返回某預言機待結算的 observation 數量 |
| owedPayment | 返回某預言機因其 observation 應得的 WIN 數量 |
| requesterAccessController | 返回 requester 訪問控制合約地址 |
| transmitters | 可向本聚合器上報價格的預言機地址列表 |
| typeAndVersion | 返回聚合器類型與版本;此版本指聚合器類型版本,與合約 version 不同 |
| validatorConfig | 返回 validator 合約地址及其 gas 上限 |
| version | 返回合約版本號,與聚合器的 typeAndVersion 不同 |
| winAvailableForPayment | 返回本合約當前可用於支付預言機的 WIN 餘額;若存在未結清的支付義務,該值可能為負 |
billingAccessController
billingAccessController 地址,限制聚合器 billing 配置的訪問權限。
function billingAccessController() external view returns (AccessControllerInterface) {
return s_billingAccessController;
}
decimals
返回價格的精度位數。價格以定點格式存儲。
function decimals() external view returns (uint8 decimalPlaces);
description
返回本餵價的描述,價格餵價通常為資產對名稱。
function description() public view override checkAccess() returns (string memory) {
return super.description();
}
getAnswer
已棄用 —— 不要使用此函數,請改用
getRoundData()。
getBilling
獲取當前 billing 配置。在 TRON 上,前三個字段(maximumGasPrice、reasonableGasPrice、microWinPerTrx)未啟用,恒為 0。
function getBilling()
external
view
returns (
uint32 maximumGasPrice,
uint32 reasonableGasPrice,
uint32 microWinPerTrx,
uint32 winPerObservation,
uint32 winPerTransmission
)
{
Billing memory billing = s_billing;
return (
billing.maximumGasPrice,
billing.reasonableGasPrice,
billing.microWinPerTrx,
billing.winPerObservation,
billing.winPerTransmission
);
}
getRoundData
獲取指定輪次的完整信息(價格 + 時間戳)。用於讀取某一輪次的完整歷史數據。
function getRoundData(uint80 _roundId)
public
view
override
checkAccess()
returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound)
{
return super.getRoundData(_roundId);
}
getTimestamp
已棄用 —— 不要使用此函數,請改用
getRoundData()。
getWinToken
獲取支付預言機所用 WIN 代幣合約的地址。
function getWinToken() external view returns (WinTokenInterface winToken) {
return s_winToken;
}
hasAccess
檢查地址是否有內部訪問權限。
function hasAccess(address _user, bytes memory _calldata) public view virtual override returns (bool) {
return super.hasAccess(_user, _calldata) || _user == tx.origin;
}
latestAnswer
返回本餵價的最新價格。不含時間戳,無法校驗時效性;若尚無寫入則返回 0。latestRoundData 同時返回最新價格與時間戳,可用於校驗時效性。
latestConfigDetails
返回當前 OCR 協議配置信息。
function latestConfigDetails() external view returns (uint32 configCount, uint32 blockNumber, bytes16 configDigest) {
return (s_configCount, s_latestConfigBlockNumber, s_hotVars.latestConfigDigest);
}
latestRound
已棄用 —— 不要使用此函數,請改用
latestRoundData()。
latestRoundData
獲取最新輪次的完整信息(價格 + 時間戳)。
function latestRoundData()
public
view
override
checkAccess()
returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound)
{
return super.latestRoundData();
}
latestTimestamp
已棄用 —— 不要使用此函數,請改用
latestRoundData()。
latestTransmissionDetails
獲取最新價格的詳細信息。僅外部賬戶(EOA)可調用。
function latestTransmissionDetails()
external
view
returns (bytes16 configDigest, uint32 epoch, uint8 round, int256 latestAnswer, uint64 latestTimestamp)
{
require(msg.sender == tx.origin, "Only callable by EOA");
return (
s_hotVars.latestConfigDigest,
uint32(s_hotVars.latestEpochAndRound >> 8),
uint8(s_hotVars.latestEpochAndRound),
s_transmissions[s_hotVars.latestAggregatorRoundId].answer,
s_transmissions[s_hotVars.latestAggregatorRoundId].timestamp
);
}
oracleObservationCount
返回某預言機待結算的 observation 數量。
function oracleObservationCount(address _signerOrTransmitter) external view returns (uint16) {
Oracle memory oracle = s_oracles[_signerOrTransmitter];
if (oracle.role == Role.Unset) {
return 0;
}
return s_oracleObservationsCounts[oracle.index] - 1;
}
owedPayment
返回某預言機因其 observation 應得的 WIN 數量。
function owedPayment(address _transmitter) public view returns (uint256) {
Oracle memory oracle = s_oracles[_transmitter];
if (oracle.role == Role.Unset) {
return 0;
}
Billing memory billing = s_billing;
uint256 winAmount = uint256(s_oracleObservationsCounts[oracle.index] - 1) * uint256(billing.winPerObservation);
winAmount += s_gasReimbursementsWin[oracle.index] - 1;
return winAmount;
}
requesterAccessController
返回 requester 訪問控制合約地址。
function requesterAccessController() external view returns (AccessControllerInterface) {
return s_requesterAccessController;
}
transmitters
可向本聚合器上報價格的預言機地址列表。
function transmitters() external view returns (address[] memory) {
return s_transmitters;
}
typeAndVersion
返回聚合器類型與版本。此版本指聚合器類型版本,與合約 version 不同。
function typeAndVersion() external pure virtual override returns (string memory) {
return "AccessControlledOffchainAggregator 4.0.0";
}
validatorConfig
返回 validator 合約地址及其 gas 上限。
function validatorConfig() external view returns (AggregatorValidatorInterface validator, uint32 gasLimit) {
ValidatorConfig memory vc = s_validatorConfig;
return (vc.validator, vc.gasLimit);
}
version
返回合約版本號。與聚合器的 typeAndVersion 不同。
function version() external view returns (uint256);
winAvailableForPayment
返回本合約當前可用於支付預言機的 WIN 餘額。若存在未結清的支付義務,該值可能為負。
function winAvailableForPayment() external view returns (int256 availableBalance) {
int256 balance = int256(s_winToken.balanceOf(address(this)));
int256 due = int256(totalWINDue());
return int256(balance) - int256(due);
}
# 開發者使用須知
WINkLink 價格餵價通過 7 個獨立預言機節點的去中心化網絡為智能合約提供鏈下價格數據。餵價數據在 DApp 中的表現,取決於外部市場情況和應用集成代碼兩方面的因素。在集成 WINkLink 價格餵價時,請關注以下兩類要點:市場完整性和應用代碼。
# 市場完整性
WINkLink 價格餵價反映真實市場情況,受外部市場環境的影響。集成方在使用餵價數據時,應理解所反映資產的市場特性,並在業務邏輯中考慮極端情況。
外部市場環境對餵價的影響包括:
- 所反映資產的市場結構(交易所分布、深度、流動性等)會影響價格穩定性
- 流動性較低的資產,對外部市場環境變化更敏感
- 在極端市場情況(劇烈波動、流動性驟降、市場異常)下,餵價的更新行為可能出現非預期變化
集成時建議結合自身業務場景考慮極端情況下的處理邏輯,並在上線後持續觀察餵價行為。
# 應用代碼
應用代碼的質量、可靠性以及對外部依賴的處理,直接影響 DApp 使用價格數據的穩健性。
校驗價格時效性
每個 WINkLink 價格餵價都有一個心跳週期(heartbeat),表示在該週期內鏈上價格必有更新。建議在使用價格前主動校驗時間戳:
(uint80 roundId, int256 answer, , uint256 updatedAt, ) = priceFeed.latestRoundData();
require(updatedAt > 0, "Round not complete");
require(block.timestamp - updatedAt <= MAX_PRICE_AGE, "Price too stale");
MAX_PRICE_AGE 應大於該價格對的 heartbeat 週期,具體取值按業務容忍度選擇。
理解精度
WINkLink 價格餵價的精度(小數位數)可能因價格對而異。在做任何價格計算前,調用 decimals() 獲取精度:
uint8 dec = priceFeed.decimals();
// 在計算中使用 dec 進行歸一化
不要假設精度為固定值。
保持合約可升級
避免將餵價合約地址硬編碼到不可變更的業務邏輯中。建議將其存儲為可由合約所有者或治理機制更新的變量,以便在 WINkLink 升級或棄用底層聚合器時,能夠平滑遷移到新的餵價合約。
先在 Nile 測試網測試
在把你的消費合約部署到主網前,請先在 Nile 測試網、指向 WINkLink 的 Nile 餵價地址完成完整集成測試:
- Nile 測試網餵價合約地址:見 Nile 測試網
- 測試網 TRX(用於部署和調用你自己的合約)獲取:Nile 測試網水龍頭 (opens new window)
關注 WINkLink 資訊變化
WINkLink 通過兩個渠道發佈價格餵價相關的更新,建議集成方持續關注與自身業務相關的內容:
- 官方公告渠道 (opens new window):發佈價格對停用/棄用通知、新增價格對上線等事項
- WINkLink 價格餵價詳情頁 (opens new window):展示每個價格對的實時配置參數(如 heartbeat、deviation threshold),參數調整時此處會同步反映
建議在集成前記錄所用價格對的配置參數基線,便於上線後定期對比,及時發現參數變更。
上線後持續監控
集成完成上線後,建議持續監控以下信號:
- 餵價合約
latestRoundData()返回是否按心跳週期定期更新 - 業務合約中 stale check 或相關校驗是否被觸發
- 上述異常事件的頻率與時間分布
可結合 TRON 區塊瀏覽器的事件訂閱或自建鏈下監控腳本實現。