To get external data (oracle data) from a custom chaincode, users must perform a cross-chaincode call to Spydra’s oracle chaincode which acts as an interface to the oracle services that Spydra offer.
Spydra’s oracle chaincode is deployed with a constant name oracle.
If you have created multiple channels in your network and have created oracles for those channels as well, then the first deployed oracle chaincode's name is oracle , the deployed oracle chaincode's name is oracle1 and so on.
The chaincode name of a particular oracle can always be found on the oracle descriptions or list page. You can reach the oracle listing page by clicking Oracle tab in the Network page.
It has a OracleRequest function that accepts the following json data as input
{ oracleSetId: string; // The oracle id found on UI params: any; // query/path/body params of the defined oracle - this can be an object or string or empty}
To make a cross chaincode call from HLF chaincode, stub.InvokeChaincode api can be used. stub.InvokeChaincode accepts 3 parameters:
1. chaincodeName (string)
2. args ([][]byte or Array.<Array.<byte>> or array of array of bytes)
3.channel (string)
The first element of args must contain the function name of the calling chaincode.
Further elements of args can contain the actual arguments of the function.
Example: To request external data from above defined oracle
// ToChaincodeArgs converts string args to []byte argsfuncToChaincodeArgs(args ...string) [][]byte { bargs :=make([][]byte, len(args))for i, arg :=range args { bargs[i] = []byte(arg) }return bargs}// My chaincode functionfunc (s *SmartContract) MyCustomFunction(ctx contractapi.TransactionContextInterface) (output string, err error) { stub := ctx.GetStub() txId := stub.GetTxID()var oracleRequestParams string=`{"oracleSetId":"64e8bc2c4708667b390d8694","params":{"q":"Texas"}}` chaincodeArgs := util.ToChaincodeArgs("OracleContract:OracleRequest", oracleRequestParams)// Request external data (oracle) response := stub.InvokeChaincode("oracle", chaincodeArgs, "") // channel parameter can be left empty fmt.Println("ORACLE RESPONSE: ", response.Status, response.Message, string(response.Payload))if response.Status !=200 { err = fmt.Errorf(string(response.Message))return } dataBytes := response.GetPayload()// Save to blockchain state err = stub.PutState(txId, dataBytes)if err !=nil { fmt.Println(err)return } output =string(dataBytes)return}
Oracle Scheduler
A scheduled oracle retrieves data from the API configured in the oracle definition and calls the chaincode function as configured in the APPLICATION section of the oracle scheduler config.
The scheduler calls the chaincode function with the following argument:
{ oracleCronId: string; // The internal oracle cron scheduler id refId: string; // Reference id for this scheduled transaction data: any; // Response given by API configured in oracle}
Example: To receive data from the oracle scheduler