Harmony
Support ForumGithubTelegramDiscord
  • Welcome
  • 🎶General
    • Introduction
      • What is Harmony?‌
      • Roadmap
      • Strategy & Architecture
      • Study Materials
      • FAQ
    • Technology
      • Key Features
      • Randomness
      • Sharding
      • Consensus
      • Effective Proof-of-Stake
      • Tokenomics
      • Transactions
    • LayerZero Bridge
      • Important Notice
      • Bridge tutorial
      • FAQ
        • What token will I get after the bridge
        • How to find a bridged token address
    • Ecosystem
      • Wallets
        • 1Wallet
        • Gnosis Safe
        • Hardware Wallets
          • Trezor
          • Ledger Nano
            • Ledger with Metamask
            • Download & Setup
            • Ledger with HMY CLI
            • Ledger with Staking Dashboard
              • Sign In With Ledger
              • Sending transactions via Ledger
              • Staking Transactions via Ledger
          • Safepal
            • Download & setup
            • Create/import account
            • Send transaction
        • Browser Extension Wallets
          • Metamask
            • Installing MetaMask
            • Adding Harmony
            • Create a New Account
            • Sending & Receiving
            • Adding Custom Harmony Tokens
            • Import an Account
          • Math Wallet
            • Download & Setup
            • Create/Import/Export Wallet
            • Sending Transactions
            • Staking
            • Collecting Rewards
            • Undelegating
          • Harmony Chrome Extension Wallet
        • Desktop Wallets
          • Guarda Wallet
          • Staking4All Wallet
        • Mobile Wallets
          • Metamask Wallet
          • Blits Wallet
          • Cobo Wallet
          • Frontier Wallet
          • Guarda Wallet
          • Infinity Wallet
          • ONTO Wallet
          • Sef Wallet
          • Trust Wallet
          • Trustee Wallet
        • Web Wallets
          • Guarda Wallet
        • HMY CLI (Harmony Command Line Interface)
          • Download & Setup
          • Create or Import Wallet
          • Sending Transactions
          • Staking Transactions
          • Querying Balances
          • Querying the Blockchain
          • List of Transaction Error Messages
          • Cookbook
          • Other CLI References
      • DApps
        • User Guide
        • DeFi
          • Sushi
          • Onsen
        • CLI 1Wallet User Guide
        • Media
          • Timeless
        • FAQ
        • NFTs
      • Partners
        • Exchanges
        • Fiat Gateways
        • DeFi Protocols
      • Integrations
      • Cross-Border Finance
      • DAOs
        • Components & Tools
          • Snapshot
        • Community DAO
        • Validator DAO
        • Developer DAO
    • Community
  • 🏗️Developers
    • Getting Started
      • Network & Faucets
      • List of RPC Providers
      • Remix IDE
      • Dev Environment Setup
      • Ethereum Compatibility
    • Deploying on Harmony
      • Using Remix
        • Ethereum Remix
        • Harmony Remix
      • Using Truffle
      • Using Hardhat
      • Using Web3
      • Using Harmony-JS
        • Setup
        • Compile & Deploy
        • Demo: Deploying an Ethereum Smart Contract on Harmony
      • Deploy HRC20
      • Smart Contract Verification
    • SDK
      • Web3.js
        • Using Web3.js to Send Transactions on Harmony
        • Find the last transaction
      • JavaScript SDK
      • Go CLI
      • Java SDK
      • Python SDK
      • Harmony Ethers.js Wrapper
    • API
      • Methods
        • Account Methods
          • hmy_getBalanceByBlockNumber
          • hmy_getTransactionCount
          • hmy_getBalance
        • Filter Methods
          • hmy_getFilterLogs
          • hmy_newFilter
          • hmy_newPendingTransactionFilter
          • hmy_newBlockFilter
          • hmy_getFilterChanges
          • hmy_getLogs
        • Transaction Related Methods
          • hmy_getStakingTransactionByBlockHashAndIndex
          • hmy_getStakingTransactionByBlockNumberAndIndex
          • hmy_getStakingTransactionByHash
          • hmy_getCurrentTransactionErrorSink
          • hmy_getPendingCrossLinks
          • hmy_getPendingCXReceipts
          • hmy_getCXReceiptByHash
          • hmy_pendingTransactions
          • hmy_sendRawStakingTransaction
          • hmy_getTransactionsHistory
          • hmy_sendRawTransaction
          • hmy_getTransactionReceipt
          • hmy_getBlockTransactionCountByHash
          • hmy_getBlockTransactionCountByNumber
          • hmy_getTransactionByHash
          • hmy_getTransactionByBlockNumberAndIndex
          • hmy_getTransactionByBlockHashAndIndex
          • hmy_getBlockByNumber
          • hmy_getBlockByHash
          • hmy_getBlocks
        • Contract Related Methods
          • hmy_estimateGas
          • hmy_getStorageAt
          • hmy_call
          • hmy_getCode
        • Protocol Related Methods
          • hmy_isLastBlock
          • hmy_epochLastBlock
          • hmy_latestHeader
          • hmy_getShardingStructure
          • hmy_blockNumber
          • hmy_syncing
          • hmy_gasPrice
          • net_peerCount
          • hmy_getEpoch
          • hmy_getLeader
        • Staking Related Methods
          • hmy_getCirculatingSupply
          • hmy_getTotalSupply
          • hmy_getStakingNetworkInfo
          • hmy_getAllValidatorInformation
          • hmy_getAllValidatorInformationByBlockNumber
          • hmy_getCurrentUtilityMetrics
          • hmy_getDelegationsByValidator
          • hmy_getDelegationsByDelegatorAndValidator
          • hmy_getDelegationsByDelegator
          • hmy_getValidatorMetrics
          • hmy_getMedianRawStakeSnapshot
          • hmy_getElectedValidatorAddresses
          • hmy_getAllValidatorAddresses
          • hmy_getCurrentStakingErrorSink
          • hmy_getValidatorInformation
          • hmy_getValidators
          • hmy_getSignedBlocks
          • hmy_isBlockSigner
          • hmy_getBlockSigners
        • Tracing Methods
          • trace_block
          • trace_transaction
      • Sample Code
    • Tools
      • Harmony VRF
      • The Graph
      • Envio
      • Ganache
        • Harmony Ganache
      • Harmony-React
      • Oracles
        • Band Protocol
      • Smart Contract Verification
    • Tutorials
      • Deploying HRC20
      • Deploying HRC721/NFT
      • The Graph - Subgraphs
        • Building & Deploying Subgraph (local node)
      • Using Band Oracle
      • Using Crosschain API
        • Scripts
        • Testing
        • Webserver
      • Using Web3.py & Pyhmy
      • Using IPFS & Filecoin
        • Using IPFS
        • Using NFT.storage
      • Indexing HRC20 with Envio
      • Building a Simple Metaverse Contract
      • Building a Simple Bridge with Ethereum
      • Staking for Multisig
    • DApp Examples
      • DApp Samples
      • Games
        • Harmony Puzzle
      • Cross-Chain
      • DeFi
      • Hackathons
        • DevPost
        • Hack the Horizon
      • Others
    • Wallets
      • Metamask
        • Interacting With Metamask
        • Using Metamask with Harmony Smart Contracts
        • Add or Switch to Harmony chain on Metamask
      • Harmony Chrome Extension Wallet
      • Math Wallet
      • WalletConnect
    • Harmony Stack and Projects
  • 🌏Network
    • Governance
      • Network Governance
        • Voting via Governance App
        • Voting via HMY CLI
      • HRC-20 Governance
      • FAQ
    • Validators
      • Terms & Concepts
        • Validator, BLS key, Instance
          • Shard Assignment
        • Slots Bidding and Election
        • Effective Proof-of-Stake
        • Block Reward
        • Epoch Transition
        • Slashing
        • Undelegation
      • Server Setup
        • Requirements
        • Cloud Guides
          • Digital Ocean
          • Vultr
          • AWS
          • Google Cloud
        • Raspberry Pi Guide
      • Node Setup
        • 1. HMY CLI Download
        • 2. Setting up BLS Keys
        • 3. Syncing DB
        • 4. Installing & Updating
          • Installing A Node
            • Using Node Binary
            • (Deprecated) Using AutoNode
              • Install & Run
              • Update
              • Monitor
              • BLS Key Management
              • Collect Rewards
              • Maintenance
              • Troubleshoot
              • Extra
            • (deprecated) Using Node.sh
          • Upgrading A Node
            • Using Node Binary
            • Using AutoNode (deprecated)
            • Using Node.sh (deprecated)
          • Checking A Node
      • Creating A Validator
      • Managing A Validator
        • Checking Validator Information
        • Changing Validator Information
        • Delegating To A Validator
        • Undelegating From A Validator
        • Check Your Delegations
        • Collecting Rewards
        • Adding A Validator Logo
      • Staking Dashboard Basics
      • Validator Information Terms
      • Validator Security Tips
      • Slashing and Uptime
      • Monitoring
        • Node Sync
        • Prometheus & Grafana
        • Network Status
      • Troubleshooting
        • Why am i not Elected?
        • Frequently Asked Questions (FAQ)
      • Tools
        • Telegram Bots
        • Dashboards
        • Reward Calculators
        • Text User Interface (TUI)
        • HMY Bidder
        • Mobile Apps
          • One Validator Dashboard
          • Termux
    • Delegators
      • Introduction
      • Staking
        • Via Browser
          • Staking Dashboard
          • Staking Transactions
          • Sending Transactions
        • Via Mobile
        • FAQ
      • Redelegation
      • Informational Videos
