docs
  • Introduction
  • Getting started
    • Meet the network using CLI
    • Your first transaction
    • Run smart contract
    • Run your own node
    • Ledger Support
  • Architecture
    • Dnode
    • Dncli
    • XFI & Other coins
    • Fees & Gas
    • Addresses
  • Staking
    • Delegate sXFI & LPT
    • Become a validator
    • Rewards & Inflation
    • Slashing
    • More
  • Move VM
    • Modules
    • Scripts
    • Script Arguments
    • Standard Library
    • Events
    • Resources
    • Move Book
    • More
  • Oracles
    • Query Price
  • PegZone
    • Deposit
    • Usage
    • Withdraw
  • Useful Resources
    • Dfinance Website
    • Wallet
    • Move Book
    • Block Explorer
    • Swagger UI
    • Community
    • VSCode Move IDE
Powered by GitBook
On this page
  • Price
  • Write a script
  • Usage in module

Was this helpful?

  1. Oracles

Query Price

PreviousOraclesNextPegZone

Last updated 4 years ago

Was this helpful?

Current dfinance VM implementation supports querying the price for the provided ticker thanks to module:

address 0x1 {
/// Enum-like module to make generic type-matching possible, every coin which is
/// officially supported by blockchain (or peg-zone specifically) is added here.
/// Ideally this module should be auto-generated and rarely updated via consensus
module Coins {
    struct ETH {}
    struct BTC {}
    struct USDT {}

    resource struct Price<Curr1, Curr2> {
        value: u128
    }

    public fun get_price<Curr1, Curr2>(): u128 acquires Price {
        borrow_global<Price<Curr1, Curr2>>(0x1).value
    }

    public fun has_price<Curr1, Curr2>(): bool {
        exists<Price<Curr1, Curr2>>(0x1)
    }
}
}

There are two functions, get_price and has_price, both require two generics (pairs) to make a call, e.g.: BTC_USDT, ETH_USDT, XFI_BTC.

Let's try to query BTC_USDT price:

let btc_usd = Coins::get_price<Coins::BTC, Coins::USDT>();

As script it looks so:

script {
    use 0x1::Coins;

    fun main() {
        let _ = Coins::get_price<Coins::BTC, Coins::USDT>();
    }
}

Also, you can check, if pair exists:

script {
    use 0x1::Coins;

    fun main() {
        // If BTC_USDT pair doesn't exist - throw error with code 101.
        assert(Coins::has_price<Coins::BTC, Coins::USDT>(), 101);
    }
}

Price

By default returned u128 price has reserved 8 decimals places.

Means price for ETH_USDT as 100.02 will be presented as 10002000000.

Write a script

Let's write a script that will take BTC_USDT price and will emit an event with this ticker's price:

script {
    use 0x1::Event;
    use 0x1::Coins;

    fun main(account: &signer) {
        let price = Coins::get_price<Coins::BTC, Coins::USDT>();

        Event::emit(account, price);
    }
}

Compile the script and execute.

You can query results by transaction id to see how events with price fired.

Usage in module

Similarly, you can write your module, that will use the price from oracles.

Something like:

module PriceRequest {
    use 0x1::Coins;

    public fun get_eth_usdt_price(): u128 {
        Coins::get_price<Coins::ETH, Coins::USDT>()
    }
}

And then just use it in your scripts.

To see an example look at our , ETH_USDT part, how price presented there.

Coins
API