navbar

Binance MarketData Oracle Docs

pragma solidity ^0.5.0;

import "./OracleAPI.sol";

/**
 * @title Example contract using MarketData oracle
 * @author TruSource
 * @notice Example contract using MarketData oracle
 * @dev Demonstrates usage of OracleAPI and building queryParams
 */
contract Example is OracleAPI {
    event LogResult(bytes32 queryId, Oracle.Oracle.Operations operationId, uint256 statusCode, string result);

    constructor(address resolverAddress) public OracleAPI (resolverAddress) public {}

    /**
     * @notice Make getAvgPrice query
     * @dev Make getAvgPrice query, queryId is returned to be used to handle query result
     */
    function getAvgPrice() external {
        trusource_getAvgPrice("BATBTC");
    }

    /**
     * @dev Handle query result using queryId, operationId and statusCode
     * @param queryId unique id for query
     * @param operationId id for operation
     * @param statusCode HTTP response status code
     * @param result query result
     */
    function trusource_callback(
        bytes32 queryId,
        Oracle.Oracle.Operations operationId,
        uint256 statusCode,
        string calldata result
    ) external checkAddress checkQueryId(queryId) {
        if (operationId == Oracle.Oracle.Operations.getAvgPrice) {
            emit LogResult(queryId, operationId, statusCode, result);
            return;
        }
    }
}

MarketData have partnered with TruSource to provide users with data on the Ethereum blockchain. Users can access data from MarketData endpoints detailed in these docs by signing up for MarketData via the TruSource website.

Dependencies

Before starting ensure the following requirements are met.

Example Project

To start, clone the MarketData example truffle project. Alternatively use the MarketData truffle box, ensure you are in a new and empty directory and run the following

truffle unbox TruSource/Binance-MarketData

Looking at the project, the contract, Example.sol, demonstrates the usage of the operations exposed by the oracleAPI.sol. A reduced version of Example.sol is shown on the right, the getAvgPrice function uses the getAvgPrice operation by calling the trusource_getAvgPrice function defined in OracleAPI.sol.

Do it Yourself

When writing a contract that uses the MarketData oracle, several important conditions have to be met.

Firstly, the contract should inherit the OracleAPI.

contract Example is OracleAPI

The constructor should accept a resolver address argument which is passed to the base contract using a OracleAPI modifier.

constructor(address resolverAddress) OracleAPI (resolverAddress) public {}

The contract must then implement a trusource_callback method.

function trusource_callback(bytes32 queryId, Oracle.Oracle.Operations operationId, uint256 statusCode, string calldata result) external checkAddress checkQueryId(queryId)

The implementation should use the checkAddress and checkQueryId(queryId) modifiers.

Callback Function

The trusource_callback method is called by TruSource, with the query return passed as one of the arguments.

trusource_callback(bytes32 queryId, Oracle.Oracle.Operations operationId, uint256 statusCode, string calldata result) external checkAddress checkQueryId(queryId)

Parameter Description
queryId Unique id to identify each query
operationId Unique id to identify each operation
statusCode HTTP status code
result API call response as string

Optional Query Parameters

/**
 * @notice Make getAvgPrice query
 * @dev Make getAvgPrice query, queryId is returned to be used to handle query result
 */
function getAvgPrice() external {
    trusource_getAvgPrice("BATBTC");
}

Some operations will allow for optional query parameters. Mutable byte buffers are used and query parameter keys and values are CBOR encoded using the solidity-cborutils library.

Use the addString or addUInt helpers to construct the query parameter buffer.

For example, lets assume the getAvgPrice operation allows optional query parameters. To construct the query parameters ?paramString=test&paramInt=1, first initialise a buffer variable.

Buffer.buffer memory queryParams = createBuffer();

Then add the keys and values.

addString(queryParams, "paramString", "test");

addUInt(queryParams, "paramInt", 1);

Options String

An options string can be passed along with a call to every operation. The format of the string is as follows

identifier/options

The following identifiers are currently supported.

identifier Description
json Parse json response
fixedNum reformat floating point return as fixed number

Multiple options can be specified. For example, both response parsing and a fixed number response:

json/parse.json.response/fixedNum/4

Response Parsing

Example response

{
  "posts": [
    {
      "id": 1,
      "title": "hello",
      "rating": 4.75
    }
  ],
  "profile": {
    "name": "typicode"
  }
}

