ICON Developer Portal

ICON Developer Portal

ICON Network is a decentralized smart contract protocol based on ‘loopchain’, a high-performance blockchain engine. The ICON Network aims to remove barriers among different blockchains and allow them to exchange values without intermediaries. By realizing this goal, ICON will realize the mass adoption of blockchain technology and Hyperconnect the World.

Get Started

Band Protocol

Band Protocol Integration

In addition to data native to the ICON blockchain, ICON developers also have access to various cryptocurrency price data provided by Band Protocol's oracle.

Bridge Contract Info

Data Available

The price data originates from data requests made on BandChain. Band's bridge SCORE on ICON then retrieves and stores the results of those requests. Specifically, the following price pairs are available to be read from the bridge contract:

  • BTC/USD
  • ETH/USD
  • ICX/USD

These prices are automatically updated every 5 minutes. The SCORE itself is currently deployed on ICON Yeouido testnet at cx8b679486b721b70e332f59cfb9c46dadc23ff0c5.

The prices themselves are the mean of the values retrieved by BandChain's validators from CoinGecko, CryptoCompare, and Binance APIs. The data request is then made by executing Band's Crypto Price in USD oracle script, the code of which you can view on their devnet. Along with the price data, developers will also have access to the following parameters:

  • The symbol of the token associated with the price
  • The multiplier used to calculate the stored price value
  • The timestamp of when the specific price request was resolved on BandChain

These parameters are intended to act as security parameters to help anyone using the data to verify that the data they are using is what they expect and, perhaps more importantly, actually valid.

Bridge Contract Price Update Process

For the ease of development, the Band Foundation will be maintaining and updating the bridge contract with the latest price data. In the near future, we will be releasing guides on how developers can create similar contracts themselves to retrieve data from Band's oracle.

Retrieving the Price Data

The code below shows an example of a relatively simple price database SCORE on ICON which retrieve price data from Band's bridge contract and store it in the contract's state.

Specifically, the contract is set to only store price data from the bridge contract if the token symbol is BTC,ETH, or ICX. For more information on what oracle scripts are and how data requests work on BandChain in general, please see their wiki and developer documentation

from iconservice import *

TAG = 'EXAMPLE_SCORE'

class BAND_PRICE_SCORE(InterfaceScore):
    @interface
    def get_price_info(self,symbol: str) -> dict:
        pass

class EXAMPLE_SCORE(IconScoreBase):
    def __init__(self, db: IconScoreDatabase) -> None:
        super().__init__(db)

        self.band_price_address = VarDB("band_price_address", db, value_type=Address)

        self.price = VarDB("price", db, value_type=int)
        self.multiplier = VarDB("multiplier", db, value_type=int)
        self.response_timestamp = VarDB(
            "response_timestamp", db, value_type=int)

    def on_install(self) -> None:
        super().on_install()

    def on_update(self) -> None:
        super().on_update()

    @external
    def set_band_price_address(self, bridge_address: Address) -> None:
        self.band_price_address.set(bridge_address)

    @external(readonly=True)
    def get_band_price_address(self) -> Address:
        return self.band_price_address.get()

    @external(readonly=True)
    def get_price(self) -> int:
        return self.price.get()

    @external(readonly=True)
    def get_multiplier(self) -> int:
        return self.multiplier.get()

    @external(readonly=True)
    def get_response_timestamp(self) -> int:
        return self.response_timestamp.get()

    @external
    def read_from_price_db(self) -> None:
        expected_symbol = "ICX"

        price_db = self.create_interface_score(self.band_price_address.get(), BAND_PRICE_SCORE)
        res = price_db.get_price_info(expected_symbol)

        res_symbol = res["symbol"]
        res_price = res["price"]
        res_multiplier = res["multiplier"]
        res_latest_response_timestamp = res["latest_response_timestamp"]

        if res_symbol != expected_symbol:
            revert(f"result token symbol mismatch: expected {expected_symbol} but got {res_symbol}")

        self.price.set(res_price)
        self.multiplier.set(res_multiplier)
        self.response_timestamp.set(res_latest_response_timestamp)

Code Breakdown

The example code above can be broken down into two sections: defining the interface for the BAND_PRICE_SCORE and the actual SCORE code itself.

BAND_PRICE_SCORE Interface

This section consists of only one function, get_price_info. This is the interface that we'll use to query Band's price SCORE for the latest price of a token, specified by the argument symbol.

EXAMPLE_SCORE class

The EXAMPLE_SCORE then contains the main logic of our SCORE. It's purpose will be to store the latest price, along with the related information, of the ICX token. Specifically, the SCORE will store 3 state variables:

  • The latest price of the ICX token as retrieved from Band's price SCORE
  • The multiplier by which price was multiplied by
  • The response_timestamp, or the timestamp in which the request associated with the stored price was resolved

The price data query itself then occurs in read_from_price_db. Before we can call the method, however, we need to first set the address of Band's price score. This is done by calling the set_band_price_address method.

The read_from_price_db function then starts of by calling get_price_info with ICX as the symbol argument. It then parse the returned dict to get the fields it needs.

Once the parsing is completed, the function then checks that the symbol, and by extention the other info, returned by get_price_info is actually what we expect. If the check failed, the function terminates and the transaction is reverted.

Otherwise, the function concludes its operations by saving the price, multiplier, and response_timestamp into the SCORE's state.

The full source code for the EXAMPLE_SCORE score can be found in this repo along with the JSON for sending the set_band_price_address read_from_price_db. The score itself is also deployed to the testnet at address cx690c2ff7941a575e9ef52f02e7636f0a08b054f4.

Updated 2 months ago

Band Protocol


Suggested Edits are limited on API Reference Pages

You can only suggest edits to Markdown body content, but not to the API spec.