Powered by GitBook
On this page
  • How to Interact with BandChain from Harmony Smart Contracts
  • Requesting data using BandChain.js library
  • Using BandChain data in EVM Smart Contract in Harmony
  • Obi.sol
  • Decoders.sol
  • IBridgeCache.sol
  • Contract Constructor
  • getPrice Function
  • References:
  • Examples
  • Requesting data using BandChain.js library
  • Using BandChain data in EVM Smart Contract in Harmony

Was this helpful?

Export as PDF
  1. Developers
  2. Tools
  3. Oracles

Band Protocol

PreviousOraclesNextSmart Contract Verification

Last updated 3 years ago

Was this helpful?

How to Interact with BandChain from Harmony Smart Contracts

We will go through each of these steps:

  1. Requesting data using BandChain.js library

  2. Using BandChain data in EVM Smart Contract in Harmony

Requesting data using BandChain.js library

BandChain provides the JavaScript library so developers can submit data requests right from their dApp client.

Once BandChain has successfully executed the requested oracle script, it will return the data and EVM proof payload back to the client to then be passed to our smart contracts in harmony blockchain.

Here is an example simple Node file requesting data using the library that queries the current Bitcoin(BTC) price from BandChain.

const BandChain = require('@bandprotocol/bandchain.js');
const { Obi } = require('@bandprotocol/obi.js');//BandChain POA mainnet endpoint URL
//const endpoint = 'http://poa-api.bandchain.org';
//BandChain dev-net endpoint URL
const endpoint = 'http://guanyu-devnet.bandchain.org/rest';const getBTCPrice = async () => {
 // Instantiating BandChain with REST endpoint
 const bandchain = new BandChain(endpoint);// Create an instance of OracleScript with the script ID
 const oracleScript = await bandchain.getOracleScript(76);// Create a new request, which will block until the tx is confirmed
 try {
   const minCount = 3;
   const askCount = 4;
   const mnemonic =
     'panther winner rain empower olympic attract find satoshi meadow panda job ten urge warfare piece walnut help jump usage vicious neither shallow mule laundry';
   const requestId = await bandchain.submitRequestTx(
     oracleScript,
     {
       symbol: 'BTC',
     },
     { minCount, askCount },
     mnemonic
   );
   // Get final result (blocking until the reports & aggregations are finished)
   const finalResult = await bandchain.getRequestResult(requestId);
   let result = new Obi(oracleScript.schema).decodeOutput(
     Buffer.from(finalResult.response_packet_data.result, 'base64')
   );
   console.log('RequestID: ' + requestId);
   console.log(result);
 } catch {
   console.error('Data request failed');
 }
};getBTCPrice();

