# Oracle Process Flow

## Creating Oracle request

An **Oracle contract** can be deployed on the Ontology **network** to send Oracle **requests** and fetch **data** from outside world and make it **accessible** to other **smart contracts**.

{% hint style="info" %}
In the future, **all** the deployed Oracle contracts will be **listed** on the **Oracle market**
{% endhint %}

The sample **Oracle contract** that we will be looking at here fetches sports statistics, i.e., match details.

Let's say the address of an example Oracle contract is as follows:

#### Test net - e0d635c7eb2c5eaa7d2207756a4c03a89790934a

#### Main net - a6ee997b142b002d49670ab73803403b09a23fa0

The structure of the Oracle **request** is of the form:

### httpGet

```yaml
operation = "CreateOracleRequest"
request = """{
		"scheduler": {
			"type": "runAfter",
			"params": "2018-06-15 08:37:18"
		},
		"tasks": [
			{
			  "type": "httpGet",
			  "params": {
				"url": "https://bitstamp.net/api/ticker/"
			  }
			},
			{
				"type": "jsonParse",
				"params":
				{
					"data":
					[
						{
							"type": "String",
							"path": ["timestamp"]
						},
						{
							"type": "String",
							"path": ["last"]
						},
						{
							"type": "Float",
							"decimal": 100,
							"path": ["open"]
						}
					 ]
				}
			}
		]
	}"""
args = [request, address]
```

The **response** is as follows:

```yaml
{
	"high": "5610.00000000",
	"last": "5518.70",
	"timestamp": "1542359479",
	"bid": "5518.12",
	"vwap": "5436.78",
	"volume": "16423.18407040",
	"low": "5199.80000000",
	"ask": "5518.69",
	"open": 5571.12
}
```

**Parameters:** `url`, **URL** of the **GET** request

### JsonParse

**JsonParse** will parse the `http` response with the parameter path list as **key**. The result will then be serialized to form a data structure, as defined by the user, and then finally written in the Oracle contract.\
Here is a list of the parameters:

| Parameter | Description                                                                                                                                |
| --------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
| data      | Data structure defined by the user                                                                                                         |
| type      | Data type, support int, float(\* decimal as int), string, array, map, struct                                                               |
| sub\_type | Sub-type of the array, map and struct                                                                                                      |
| decimal   | decimal places of floating point value                                                                                                     |
| path      | Iterator list of **JSON** parse key, if data is `json`, write **key** in list, if data is **array**, write **index** as **string** in list |

Here's a complex **JsonParse** example:

```yaml
var request = """{
		"scheduler": {
			"type": "runAfter",
			"params": "2018-06-15 08:37:18"
		},
		"tasks": [
			{
			  "type": "httpGet",
			  "params": {
				"url": "http://data.nba.net/prod/v2/20181129/scoreboard.json"
			  }
			},
			{
				"type": "jsonParse",
				"params":
				{
					"data":
					[
						{
							"type": "Array",
							"path": ["games"],
							"sub_type":
							[
								{
									"type": "Struct",
									"sub_type":
									[
										{
											"type": "String",
											"path": ["gameId"]
										},
										{
											"type": "String",
											"path": ["vTeam", "teamId"]
										},
										{
											"type": "String",
											"path": ["vTeam", "score"]
										},
										{
											"type": "String",
											"path": ["hTeam", "teamId"]
										},
										{
											"type": "String",
											"path": ["hTeam", "score"]
										}
									]
								}
							]
						}
					]
				}
			}
		]
	}"""
```

A part of the raw `HTTP` response is:

```yaml
{
	"numGames": 3,
	"games": [{
			"gameId": "0021800316",
			"vTeam": {
				"teamId": "1610612744",
				"score": "128"
			},
			"hTeam": {
				"teamId": "1610612761",
				"score": "131"
			}
		},
		{
			"gameId": "0021800317",
			"vTeam": {
				"teamId": "2610612744",
				"score": "96"
			},
			"hTeam": {
				"teamId": "2610612761",
				"score": "131"
			}
		},
		{
			"gameId": "0021800318",
			"vTeam": {
				"teamId": "3610612744",
				"score": "128"
			},
			"hTeam": {
				"teamId": "3610612761",
				"score": "131"
			}
		}
	]
}
```