This is useful when an operation returns a json response and a single value is required in the contract. Take the example response on the right as an example.

Assuming the title of the first post is required, the option string would be constructed as

json/posts.0.title

Fixed point number response

Solidity does not yet support floating point numbers, fixed point number representations are commonly used instead within smart contracts. When constructing the string pass an integer to represent decimal multiplier.

For example, if the following options string was used for the example response (4.75)

json/posts.0.rating/fixedNum/2

The response would be "475". The parseInt can then be used to parse the string as a uint256.

Local Testing

The MarketData example and any user projects using the MarketData oracle can be tested locally with a local server that can mimic the TruSource servers that will fetch and respond with data to contracts running on local ganache blockchains.

  1. Start an Ethereum client. We will use ganache-cli.

    npx ganache-cli

    Note: the client needs to support WebSockets (do not use truffle develop for this reason).

    For other options, see Truffle - Choosing an Ethereum client.

  2. Migrate the smart contracts, in a 2nd terminal

    truffle migrate

  3. Start the TruSource local server. It will listen for events, fetch and return data to requesting contracts.

    npm start

  4. Using the provided Truffle script ./server/calls.js, call functions in Example.sol. This will execute a set of contracts calls, testing each operation with provided example arguments. In a 3rd terminal

    truffle exec server/calls.js

Network Testing

ropsten migrations

const yourContract = artifacts.require("yourContract");

module.exports = (deployer, network) => {
  if (network === "ropsten") {
    const resolverAddress = "0x4b76334b90866335c4878b278c89226b38c9f116";
    deployer.deploy(yourContract, resolverAddress);
  }
};
network Resolver Address Oracle Address
ropsten 0x4b76334b90866335c4878b278c89226b38c9f116 0x6b8c6c5ae9b9f67d85a6bcdc972f5b98c238463b

The MarketData oracle is currently deployed on the networks shown in the table.

To use the MarketData oracle on a given network, you must deploy your contract and provide the resolver address as a constructor argument.

For all contract calls that make a call to the MarketData oracle, Trusource will make a call to the trusource_callback function in your contract with the result.

The truffle migrations for ropsten is demonstrated.

To deploy your contract to a live network, update the migrations as shown, a do the following within the MarketData truffle box:

  1. Uncomment line 4 to 12 in truffle-config.js.

  2. Set the SEED_PHRASE (mnemonic) and ETHEREUM_RPC_URL environment variables in .env.

  3. Migrate the contracts.

    truffle migrate --network <network-name>

  4. Whitelist the contract that will call the MarketData API at trusource.io.

Operations

getAvgPrice

/**
 * @notice Make getAvgPrice query
 * @dev Make getAvgPrice query, queryId is returned to be used to handle query result
 */
function getAvgPrice() external {
    trusource_getAvgPrice("BATBTC");
}

OracleAPI Method

trusource_getAvgPrice(string memory symbol)

trusource_getAvgPrice(string memory symbol ,string memory options)

trusource_getAvgPrice(string memory symbol ,Buffer.buffer memory optionalQueryParams)

trusource_getAvgPrice(string memory symbol ,Buffer.buffer memory optionalQueryParams, string memory options)

Operation Query Parameters

Optional query parameters need to be CBOR encoded and be passed as a bytes array. See optional query parameters for more details.

Parameter Required
symbol true

Options

An options string can be provided, see options string for more details.

getDepth

/**
 * @notice Make getDepth query
 * @dev Make getDepth query, queryId is returned to be used to handle query result
 */
function getDepth() external {
    Buffer.buffer memory optionalQueryParams = createBuffer();

    // Optional
    addUInt(optionalQueryParams, "limit", 5);

    trusource_getDepth("BATBTC", optionalQueryParams);
}

OracleAPI Method

trusource_getDepth(string memory symbol)

trusource_getDepth(string memory symbol ,string memory options)

trusource_getDepth(string memory symbol ,Buffer.buffer memory optionalQueryParams)

trusource_getDepth(string memory symbol ,Buffer.buffer memory optionalQueryParams, string memory options)

Operation Query Parameters

Optional query parameters need to be CBOR encoded and be passed as a bytes array. See optional query parameters for more details.

Parameter Required
symbol true
limit false

Options

An options string can be provided, see options string for more details.