Now let’s go through each section of the code.

Import the library and declare the necessary variables:

const BandChain = require('@bandprotocol/bandchain.js');
const { Obi } = require('@bandprotocol/obi.js');

The code requires two libraries:

Now, set the request parameters:

// BandChain devnet endpoint URL
const endpoint = 'http://guanyu-devnet.bandchain.org/rest';
// Mnemonic of the account to make the query from.
const mnemonic =
 'panther winner rain empower olympic attract find satoshi meadow panda job ten urge warfare piece walnut help jump usage vicious neither shallow mule laundry';// Request parameters
const bandchain = new BandChain(endpoint);
const oracleScript = await bandchain.getOracleScript(76);
const minCount = 3;
const askCount = 4;

Here we set the values that we will be using to make the request

  • endpoint: the endpoint we will make the query to

  • mnemonic: the mnemonic we will use to make the query. The associated account must have a balance to make a request

  • bandchain: contains the necessary functions we’ll need to make the request

  • oracleScript: object containing details of the oracle script we will be querying

  • minCount: the minimum number of BandChain’s validators that responds for us to consider the request successful

  • askCount: the maximum number of validators that we want to respond to the request

Now make the Oracle request and get the random hash:

const requestId = await bandchain.submitRequestTx(
   oracleScript,
   {
     symbol: 'BTC',
   },
   { minCount, askCount },
   mnemonic
 );
  // Get final result (blocking until the reports & aggregations are finished)
 const finalResult = await bandchain.getRequestResult(requestId);
 let result = new Obi(oracleScript.schema).decodeOutput(
   Buffer.from(finalResult.response_packet_data.result, 'base64')
 );
 console.log('RequestID: ' + requestId);
 console.log(result);