Here, the raw `HTTP` response is parsed and then a structure is created based on the data structure, which is then serialized.

An **application** smart **contract** calls the **Oracle contract** to fetch the result and then **deserializes** it as follows:

```yaml
[
    [
        ["0021800316", "1610612744", "128", "1610612761", "131"],
        ["0021800317", "2610612744", "128", "2610612761", "131"],
        ["0021800318", "3610612744", "128", "3610612761", "131"]
    ]
]
```

### Scheduler

This option is used to fix the time when a contract or task will be executed. It's format is as follows:

```yaml
{
    "type": "",
    "params": "",
}
```

Currently it only supports one execution method, **runAfter.**&#x20;

**runAfter** is used to specify a time when the task is to be run. For example, this can be used to send scores to the user after a game has ended. If the `type` field is left **empty**, the task will be run **immediately**. While the `params` field is used to specify the time in this format: **`YYYY-MM-DD HH:MM:SS`**\
Example - **"2018-06-15 08:37:18"**

### **httpPost**

The request format is as follows:

```yaml
operation = "CreateOracleRequest"
request = """{
        "scheduler": {
            "type": "runAfter",
            "params": "2018-06-15 08:37:18"
        },
        "tasks":[
            {
              "type": "httpPost",
              "params": {
                "url": "https://api.random.org/json-rpc/1/invoke",
                "contentType": "application/json-rpc",
                "body": "{\\"jsonrpc\\": \\"2.0\\",\\"method\\": \\"generateSignedIntegers\\",\\"params\\": {\\"apiKey\\": \\"c7511065-c88d-4f28-af4f-293c91ad20d9\\",\\"n\\": 6,\\"min\\": 1,\\"max\\": 10,\\"replacement\\": false,\\"base\\": 10},\\"id\\": 1}"
              }
            },
            {
                "type": "jsonParse",
                "params":
                {
                    "data":
                    [
                        {
                            "type": "Array",
                            "path": ["result", "random", "data"],
                            "sub_type":
                                [
                                    {
                                        "type": "Int"
                                    }
                                ]
                        }
                    ]
                }
            }
        ]
    }"""
args = [request, address]
```

The raw `HTTP` response is:

```yaml
{
    "jsonrpc": "2.0",
    "result": {
        "random": {
            "method": "generateSignedIntegers",
            "hashedApiKey": "oT3AdLMVZKajz0pgW/8Z+t5sGZkqQSOnAi1aB8Li0tXgWf8LolrgdQ1wn9sKx1ehxhUZmhwUIpAtM8QeRbn51Q==",
            "n": 6,
            "min": 1,
            "max": 6,
            "replacement": true,
            "base": 10,
            "data": [
                2,
                4,
                4,
                1,
                5,
                3
            ],
            "completionTime": "2013-09-30 14:58:03Z",
            "serialNumber": 69260
        },
        "signature": "BxHxajeRg7Q+XGjBdFS1c7wkZbJgJlverfZ5TVDyzCKqo2K5A4pD+54EMqmysRYwkL3w2NS2DFLVrsyO1o96bW9BGp5zjjrEegz9mB+04iOTaRwmdQnLJAj/m3WRptA+qzodPCTaqud8YWBifqWCM34q98XwjX+nlahyHVHT9vf5KO0YVkD/yRI1WN5M/qX21chVvSxhWdmIrdCkrovGnysFq8SzCRNhpYx+/1P+YT2IKsH8jth9z82IAz1ANVh918H/UdpuD1dR7TD6nk3ntRgGrIiu2qqVzFi8A7/6viVgRqtffE4KVZY6O9mUJ+sGkF5Ohayms7LHSFy1VC8wMbMgwod+A8nr5yzjAC4SCUkT1bKAyWNF3SdVcLtvWdcf97Ew6RjohzCW4Vs3jUlh6jF/pj3b3++U3lBHCh43IIonw8MQ7afwpqP12yvyDym1isNjhMKYjmzWRerSvnsMyQIH8xFW7IHt2g/0qnzJgABFmUNBRKJPCD9CMgjh60sSwW7EyrGMy7/qisfE0IU74P/F7KCty/g1jIlXX5/O1lQjwY34wnoP0NXL08QteukRZZUfJQnscx1NGE+HX1c9bMBI8LC0ZFYFk+uY6ib/0rCV5OcLLE9PihCdC8WoI1x3bobr8tbtfgnXMTjogxwVXiiSN1TMnTIWlJ+KM5eSWrw=",
        "bitsUsed": 16,
        "bitsLeft": 932400,
        "requestsLeft": 199991,
        "advisoryDelay": 1000
    },
    "id": 1
}
```