getTicker24hr

/**
 * @notice Make getTicker24hr query
 * @dev Make getTicker24hr query, queryId is returned to be used to handle query result
 */
function getTicker24hr() external {
    Buffer.buffer memory optionalQueryParams = createBuffer();

    // Optional
    addString(optionalQueryParams, "symbol", "BATBTC");

    trusource_getTicker24hr(optionalQueryParams);
}

OracleAPI Method

trusource_getTicker24hr()

trusource_getTicker24hr(string memory options)

trusource_getTicker24hr(Buffer.buffer memory optionalQueryParams)

trusource_getTicker24hr(Buffer.buffer memory optionalQueryParams, string memory options)

Operation Query Parameters

Optional query parameters need to be CBOR encoded and be passed as a bytes array. See optional query parameters for more details.

Parameter Required
symbol false

Options

An options string can be provided, see options string for more details.

getBookTicker

/**
 * @notice Make getBookTicker query
 * @dev Make getBookTicker query, queryId is returned to be used to handle query result
 */
function getBookTicker() external {
    Buffer.buffer memory optionalQueryParams = createBuffer();

    // Optional
    addString(optionalQueryParams, "symbol", "BATBTC");

    trusource_getBookTicker(optionalQueryParams);
}

OracleAPI Method

trusource_getBookTicker()

trusource_getBookTicker(string memory options)

trusource_getBookTicker(Buffer.buffer memory optionalQueryParams)

trusource_getBookTicker(Buffer.buffer memory optionalQueryParams, string memory options)

Operation Query Parameters

Optional query parameters need to be CBOR encoded and be passed as a bytes array. See optional query parameters for more details.

Parameter Required
symbol false

Options

An options string can be provided, see options string for more details.

getTickerPrice

/**
 * @notice Make getTickerPrice query
 * @dev Make getTickerPrice query, queryId is returned to be used to handle query result
 */
function getTickerPrice() external {
    Buffer.buffer memory optionalQueryParams = createBuffer();

    // Optional
    addString(optionalQueryParams, "symbol", "BATBTC");

    trusource_getTickerPrice(optionalQueryParams);
}

OracleAPI Method

trusource_getTickerPrice()

trusource_getTickerPrice(string memory options)

trusource_getTickerPrice(Buffer.buffer memory optionalQueryParams)

trusource_getTickerPrice(Buffer.buffer memory optionalQueryParams, string memory options)

Operation Query Parameters

Optional query parameters need to be CBOR encoded and be passed as a bytes array. See optional query parameters for more details.

Parameter Required
symbol false

Options

An options string can be provided, see options string for more details.

getTrades

/**
 * @notice Make getTrades query
 * @dev Make getTrades query, queryId is returned to be used to handle query result
 */
function getTrades() external {
    Buffer.buffer memory optionalQueryParams = createBuffer();

    // Optional
    addUInt(optionalQueryParams, "limit", 1);

    trusource_getTrades("BATBTC", optionalQueryParams);
}

OracleAPI Method

trusource_getTrades(string memory symbol)

trusource_getTrades(string memory symbol ,string memory options)

trusource_getTrades(string memory symbol ,Buffer.buffer memory optionalQueryParams)

trusource_getTrades(string memory symbol ,Buffer.buffer memory optionalQueryParams, string memory options)

Operation Query Parameters

Optional query parameters need to be CBOR encoded and be passed as a bytes array. See optional query parameters for more details.

Parameter Required
symbol true
limit false

Options

An options string can be provided, see options string for more details.

OracleAPI

Helper functions enabling the use of optional query parameters for some operations and response parsing are provided.

addInt

CBOR encode a string key and uint value pair and add to buffer.

addUint(Buffer.buffer memory param, string memory key, string memory value)

Parameter Description
param buffer object to which the encoded key and value will be added to
key query parameter key of type string
value query parameter value of type uint

addString

CBOR encode a string key and string value pair and add to buffer.

addString(Buffer.buffer memory param, string memory key, string memory value)

Parameter Description
param buffer object to which the encoded key and value will be added to
key query parameter key of type string
value query parameter value of type string

parseInt

Parse a the string response within trusource_callback as uint256.

parseInt(string memory str)

Parameter Description
str string representation of uint

createBuffer

Initialises and returns buffer set to defaultBufferSize of 256.

createBuffer()