Finally, we execute the submitRequestTx member function of the previously declared bandchain object to make the oracle data request.

We can then do one of two things with regards to this request:

  • Call getRequestResult, as we did here, to get the actual result of the request

  • Call getRequestProof to get the proof bytes associated with the request

Both of these functions take in one argument, the requestID of the request you want to retrieve the result/proof from.

If the query is successful, the code should print a value similar to:

{ price: 11406282500000n },

which is the retrieved price of Bitcoin multiplied by 1 billion.

Using BandChain data in EVM Smart Contract in Harmony

Now that we know how to make a request to BandChain and retrieve the corresponding proof, we will now examine how we can use that proof in our smart contract.

The code below demonstrates an example contract that retrieves the latest price of Bitcoin from Band’s bridge contract and saves it onto the contract’s state:

pragma solidity 0.6.11;
pragma experimental ABIEncoderV2;import {Obi} from "./libraries/Obi.sol";
import {IBridge} from "./interfaces/IBridge.sol";
import {IBridgeCache} from "./interfaces/IBridgeCache.sol";
import "openzeppelin-solidity/contracts/math/SafeMath.sol";contract SimplePriceDB {
   using SafeMath for uint256;
   using ResultDecoder for bytes;
   using ParamsDecoder for bytes;IBridge bridge;
   IBridge.RequestPacket req;uint256 public price;constructor(IBridge bridge_) public {
        bridge = bridge_;req.clientId = "from_scan";
       req.oracleScriptId = 76;
       // {symbol:"BTC"}
       req.params = hex"00000003425443";
       req.askCount = 4;
       req.minCount = 4;
   }// getPrice fetches the latest BTC/USD price value from the bridge // contract and saves it to state.

   function getPrice() public {
      (IBridge.ResponsePacket memory res,) = bridge.getLatestResponse(req);
       ResultDecoder.Result memory result = res.result.decodeResult();
       price = result.px;
   }
}

Okay, now let’s break down the code.

import {Obi} from "./libraries/Obi.sol";
import {IBridge} from "./interfaces/IBridge.sol";
import {IBridgeCache} from "./interfaces/IBridgeCache.sol";
import "openzeppelin-solidity/contracts/math/SafeMath.sol";

Obi.sol

Decoders.sol

IBridgeCache.sol

Now let’s look at the contract itself:

contract SimplePriceDB {
   using SafeMath for uint256;
   using ResultDecoder for bytes;
   using ParamsDecoder for bytes;IBridge bridge;
   IBridge.RequestPacket req;uint256 public price;constructor(IBridge bridge_) public {
        bridge = bridge_;req.clientId = "from_scan";
       req.oracleScriptId = 76;
       // {symbol:"BTC"}
       req.params = hex"00000003425443";
       req.askCount = 4;
       req.minCount = 4;
   }// getPrice fetches the latest BTC/USD price value from the bridge // contract and saves it to state.   function getPrice() public {
      (IBridge.ResponsePacket memory res,) = bridge.getLatestResponse(req);
       ResultDecoder.Result memory result = res.result.decodeResult();
       price = result.px;
   }
}