An application contract **deserializes** the result as follows:

```yaml
[
    [
        2,
        4,
        4,
        1,
        5,
        3
    ]
]
```

The `HTTP` post example above fetches a random number from **random.org.** This Ontology Oracle packages a more convenient method **`randomOrg`** to get a **signed random number**.

The request is as follows:

```yaml
operation = "CreateOracleRequest"
request = """{
        "scheduler": {
            "type": "runAfter",
            "params": "2018-06-15 08:37:18"
        },
        "tasks": [
            {
              "type": "randomOrg",
              "params": {
                "method": "GenerateSignedIntegers",
                "n": 10,
                "min": 1,
                "max": 10,
                "replacement": false
              }
            },
            {
                "type": "jsonParse",
                "params":
                {
                    "data":
                    [
                        {
                            "type": "Array",
                            "path": ["data"],
                            "sub_type":
                                [
                                    {
                                        "type": "Int"
                                    }
                                ]
                        },
                        {
                            "type": "String",
                            "path": ["signature"]
                        }
                    ]
                }
            }
        ]
    }"""
args = [request, address]
```

Here is the list of parameters:

| Parameter   | Description                                                                         |
| ----------- | ----------------------------------------------------------------------------------- |
| n           | Number of random numbers                                                            |
| min         | Lower limit for random numbers                                                      |
| max         | Upper limit for random numbers                                                      |
| replacement | **`true`**: random number can occur multiple times, **`false`**: numbers are unique |

The response is:

```go
type SignedIntegerData struct {
	Raw          json.RawMessage `json:"raw"`
	HashedApiKey string          `json:"hashedApiKey"`
	SerialNumber int             `json:"serialNumber"`
	Data         []int           `json:"data"`
	Signature    string          `json:"signature"`
}
```

**Unsigned random numbers** can also be generated as follows:

```yaml
operation = "{
        "scheduler": {
            "type": "runAfter",
            "params": "2018-06-15 08:37:18"
        },
        "tasks": [
            {
              "type": "randomOrg",
              "params": {
                "method": "GenerateIntegers",
                "n": 10,
                "min": 1,
                "max": 10,
                "replacement": false
              }
            },
            {
                "type": "jsonParse",
                "params":
                {
                    "data":
                    [
                        {
                            "type": "Array",
                            "path": ["data"],
                            "sub_type":
                                [
                                    {
                                        "type": "Int"
                                    }
                                ]
                        },
                        {
                            "type": "String",
                            "path": ["completionTime"]
                        }
                    ]
                }
            }
        ]
    }"""
args = [request, address]
```

| Parameter   | Description                                                                         |
| ----------- | ----------------------------------------------------------------------------------- |
| n           | Number of random numbers                                                            |
| min         | Lower limit for random numbers                                                      |
| max         | Upper limit for random numbers                                                      |
| replacement | **`true`**: random number can occur multiple times, **`false`**: numbers are unique |

The response is as follows:

```go
type IntegerData struct {
	Data           []interface{} `json:"data"`
	CompletionTime string        `json:"completionTime"`
}
```

## Result of Oracle request

The transaction hash `txhash` can be used to fetch the **result** of the on-chain Oracle **request**. The request format is:

```yaml
operation = "GetOracleOutcome"
args = txhash
```

## Sample Code

Please follow [**this**](https://github.com/ontio/ontology-oracle/blob/master/smartcontract/oracle.py) link to refer to **Oracle contract** template.

Please follow [**this**](https://github.com/ontio/ontology-oracle/blob/master/smartcontract/app.py) link to refer to an **application contract** that uses **Oracle**.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.ont.io/ontology-elements/oracle/oracle-process-flow.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
