Onchain Oracle Template

Here we provider an example of an onchain provider interface for use in deploying multiparty oracles or wrapping arbitrary onchain logic

pragma solidity ^0.4.24;

import "../ownership/ZapCoordinatorInterface.sol";
import "../../platform/dispatch/DispatchInterface.sol";
import "../../platform/registry/RegistryInterface.sol";
import "./OnChainProvider.sol";


contract SampleOnChainOracle is OnChainProvider, Ownable {

    event RecievedQuery(string query, bytes32 endpoint, bytes32[] params);

    ZapCoordinatorInterface coord;
    RegistryInterface registry;
    DispatchInterface dispatch;

    //initialize provider
    constructor(
        address coordinator, 
        uint256 providerPubKey,
        bytes32 providerTitle 
    ){
        coord = ZapCoordinatorInterface(coordinator); 

        RegistryInterface registry = RegistryInterface(coord.getContract("REGISTRY")); 
        registry.initiateProvider(providerPubKey, providerTitle);
    }

    //initialize an endpoint curve
    function initializeCurve(
        bytes32 specifier, 
        int256[] curve
    ) onlyOwner public returns(bool) {
        
        RegistryInterface registry = RegistryInterface(coord.getContract("REGISTRY")); 
        require(registry.isProviderInitiated(address(this)), "Provider not intiialized");

        return registry.initiateProviderCurve(specifier, curve, address(0));
    }

    function setProviderParameter(bytes32 key, bytes value) onlyOwner public {

        registry = RegistryInterface(coord.getContract('REGISTRY'));
        registry.setProviderParameter(key, value);
    }

    function setEndpointParams(bytes32 endpoint, bytes32[] endpointParams) onlyOwner public {

        registry = RegistryInterface(coord.getContract('REGISTRY'));
        registry.setEndpointParams(endpoint, endpointParams);
    }

    // middleware function for handling queries
    function receive(uint256 id, string userQuery, bytes32 endpoint, bytes32[] endpointParams, bool onchainSubscriber) external {

        emit RecievedQuery(userQuery, endpoint, endpointParams);
        
        dispatch = DispatchInterface(coord.getContract('DISPATCH'));
        if(onchainSubscriber && msg.sender == address(dispatch)) {

          //Do something
          dispatch.respond1(id, "Hello World");

        } 
        // else: Do nothing (onchain only)
    }

}

Constructor

This function takes in the Zap Coordinator, as well as the intended Public Key and Title. It then calls Zap's registry contract to add the smart contract into Zap's database as a new oracle.

Initialize Curve

This is where the smart contract sets up the pricing curve for the oracle and initializes an endpoint. For more information on how to set up the array the contract takes in as a parameter, look at the Curve Encoding section. You will notice that at the beginning, registry is redefined by the Zap Coordinator. This is in case the Zap contract has updated. The coordinator will fetch the updated address and use that for future reference

Set Provider Parameter

Sets any key:value pair for the provider, which is normally some asset that needs to be known by the subscriber.

Set Endpoint Params

Sets up the endpoint parameters for the endpoint. These parameters will determine how the oracle will retrieve an answer for queries made to the smart contract.

Receive

The way that Zap's dispatch contract calls on the oracle contract. Parameters for this function are standardized. Similar to the registry contracts, the dispatch contract in this contract is updated whenever the receive function is called. Eventually after the receive function is called, the contract should generate an answer for the query and call dispatch.respond(). It should be noted that the response types are from 1 to four strings, an integer array, or a bytes32 array.

Last updated