# WINkLink 价格服务

# 概览

为确保智能合约能反映真实世界的代币价格,需经常对合约的价格信息进行更新。 其中,DeFi 资产的价格尤其需要和现实世界资产紧密挂钩, 否则可能导致套利或合约攻击,给用户和开发者造成损失。

WINkLink 价格服务专注于数字货币价格对,为去中心化应用(DApp)提供准确稳定的外部世界数字货币价格信息。 WINkLink 打造了聚合多个预言机节点价格数据的解决方案,从而提供稳定的价格服务,称作喂价合约(Price Feed Contract)。

# 支持的价格对列表及配置

# 主网

价格对 合约地址(代理)
BTC-TRX TX4rin6u2SaF3TqANqRgzfSCGi95azQNVY
BTC-USD TQoijQ1iZKRgJsAAWNPMu6amgtCJ3WMUV7
BTT-TRX TS26cn4GmmipyGTcgvRRwqL6AyEU6vK4rw
BTT-USD TBAAW545oJ6iTxqzezGvagrSUzCpz1S8eR
BTTOLD-TRX TUjTmKMxGmH78t5DmY7YsfJFoGw6XyX9VZ
BTTOLD-USD TEEnwU47Fgx4Ehii7Xs9bLWK3XKo4fs6sV
ETH-TRX TXZ9AUk6nC2454NSDGUWvPB72JxSNJrezX
ETH-USD TR2yWYWovJaSM7TfZq7L7sT7ZRugdJJQmL
JST-TRX TC19QPF2mjP1ZhXxD8JNKJs4ksxMZkCuNP
JST-USD TE5rKoDzKmpVAQp1sn7x6V8biivR3d5r47
LIVE-USD TNdLmxVhdj1H1yGjhhSp33cMaAJKjyTAM4
LTC-TRX TVJPFXKMysYsRWEXJ3JkSnAUPucinUFUB6
LTC-USD TGxGL85kN3W5sGdBiobgWabWFcMEtoqRJJ
NFT-TRX TKtc1V6QAY1Gpy511QjzXkLUphG8Dre8CY
STRX-TRX TW9bNueyJZA9iZnNXGYkJuPJJ7KFN3o5qw
NFT-USD TEC8b2oL6sAQFMiea73tTgjtTLwyV1GuZU
SUN-TRX TLLyqXr5cbYEMjzeThe1esss1SVBbxxubu
SUN-USD TRMgzSPsuWEcVpd5hv19XtLeCk8Z799sZa
SUNOLD-TRX TWAob1YsNzh7bfgkjfAD9MAdarcoSWScWw
SUNOLD-USD TEEuSdqyv2NFREtNoUXMTDSmJVK3KCuLac
TRX-USD TR5HtpPK4gX4RFC4DCBUHfFgsGkGFEzSAb
TUSD-TRX TLXMULb1SRpv841Q54C4DhWkmmGfRA2rUH
TUSD-USD TBc3yBP8xcyQ1E3hDTUhRxToMrgekLH2kh
USDC-TRX TNTm5ezUGHxYc9Mvst58yYTAjxDmqWWGZc
USDC-USD TNu3zS55MP4KnBBP6Maw1nHSzRpc3CXAxm
USDD-TRX TWW4P2pck8rFcxx3H8NfnH4qhNPu1V35Pb
USDD-USD TJ7jEgoYVaeymVfYZ3bS57dYArwVDS1mhW
USDJ-TRX TCBKyYMP4YQFHxYznuUaResHDTaEWLuJNW
USDJ-USD TB1MyT7pDCNg8w7cSW1QvYKs4WPzErzP5k
USDT-TRX TUfV7S4RYtdmBvtHzedfFPVsK9nvndtETp
USDT-USD TKePc46n5CiUCR8LL788TFeKA4kjvNnuem
WIN-TRX TQvCG1U2jGTVwXLqvFWR27LDtEJZVgRbEg
WIN-USD TSCef3LT3jpLwwXCWhZe3hZoMsYk1ZLif2
WSTUSDT-TRX TKcTU5vCPqBBfuULEGXg9kkLx6Tzs2Zo3x

# Nile 测试网

  • WIN 代币合约地址: TNDSHKGBmgRx9mDYA9CnxPx55nu672yQw2
  • WinkMid 合约地址: TLDU7C8K3Gd3pXrAj9gtpVVNRHZHuHHZ8P

价格服务合约地址列表:

