navbar

ApiDojo LiveScore Oracle Docs

pragma solidity ^0.5.0;

import "./OracleAPI.sol";

/**
 * @title Example contract using LiveScore oracle
 * @author TruSource
 * @notice Example contract using LiveScore 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 getLeagues query
     * @dev Make getLeagues query, queryId is returned to be used to handle query result
     */
    function getLeagues() external {
        trusource_getLeagues("soccer");
    }

    /**
     * @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.getLeagues) {
            emit LogResult(queryId, operationId, statusCode, result);
            return;
        }
    }
}

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

Dependencies

Before starting ensure the following requirements are met.

Example Project

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

truffle unbox TruSource/ApiDojo-LiveScore

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 getLeagues function uses the getLeagues operation by calling the trusource_getLeagues function defined in OracleAPI.sol.

Do it Yourself

When writing a contract that uses the LiveScore 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 getLeagues query
 * @dev Make getLeagues query, queryId is returned to be used to handle query result
 */
function getLeagues() external {
    trusource_getLeagues("soccer");
}

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 getLeagues 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 LiveScore example and any user projects using the LiveScore 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

Authentication

The LiveScore operations require authentication, an .env-template file will be found at the root of the truffle project, rename this file to .env and populate the following environment variables

X-RAPIDAPI-KEY

Sign up for the free tier of LiveScore API to acquire the credentials.

Network Testing

ropsten migrations

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

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

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

To use the LiveScore 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 LiveScore 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 LiveScore 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 LiveScore API at trusource.io.

Operations

getLeagues

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

OracleAPI Method

trusource_getLeagues(string memory category)

trusource_getLeagues(string memory category ,string memory options)

trusource_getLeagues(string memory category ,Buffer.buffer memory optionalQueryParams)

trusource_getLeagues(string memory category ,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
category true

Options

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

getMatchesDetail

/**
 * @notice Make getMatchesDetail query
 * @dev Make getMatchesDetail query, queryId is returned to be used to handle query result
 */
function getMatchesDetail() external {
    trusource_getMatchesDetail("soccer", 3065852, 1);
}

OracleAPI Method

trusource_getMatchesDetail(string memory category, uint256 id, uint256 p)

trusource_getMatchesDetail(string memory category ,uint256 id ,uint256 p ,string memory options)

trusource_getMatchesDetail(string memory category ,uint256 id ,uint256 p ,Buffer.buffer memory optionalQueryParams)

trusource_getMatchesDetail(string memory category ,uint256 id ,uint256 p ,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
category true
id true
p true

Options

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

getTable

/**
 * @notice Make getTable query
 * @dev Make getTable query, queryId is returned to be used to handle query result
 */
function getTable() external {
    trusource_getTable("soccer", 3065852, 1);
}

OracleAPI Method

trusource_getTable(string memory category, uint256 id, uint256 p)

trusource_getTable(string memory category ,uint256 id ,uint256 p ,string memory options)

trusource_getTable(string memory category ,uint256 id ,uint256 p ,Buffer.buffer memory optionalQueryParams)

trusource_getTable(string memory category ,uint256 id ,uint256 p ,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
category true
id true
p true

Options

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

getMatchesByDate

/**
 * @notice Make getMatchesByDate query
 * @dev Make getMatchesByDate query, queryId is returned to be used to handle query result
 */
function getMatchesByDate() external {
    trusource_getMatchesByDate("soccer", "2019-08-04");
}

OracleAPI Method

trusource_getMatchesByDate(string memory category, string memory date)

trusource_getMatchesByDate(string memory category ,string memory date ,string memory options)

trusource_getMatchesByDate(string memory category ,string memory date ,Buffer.buffer memory optionalQueryParams)

trusource_getMatchesByDate(string memory category ,string memory date ,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
category true
date true

Options

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

getMatchesLeague

/**
 * @notice Make getMatchesLeague query
 * @dev Make getMatchesLeague query, queryId is returned to be used to handle query result
 */
function getMatchesLeague() external {
    trusource_getMatchesLeague("soccer", "england");
}

OracleAPI Method

trusource_getMatchesLeague(string memory category, string memory league)

trusource_getMatchesLeague(string memory category ,string memory league ,string memory options)

trusource_getMatchesLeague(string memory category ,string memory league ,Buffer.buffer memory optionalQueryParams)

trusource_getMatchesLeague(string memory category ,string memory league ,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
category true
league true

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()