如何获取美元和HBAR之间的汇率以用于Hedera应用程序或智能合约?

问题描述 投票:0回答:3

我的智能合约或应用程序如何从 Hedera 网络(Hedera 文件服务)上的文件访问 USD/HBAR 汇率信息?

我感兴趣的文件是0.0.112。我尝试从我的应用程序中使用 SDK 进行查询,它似乎为我提供了信息,但我如何在合同中使用它以及该价格信息的实时性如何?

async function main() {
    const fileQuery = new FileContentsQuery().setFileId("0.0.112");
    const contents = await fileQuery.execute(client);
    console.log(contents.toString());
}
main();
solidity hedera-hashgraph hashgraph hedera
3个回答
0
投票

您正朝着正确的方向前进。几点:

正如您所发现的,外部应用程序只需使用 SDK 执行 FileContentsQuery() 即可访问 0.0.112 的汇率。您还可以使用此镜像 REST API 调用 (https://mainnet-public.mirrornode.hedera.com/api/v1/network/exchangerate),它还会公开 HFS 文件中的汇率信息。

如果您需要在智能合约中访问 0.0.112 的汇率信息,那么我建议查看 HIP-475 (https://hips.hedera.com/hip/hip-475),所以你可能会得到类似的结果:

import "./IExchangeRate.sol";

abstract contract SelfFunding {
    uint256 constant TINY_PARTS_PER_WHOLE = 100_000_000;
    address constant PRECOMPILE_ADDRESS = address(0x168);

    function tinycentsToTinybars(uint256 tinycents) internal returns (uint256 tinybars) {
        (bool success, bytes memory result) = PRECOMPILE_ADDRESS.call(
            abi.encodeWithSelector(IExchangeRate.tinycentsToTinybars.selector, tinycents));
        require(success);
        tinybars = abi.decode(result, (uint256));
    }

    modifier costsCents(uint256 cents) {
        uint256 tinycents = cents * TINY_PARTS_PER_WHOLE;
        uint256 requiredTinybars = tinycentsToTinybars(tinycents);
        require(msg.value >= requiredTinybars);
        _;
    } 
}

请注意,0.0.112 中的汇率不是来自交易所的实时价格预言机。相反,它是主要交易所近期 HBAR 兑美元汇率的加权中位数。因此,如果您需要实时定价数据,0.0.112 中的信息将不起作用。

您可能需要使用加密货币交易所的 API(最好是几个交易所的平均值)。该查询无法从智能合约执行。这通常在外部应用程序中执行,然后如果智能合约逻辑需要此信息,则该应用程序可以调用智能合约。


0
投票

更新的答案,对于较新的 Solidity 版本,还使用 HIP-475 的汇率系统合约, 可以在

0x168
获得,界面如下:

interface IExchangeRate {
    function tinycentsToTinybars(uint256 tinycents) external returns (uint256);
    function tinybarsToTinycents(uint256 tinybars) external returns (uint256);
}

只要您的用例确实需要高度的准确性或“活跃度”, 这可以很好地完成转换。

以下示例演示如何使用汇率系统合约 从 USD 美分转换为 HBAR 美分。

在 Remix 中尝试一下

// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.18;

interface IExchangeRate {
    // Given a value in tinycents (1e-8 US cents or 1e-10 USD), returns the 
    // equivalent value in tinybars (1e-8 HBAR) at the current exchange rate 
    // stored in system file 0.0.112. 
    // 
    // This rate is a weighted median of the the recent" HBAR-USD exchange 
    // rate on major exchanges, but should _not_ be treated as a live price 
    // oracle! It is important primarily because the network will use it to 
    // compute the tinybar fees for the active transaction. 
    // 
    // So a "self-funding" contract can use this rate to compute how much 
    // tinybar its users must send to cover the Hedera fees for the transaction.
    function tinycentsToTinybars(uint256 tinycents) external returns (uint256);

    // Given a value in tinybars (1e-8 HBAR), returns the equivalent value in 
    // tinycents (1e-8 US cents or 1e-10 USD) at the current exchange rate 
    // stored in system file 0.0.112. 
    // 
    // This rate tracks the the HBAR-USD rate on public exchanges, but 
    // should _not_ be treated as a live price oracle! This conversion is
    // less likely to be needed than the above conversion from tinycent to
    // tinybars, but we include it for completeness.
    function tinybarsToTinycents(uint256 tinybars) external returns (uint256);
}

contract Exchange {
    IExchangeRate constant ExchangeRate =
        IExchangeRate(address(0x168));

    event ConversionResult(uint256 inAmount, uint256 outAmount);

    function convert(uint256 usdCents) external returns (uint256 hbarCents) {
        hbarCents = ExchangeRate.tinycentsToTinybars(usdCents * 100_000_000) / 1_000_000;
        emit ConversionResult(usdCents, hbarCents);
    }
}

请注意,截至撰写本文时,1,000.00 美元等于 19,584.80 HBAR。

exchange-rate-coinbase-pair

但是,输入 100,000 (

usdCents
) 会返回 1,969,667 (
hbarCents
) 的输出, 大约是实时价值的 0.6% 折扣。 所以不要在 DEX 或类似的东西中使用它。


0
投票
const fileQuery = new FileContentsQuery().setFileId("0.0.112");
const contents = await fileQuery.execute(client);
const exchangeRate = ExchangeRates.fromBytes(contents);
console.log('Exchange rate is ', exchangeRate);
© www.soinside.com 2019 - 2024. All rights reserved.