价格对 Nile (代理)
BTC-TRX TFETSL1Yc8dCJM7z6uBkHhAsPbqP5UaCDE
BTC-USD TAX8Pm3FgN74za72TFZrn5gPBxJTKgnnpE
BTT-TRX TKbeHN2hdrgSShG6iF3mDsJTu9fFzNrHjo
BTT-USD TJdzg4wqBt4JkP1ehbYQufg1cLjbomT2j7
BTTOLD-TRX TETkTRbnyB4ptWiK9qXgiyFxQQ9d8ZacT6
BTTOLD-USD TRpRfFzubR7oheDCwHRbwJRfeFa85L6tWE
ETH-TRX TSVJwLrhWBF7K6BkEG6hStjMxQJXAzBABQ
ETH-USD TQGyY3mWTTzKKBLBg3wQTSbAGqBnGqYSzX
JST-TRX TSf6ZwFrDg5Jvyci1PnRHrrZvPpCCKNTjj
JST-USD TJ7SizJiCAjMPAri1CFAxzg4xCRLycumMj
LIVE-USD TPxNjLNrn3WAwoyGQgqJyw3dLo9E79mUdH
LTC-TRX TWProfbHdGBCf7HVNys5KAbVT4vhUwpu22
LTC-USD TRSFTb2seuQxQqUsyeJ8Wg8XhX1e2g3T19
NFT-TRX TWP99RnyMVKFjzuu9XT5J21qBZu8DwhCum
NFT-USD TX5KVe4sp24w5HJ4nfk2ZstRhV8RTFm67W
STRX-TRX TEbUQ4gohuK5wdtKmpnGd2kvyzhhznJDCx
SUN-TRX TTxxeWGpSDV3zPDxnYXzG1ue7RpTYTvDpY
SUN-USD TJjENuVH7TD8RJdGtj22ac6Bt1ktpBGURR
SUNOLD-TRX TNfn4qt4QJ7LAndM2aWbxrGGH8CRGvzxui
SUNOLD-USD TMKzWKMA1gSwjYSL6VpfCUXLuwPKdjEsQ2
TRX-USD TCeXRh9vcb78j2Eb2oJk4YwwnoHQDT64T1
TUSD-TRX TM1bvBzHkRrQqvvHGi1CC1Heb8ESWreiNW
TUSD-USD TUuxMFxv6qPn1ymZoYY45SSK1hhEVAvyKz
USDC-TRX TWio8JqYx2aey49ua2ohLoyBPbVVWos8RB
USDC-USD TF5a2qhfxtWzUQnAocPoxgKXLe1vEE8oER
USDD-TRX TFr7TWdb5RWPNCfecr3HNfnCmNNL8qvgmJ
USDD-USD TX264fxRmdhNfUgkruk9orzAVvtCehyowq
USDJ-TRX TDJtnT7JRNqmNaqY1mK9i1xWN4GnX1UfGd
USDJ-USD TKZUQTYAhH1LTG67QmhX4HxTWZdvLfH9d1
USDT-TRX TJL5M1QqL7oF2ceazAFJ2ump9jf87jUqnK
USDT-USD TT2ETLY1Mmx2DKYT9S6fMvKGPqbWH3LDEJ
WIN-TRX TP7aHYuXUkKPKsojs9BNJDVyAJeQ2KtfCj
WIN-USD TYYMqsRNZTwsiFkRtn2NewvXT9GnnsPBH9
WSTUSDT-TRX TZGEUihByCHG79Hbpider6pGZfY9S8ct6P

# 申请新价格对

如您想在 WINkLink 申请添加新价格对,请填写并提交此表格。 (opens new window)

# 获取最新价格

使用 AggregatorInterface 接口获取 Consumer 合约的最新价格数据。

这一接口定义了喂价合约提供给用户的函数。 下方的代码示例展示了如何使用 AggregatorInterface 接口获取最新价格:


pragma solidity ^0.5.0;

interface AggregatorInterface {
function latestAnswer() external view returns (int256);
function latestTimestamp() external view returns (uint256);
function latestRound() external view returns (uint256);
function getAnswer(uint256 roundId) external view returns (int256);
function getTimestamp(uint256 roundId) external view returns (uint256);
}

contract PriceConsumer {
AggregatorInterface internal priceFeed;

    /**
     * Price Aggregator Address: TYZxQSHAhxGgUWzxYEZAohvWc9cQWXtNBt
     */
    constructor() public {
        priceFeed = AggregatorInterface(0xF7e52418572834722ED87E9425d673FEdBD55a0e);
    }

    /**
     * Returns the latest price
     */
    function getLatestPrice() public view returns (int) {
        // If the round is not complete yet, timestamp is 0
        require(priceFeed.latestTimestamp() > 0, "Round not complete");
        return priceFeed.latestAnswer();
    }
}

# 获取价格历史