The contract itself can then be further broken down into two parts: the constructor and the main getPrice function.

Contract Constructor

constructor(IBridge bridge_) public {
    bridge = bridge_;req.clientId = "from_scan";
   req.oracleScriptId = 76;
   // {symbol:"BTC"}
   req.params = hex"00000003425443";
   req.askCount = 4;
   req.minCount = 4;
}

The contract’s constructor takes one argument, the address of the bridge contract. It then sets the various fields of the req RequestPacket variable. This req variable will be what we will use as the key to match and retrieve the price from the bridge contract. Specifically, in this case, we set req to have the following parameters.

  • clientId (“from_scan”): the unique identifier of this oracle request, as specified by the client.

  • oracleScriptId (76): The unique identifier number assigned to the oracle script when it was first registered on Bandchain.

  • params (hex”00000003425443"): The data passed over to the oracle script for the script to use during its execution. In this case, it is hex representation of the OBI-encoded request struct

  • minCount (4): The minimum number of validators necessary for the request to proceed to the execution phase

  • askCount (4): The number of validators that are requested to respond to this request

getPrice Function

// getPrice fetches the latest BTC/USD price value from the bridge // contract and saves it to state.function getPrice() public {(IBridge.ResponsePacket memory res,) = bridge.getLatestResponse(req);ResultDecoder.Result memory result = res.result.decodeResult();price = result.px;}

This is then the main function that we will use to fetch the price from Band’s bridge contract and save it into our price database contract’s state. It calls the bridge contract’s getLatestResponse to retrieve the latest request response associated with a BTC/USD price request. It then uses Decoders.sol’s decodeResult method to parse that response into a struct. Finally, we save the price value from that response into the contract’s price variable.

References:

Examples

Requesting data using BandChain.js library

git clone https://github.com/harmony-one/band_oracle
cd band_oracle

yarn
node main.js

Using BandChain data in EVM Smart Contract in Harmony

git clone https://github.com/harmony-one/band_oracle
cd band_oracle

yarn
export PRIVATE_KEY=place your private key here
yarn hardhat run ./scripts/deploy.js

contract's been deployed and you can call getPrice or getMultiPrices to get actual prices

Band’s StdReference contract for testnet 0xE740092E081CA7491A46C8Aa0175446e962e2A08

mainnet contract is coming soon

: a helper library to assist us when encoding/decoding data to/from Band Protocol’s OBI standard

: the library that we’ll be using to make the queries to BandChain

Aside from OpenZeppelin’s , the contract we will be writing requires three helper files specific to Band’s oracle and bridge architecture: Obi.sol, Decoders.sol, and IBridgeWithCache.sol.

This contains a set of functions to help serialize and deserialize binary data when interacting with the BandChain ecosystem. The full standard specification can be found on their wiki and the code on the .

This is what we will use to work with data related to requests made on BandChain. This will help us in extracting the various information, such as the price value, we may need from the request response from Band’s oracle. The file is available from an oracle script’s bridge code tab on the devnet explorer. For this particular example, the code is available .

The interface file for Band’s bridge contract. The code for this can also be found on the BandChain .

bridge: the address of Band’s bridge contract on the blockchain this example contract is deployed to. See this for the chains that Band currently supports and corresponding contract addresses. You can deploy the bridge contract by yourself on the harmony chain. Bridge contract can be found .

Examples can be found here

🏗️
BandChain.js
@bandprotocol/obi.js
@bandprotocol/bandchain.js
SafeMath.sol
BandChain repository
here
repository
list
here
https://docs.bandchain.org/developer/dapp-integrations/requesting-data-from-bandchain.html#requesting-data-using-the-bandchain-js-library
https://docs.bandchain.org/developer/dapp-integrations/using-bandchain-data-evm.html
https://github.com/harmony-one/band_oracle
https://github.com/harmony-one/band_oracle/blob/main/main.js
https://github.com/harmony-one/band_oracle