AggregatorInterface 接口使用 getAnswer(uint256 roundId) 函数获取价格历史, 对应的时间戳可通过 getTimestamp(uint256 roundId) 获得。

# 设置喂价合约

# 部署合约

WINkLink 生态采用去中心化架构,所有智能合约开源,任何组织和个人都可以部署自己的 WINkLink 预言机合约, 并对外公布所提供的服务。

用户可以从各个公开 WINkLink 服务中选择自己所需的组合,创建自己的聚合数据合约,享受去中心化机制带来的便利。

项目合约可点此查看:https://github.com/tron-oracle/winklink-libocr/tree/main/tvm-contracts (opens new window) - 连接您的 Github 账户

您可以使用以下任一工具或程序库进行合约部署和调用测试:

# 聚合器合约

聚合器合约部署在波场 TRON 公链上,具有以下功能:

  • 接受来自 WINKLink 节点的链下聚合传输;
  • 计算数据请求的 WIN 代币费用,准许预言机节点领取奖励;
  • 实现 Owned 接口, 进而对聚合器合约暴露的不同方法提供权限控制。

合约代码可于 AccessControlledOCRAggregator.sol 查看。

# 启动喂价服务节点

# 节点部署

合约部署完毕后,即可开始 WINLink 节点部署。

WINkLink 节点(项目目录节点)代码可点此查看:https://github.com/tron-oracle/winklink-2.0/tree/main (opens new window) — 连接您的 Github 账户。

WARNING

当前节点实现包含通过交易所 API 访问代币价格的适配器。 请在中国大陆以外的稳定网络环境中运行节点。

# 准备节点账户

每个 WINLink 节点必须与一个波场帐户关联,以便调用聚合器合约传输数据。

账户地址和私钥生成后,开发人员可以在测试网水龙头页面测试 TRX 代币。该代币用于支付调用智能合约产生的手续费。

节点初始运行时将生成账户,私钥将存储在密钥链中。 节点将使用该账户进行喂价传输。

WARNING

账户尚未激活,请转账任意数量的 TRX 到该账户以进行激活

# 所需环境

WINkLink 节点依赖 PostgreSQL 数据库, 开发者可在 PostgreSQL 的官方文档中获取更多信息。

TIP

这里假定本机部署的 PostgreSQL 实例的用户名和密码分别是 root:root。 在生产环境中请使用强密码或其他验证方式。

WINkLink 节点使用的编程语言为 Go,因此需要搭建 Golang 环境。

# 节点配置

WINkLink 节点的配置文件格式为 TOML, 主配置为 tools/config/config.toml。 你可以使用 secrets.toml 指定要使用的 db 实例。 以下为参考模板。

# secrets.toml
[Database]
URL = 'postgresql://root:root@localhost:5432/winklink?sslmode=disable' # Require
AllowSimplePasswords = true

[Password]
Keystore = 'keystorePassword' # Required

[Tron]
TronApiKey = 'apiKey'

节点配置文件确认完毕后,还需要创建 apicredentials 文件和密码,然后写入用户 ID 和密码访问节点 API:

# apicredentials
example.user@fake.email
totallyNotFakePassword (16 characters long)
# password
totallyNotFakePassword (16 characters long)

TIP

请妥善托管您的个人信息。

# 搭建节点 Docker 镜像

使用以下指令构建标准的 Linux 镜像:

#build a docker image
docker buildx build --platform linux/amd64 -t winklink-2.0 -f core/winklink.Dockerfile .

将构建好的 Docker 镜像打上标签并推送到所需的存储库进行部署。

# 用源代码启动节点

安装 go1.20 (opens new window)

前往 winklink-2.0 源代码的基本目录

搭建命令行界面

make install

使用以下指令及对应配置项启动 WINkLink 节点:

winklink -c /tools/config/config.toml -s /tools/config/secrets.toml node start -p /tools/secrets/vrfpassword -a /tools/secrets/apicredentials

WARNING

节点帐号必须有足够的 TRX 代币,用于合约调用。 可以通过测试网水龙头申请测试代币。

# 为节点添加任务

节点的任务代表其所支持的数据服务,每个任务都有一个 32 字节的唯一 ID。 对终端用户而言, (预言机地址,任务 ID) 唯一标识了一个 WINLink 节点提供的数据服务。 每个 WINkLink 节点都可以提供多项数据服务。

WINLink 节点正常运行后,就可以通过 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 的任务选项卡下检索任务。

子选项卡如下:

  • 概览:最近的运行任务和任务流列表
  • 定义:任务规范
  • 错误:自任务创建以来累计遇到的不同错误
  • 运行:所有任务运行的列表

job-page-ui.png