How to create an oracle for your own blockchain?

What is a blockchain oracle?

An oracle is a third-party source of information that you (have to) trust. The oracle can submit information to your blockchain. This information can then be used to execute a business logic, based on predefined conditions, programmed in your smart contract. 

What types of oracles are there?

There are at least 5 different types of oracles, all with different functions or characteristics, which can be created for your own blockchain. With any oracle pushing data, you can let a cron smart contract self-execute on one (or more blockchains with Interchain), based on pre-defined code. The frequency can be set on any cadence from every minute, only on certain days of the week or month, and everything in between.

Software oracles or deterministic oracles.  

This type of oracle is the most well known and most used. It is a single source data feed that can integrate with a smart contract to create transactions based on predefined rules. If you decide that you trust the data coming from an oracle you intend to use, then you can go for the deterministic oracle, providing data quickly from the outside world to the digital world, executing predefined code in your smart contract. 

Hardware Oracles 

Hardware oracles can be RFID tags and sensors inside cars or products, or any other type of hardware sending information from the physical world to the digital world. Take for example Knowledge Perk, using Dragonchain’s technology to put roast data points on the blockchain. The application was built and used inside the store within 4 days. The roast data points are obtained through IoT devices inside the coffee roaster, then stored on the blockchain. This allows customers to see the entire roasting process. It’s a way for Knowledge Perk to use blockchain technology to differentiate their services from other coffee chains like Starbucks and Woods coffee. By scanning the QR code on the packaging, anyone buying coffee at Knowledge Perk can see all of this decentralized and immutable data. Whether you make wine, own a beer brewery, grow flowers and plants, or are responsible for water management in your local town or state. With (hardware) oracles you can quickly get all of that data on chain. In a matter of minutes with our blockchain platform, as you can see in the oracle demo further down this article. 

Inbound oracles

Inbound oracles supply external data to a smart contract. A news website providing us with the latest weather forecasts and current temperature is an inbound oracle. We could also find examples in games such as Pokemon Go. Based on our GPS activity, the game determines whether we walked enough distance to hatch our eggs. Pokemon Go added some restrictions to prevent gaming the system, such as the maximum speed that we are allowed to walk. If we walk too fast, or use a scooter or a car, the distance we’ve traveled will not be added to the required distance to hatch an egg. For this, the Pokemon Go team must rely on external sources such as GPS. They must trust the data points and find more secure and non-tamperable ways to monitor our activity.

Outbound Oracles 

Outbound oracles communicate data from smart contracts to an external network or blockchain. The smart contract itself can act as an outbound oracle. As an example we can use Dragonchain’s Wyrm Holes to show a combination of both outbound and inbound oracles used in an innovative solution for cross-chain token transfers. In the following use case, native Ethereum (ERC20) tokens are sent from the Ethereum blockchain (ETH) into a Wyrm Hole and sent out as foreign tokens to the NEO blockchain. 

A user sends tokens to the Wyrm Hole address on Ethereum. The ETH watcher sends the transaction to the Wyrm Hole contract. The Wyrm Hole contract validates the transaction and credits the user account. The user selects the NEO blockchain to send tokens to. The Wyrm Hole contract validates and publishes the transaction to the NEO blockchain, minting tokens. The NEO publisher invokes the Wyrm Hole contract; confirming the transaction is complete then debiting the user account.

Consensus-based Oracles

In contrast to software oracles, consensus-based oracles do not use a single source. There are several ways to create and use decentralized oracles. One would be a rating system inside a prediction market. To reduce risk and provide more security, a combination of oracles might be used. For example you could take the average of 5 oracles. Or, 5 out of 7 oracles can determine the outcome of an event. Consensus-based oracles are slower, only because it takes more time to reach consensus. If we can not trust an oracle that gives us the  information we need, or if we are not certain of the accuracy at all times, a slightly safer path may be through consensus-based oracles. Especially if there exists a large sum of money or legal ramifications behind it.

Why oracles require trust. 

The biggest and possibly only disadvantage regarding use of an oracle is the requirement we trust them and their maintainers. The Oracle Problem is defined as the security, authenticity, and trust conflict between third-party oracles and their trustless execution of smart contracts. The digital world needs to communicate with the physical world. Dragonchain might be the preferred blockchain platform to connect the outside world with blockchain, in a way that smart contracts may utilize data residing in legacy systems.

The conflict between third-party oracles and the execution of smart contracts is not a serious problem for every blockchain application. It only requires specific workarounds and precautionary measures for certain use cases, depending on the instance. Consensus-based oracles reduce risk, but one solution does not fit all issues. Is it even possible to completely remove the issue of trust with oracles, similar to Satoshi solving the double spend problem? In our Telegram community, a member asked this question:

“With Dragonchain the capability to create your own oracles is essentially built right into the platform. Isn’t the problem with this that you have to trust the oracle and the API? what if the company changes the API to screw with your contract? I thought that was the problem Chainlink solved; that you didn’t have to trust the oracle and API?”

We assume he refers to a regular software / deterministic 3rd party oracle, and so if anyone changes the API of this oracle, it requires us to update it in our smart contract too. This is the same with Chainlink. The data source (oracle/API) needs to provide correct information at all times, no matter what blockchain reads it. This is something neither Chainlink or Dragonchain can solve, as we don’t control all the oracles and APIs (and the data they submit) in the world. We don’t want to control all oracles or APIs. It is based on trust, and truthfully there might be complications in smart contracts if an oracle / API returns inaccurate or manipulated data. But there exist workarounds to reduce this risk too, all requiring further investment (more sources, such as sensors or RFID chips), more coding (smart contracts, consensus, Interchain) or more decentralisation. If we think about it (others have frequently in various articles), smart contracts are actually dumb contracts set to follow rules they were created to satisfy, assuming there are no bugs.

To better understand, we found the following example on Mycryptopedia while deeper researching the topic.

“Conversely, a possible remedy for this problem would be to request data from multiple oracles as opposed to a single one. If an oracle returned a temperature reading of 24 °C, but 4 other oracles returned a value of 18 °C, additional conditions could be programmed into the smart contract to resolve the conflict. The smart contract may choose to accept only the majority value, in this case 18 °C, which would result in Bob being the victor of the wager. On the other hand, the smart contract can be programmed to not execute at all, therefore requiring the intervention of both Alice and Bob.”

Now let’s get back to our weather theme for more inspiration. Let’s look at a real world example. Just a few days ago in The Netherlands, a weather API from a local town pushed out wrong data. It pushed out a record high of 41.7 °C during a heat wave, making the news. However it was inaccurate. The Netherlands only uses a single automated weather station per location (and a backup if one goes out, but the backup doesn’t participate unless this happens). So as a result we saw an unwelcome and inaccurate sudden spike in temperature. We would need three or more weather stations on every position to mitigate this issue, rather than one. But even with three or more weather stations, someone might still hypothetically manipulate them all, since they are in the same position/spot. Ultimately this would result in non-execution of the smart contract, or execution and placement of data on chain, inaccurately, as we saw then. (It was not actually put on chain, we use it only as a hypothetical example.)

If we use three or more weather stations, as they are in the exact same spot, someone could theoretically use a flamethrower or light up a barbeque in order to heat things up a bit, grabbing the new heat record first. Still this requires real humans to fact-check, or robots/drones, or camera surveillance… Anyways, blockchain is unable to solve every error humans or executable code might cause. A blockchain records what it receives, not whether or not the data is accurate. Smart contracts executing based on data received might provoke some serious complications for use cases outside of weather oracles.

In the Netherland’s case, it is thought to have been a military aircraft causing the temporary spike in temperature, flying near the weather station, around the moment the API recorded and transmitted the current temperature. Even after adding more weather stations to the same spot, all stations would all have recorded this spike. Unless we spread them out (decentralize them) a bit more, issues will continue to arise, as this changes the way they record temperatures. By taking the average of three weather stations spread out over a larger area, it is no longer comparable to current weather history, as this was measured differently; from one source only.

Trust and the single point of failure in oracles.

Let us for a moment assume one chose to use Chainlink to host decentralized blockchain oracles. While Chainlink may be an interesting project (which Dragonchain may strongly consider to Interchain with in the future), Chainlink is not a one-stop solution for all. And it certainly is not the first or only enabling one to use an oracle to on-chain and decentralize data. In fact, very simply put, Chainlink operates as a layer or middleman between let’s say, Google’s BigQuery and Ethereum. Similar to Dragonchain, one might connect smart contracts with key external resources such as off-chain data and APIs.The Chainlink network allows multiple independent nodes to perform decentralized computations in attempt to trace/calculate the accuracy of external input, before it is written to a smart contract.

Even this does not solve an oracle’s innate issue; an oracle requires trust. Remember the example of the weather station. Each oracle requires a specific solution to its problem, and not all problems are solved with the same solution. For example Augur is a decentralized oracle and prediction market protocol built on the Ethereum blockchain. You can forecast events and be rewarded for predicting them correctly, which is very interesting. Chainlink aims to solve trust issues with oracles (a single point of failure) by providing trustless and decentralized oracles. This works to some extent for a portion of their decentralized oracles currently operating. However, again, in the above example involving weather stations, we would still always have to trust their oracles, whether they are actually in control of the feed or not. Whether the data obtained is decentralized or not, whether a network of nodes agree to come to consensus, these are interesting questions.

Ideally the solution should start at the source. This solution exists pre-attached to the complications mentioned above. The physical weather station is a single point of failure, as proven in recent days in the Netherlands. We can start taking the average of 3 weather stations, spread out over a larger area. But then it isn’t possible to compare to any weather history, because that was measured quite differently. One source per location only, in one spot, spread out over a larger area.

To further demonstrate this point while providing an additional example, we ought to make things a bit more complicated. Let’s say company X decides to utilize three or more weather stations. X might take the average of those three weather stations. Or X might opt for the consensus-based solution; whereby at least two of the three weather stations must provide the same data for anything to be evaluated as valid.

Whether or not the oracle indeed provides the correct data, we must still somehow trust that company X has not tampered with it. Perhaps we should have three different companies in the exact same locations, each with their own three weather stations. In some way they acquire consensus with the data from all nine weather stations. For the weather, it may not be important enough to go this far. But what if millions, billions, or trillions of dollars worth of cryptocurrencies were at risk?

This brings us to the next example, with a little help from TwiceCrypto, who published an article regarding Chainlink on Publish0x, named ‘is the shilling of Chainlink justified’? This was not an attack on Chainlink, since the article was written in Chainlink’s favor. We encourage any developer or blockchain enthusiast to Do their Own Research; innovate with Chainlink, with Dragonchain, or all together. We’d like to further adoption and blockchain’s potential, adding oracles into the mix.

A case study in that article we’d enjoy discussing examines the relationship between Synthetix and Chainlink. Synthetix is a small cryptocurrency exchange partnered with Chainlink aiming to further decentralize price feed oracles. Synthetix allows anyone to build and run an oracle in order to obtain price feeds for synthetic assets, referred to as Synths. Each Synth relies on a variety of price feeds in order to maintain a stable price. These feeds are crucial for their network to operate accurately and efficiently.

“Currently, the Synthetix team controls all the price oracles.. and the nature of the oracle is kept secret to prevent manipulation or attacks on the integrity of the price oracle. We as users of the exchange have to trust that the oracle used provides correct information regarding price.. and we’re constantly updating it with 100% uptime.” The team is aware of their inbuitl weakness. They plan to decentralize price feeds by allowing people to run Chainlink nodes, in order to supply price feeds for the exchange. Along with a variety of price feeds, the node operators are financially incentivized to provide consistent honesty. “The price of each synthetic asset will be more accurate in comparison to the real-time market price”, wrote TwiceCrypto.

While this may minimize risk, it does not solve the core issue; that is, oracles rely on the data decentralized feeds provide. Whether willingly or unwillingly, all nodes can still reach consensus on the price provided by the oracles, even if proven as inaccurately provided. Decentralized or not, it is still possible to manipulate, and so long or short Bitcoin. Beside this, experiencing some order submission error because ‘the system is currently overloaded’, (which Bitmex users certainly have experience with) is not fun. There exists no decentralized oracle to protect us from this.

This further proves the double spend problem solved by the invention of Bitcoin by Satoshi Nakamoto.Trustless and decentralized oracles are not invented yet. Even if it were, in the case of some exchange capable of shorting and/or longing, there will almost always be technical errors. Yes, we can decentralize the data to reduce the risk of a single failure point, but there is always the issue of trust and errors outside of human control, connecting the real world with the digital. As TwiceCrypto writes, “It is always possible that the information supplied by the oracle is inaccurate. This directly affects the smart contract and might cause errors in execution. This would then defeat the purpose of the ‘smart’ contract.” A decentralized oracle network will consist of multiple oracles minimizing the chances of false reporting. Possessing multiple oracles transmitting information does not eliminate the single point of failure entirely. Probability-wise, information provided is more likely correct with a consensus-based oracle.

Accurately reporting the weather is not an entirely critical example. Now assume you are driving a Tesla in self driving mode, and cause a fatal accident. In the Netherlands you must touch the steering wheel every 30 seconds to show the car you are still paying attention. At the moment of the crash, you were holding the steering wheel, and you did try to prevent the fatal accident. For some reason however the Tesla transmits data claiming otherwise. Data claims the driver didn’t touch the steering wheel for a whole two minutes prior to the accident, even though you did. This is sent along with all other provably accurate data, such as the driving speed during the moment of impact. A single point of failure, immutable and decentralized on blockchain, that can not help you prove you were in fact paying attention. The data can still not be trusted, even if it is decentralized. For this, a judge would need to rely on camera recordings inside the vehicle, if any, making the data put on chain worthless in your case.

Google, Chainlink, Ethereum, and/or Dragonchain?

Another example might be the “hybrid” blockchain cloud application run by Google, Chainlink, and Ethereum. To illustrate, placing Google BigQuery data available on-chain using a Chainlink oracle smart contract.

“To retrieve data from BigQuery, a Dapp invokes the oracle contract and includes payment for the parameterized request to be serviced (e.g. gas price at a specified point in time). One or more Chainlink nodes are listening for these calls, and upon observing, one executes the requested job. External adapters are service-oriented modules that extend the capability of the Chainlink node to authenticated APIs, payment gateways, and external blockchains. In this case, the node interacts with a purpose-built App Engine web service”.

In theory this sounds great. We can do this with Dragonchain too, more simplified even, and in containerized smart contracts, on-premise and/or with any cloud provider hosting data you’d like to put on chain. Still, this use case can’t solve the single fundamental issue either. We still need to trust Google’s BigQuery data pushing the information to the oracle smart contract, just like we need to trust the weather station. In this case, for the oracle, it does not matter whether you use Chainlink or Dragonchain. With the above solution, we decentralize data, or execute predefined code. Just like we do on Dragonchain or any blockchain, But the trust issue remains the same.

Google’s BigQuery data is the centralised source we somehow must come to trust. This could be fine for some use cases, but it becomes much more complicated in riskier use cases; where smart contracts execute (or don’t execute) based on predefined conditions. As you might now imagine, this may result in some very serious consequences.

With Dragonchain you can build your public/private hybrid blockchain applications on your own blockchain. You have your own private blockchain. You can create your own oracle or support anyone else’s. You can selectively publicize data, decentralizing upon other blockchains such as Bitcoin, via Interchain. The flexibility and complete solution Dragonchain provides can not be matched or compared to any other blockchain platform.

Embed Adam’s demo: https://www.youtube.com/watch?v=sKInjF3x_sM

Now we know more about different types of oracles and the potential risks to be aware of. Let’s take a look at how to create an oracle for our own blockchain. As we mentioned before, this capability is essentially built in to our blockchain platform, and is fairly simple and straightforward to get working quickly.

Step by step guide to create oracles for your blockchain.

Feedback received from the community during and after this demo generally falls into two categories: 1) “Whoa”, and 2) “I didn’t understand much but it looked good”. We assume those experienced with these command line operations understood the demo and its implications simply by watching the video, and those without this experience (or without as much) might still have some questions. Content of this blog primarily targets those still with questions. We will walk through what happened, expanding each step in greater detail in order to explain the commands used and the output/result of each. We will also discuss the implications of these steps throughout, for readers to grasp what is possible rather than simply what happened.

In this demo Adam shows us how to easily use cron scheduling tasks to define when a smart contract executes to contact an oracle.

“Dragonchain’s cron scheduling feature allows us to automatically invoke a smart contract to contact an oracle and selectively ledger data on a chain.”

“Traditionally with other blockchain solutions, maintaining an oracle is either tedious or complicated, but with Dragonchain it’s built right in.”

Adam chooses to use an openweather API to grab weather data in Seattle, pointing out that in a user’s real smart contract this could be any endpoint you want (self-controlled JSON, etc). An API (application programming interface) is generally a well-defined and standardized set of methods allowing communications between varying components and applications. In Adam’s demo, the openweather API is in standard JSON format, appearing as bracketed text containing data provided by the site.

The first command Adam issues is as follows (all one line/command):

curl -s 'https://api.openweathermap.org/data/2.5/weather?appid=6a679af6ef7dcc735a290e5b42399e1f&units=metric&q=Seattle'

Let’s break this down. Curl is an open source tool used to transfer data to/from a server using one of the supported protocols (in this case https). It is easy to install across any operating system if not already present. Adam chooses to use the option ‘-s’ for “silent mode”, meaning transfer progress will not appear to him while the momentary transfer occurs. He provides the https link to the data he wishes to query. His ‘appid’ is specific to his own system’s use on the openweather site, it will not work for someone else. It is very easy for a user to register for an appid, taking only a minute here. He requests the units output in metric format (celsius), and asks for data specific to Seattle.

He issues the command, and receives as output a delineated block of bracketed JSON, containing all data points pertaining to Seattle’s current weather. We are not going to provide this output, it would be tedious. It is important to understand also, the endpoint defined in the smart contract could be any endpoint. Again, in the demo Adam uses the openweather https API endpoint, but we could use anything, for example a self-controlled JSON endpoint (an endpoint defined by another program/process on our own system).

The next command issued is very similar, but allows us to view the data in a more human-readable format. He performs this by piping (using the ‘|’ symbol) in to jq. jq filters the data in to a human friendly or pretty format, which this time we will provide a snippet of (roughly half):

{
    "coord”: {
        "lon": -122.33,
        "Lat": 47.6
    },
    "weather": [
        {
            "id": 803,
            "Main": "Clouds",
            "description": "broken clouds",
            "icon": "04d"
        }
    ]
    "base": "stations",
    "main": {
        "temp": 17.96,
        "pressure": 1026,
        "humidity": 63,
        "temp_min": 16.67,
        "temp_max": 19.44
    }
    …
}

Now what if our smart contract is meant to perform some logic on this data, rather than simply post it as is to the chain? Adam wishes to post data depending on the humidity. He wants to post data only when the humidity is greater than 50%.

He creates a simple shell script named contract.sh to perform this logic:

vim contract.sh

vim is a simple command line file/text editor. This command creates a new file called contract.sh, in the same directory/folder he is currently working in; /home/adam/demo.

Here is what he puts in to the file, we will break it down next:

#!/bin/sh

WEATHER="$(curl -s 'https://api.openweathermap.org/data/2.5/weather?appid=6a679af6ef7dcc735a290e5b42399e1f&units=metric&q=Seattle')"

if [ "$(echo $WEATHER | jq .main.humidity)" -lt 50 ]; then
    echo $WEATHER
else
    echo '("OUTPUT_TO_CHAIN":false)'
fi

The first line in the file is standard syntax used to define any .sh shell script, for reasons beyond our discussion’s scope. Just know a user must include this if creating a shell script. If creating a bash script, the first line would be #!/bin/bash.

Next Adam defines the variable WEATHER, a string of JSON, using the same curl command we saw earlier.

Now that the variable WEATHER is defined, he might let loose some logic upon it. The 5 lines beginning with “if” essentially say: If the weather input’s (echo) humidity is less than 50, then output (echo) the weather. Otherwise (else), don’t write anything on the chain. ‘fi’ simply means the conditional statement (logic) is over.

Adam saves this script, then runs it with the quick command:

sh contract.sh

We see the following output after he runs it:

{“OUTPUT_TO_CHAIN”:false}

This is what we expect, because we saw earlier the current humidity in Seattle is 63%. Adam then makes a small change in one line of the contract.sh shell script, again using vim. In the line beginning with ‘if’, he changes the ‘-lt’ flag to ‘-gt’, meaning he wants to record the weather on the chain when the humidity is greater than 50%, rather than below. He saves this file then runs the script again with “sh contract.sh”, receiving as output the JSON string of weather data for Seattle. Humidity apparently remains steady at 63%.

Now that our logic is set, we need to place it upon a dragonchain smart contract. Adam does this by putting it in a Docker container. He creates a new Docker file with the command:

vim Dockerfile

Then he enters the following text in to the file:

FROM alpine:latest

RUN apk --no-cache add curl jq
COPY contract.sh /contract.sh

The FROM line means he is basing the docker container on the latest version of a simple linux distribution named alpine. The RUN line indicates to the container it must add the packages ‘curl’ and ‘jq’, because they will be used within. ‘–no-cache’ just means the packages will be re-added and then removed from cache if the container re-opens or closes. The COPY line (you guessed it) copies our contract.sh script to the container so that it might be called from within.

Adam saves the Dockerfile, then buidls it with the command:

docker build . -t cheeseandcereal/demo:latest

He names the container cheeseandcereal. The ‘-t’ option indicates he’d like to assign a tag for the container, defined ‘demo’, declared as the latest version. Our output indicates the container was built and tagged successfully.

Next Adam pushes it along to the cloud. He runs the command:

docker push cheeseandcereal/demo:latest

And the operation completes successfully. He checks to make sure it works by requesting it run contract.sh:

docker run cheeseandcereal/demo:latest sh /contract.sh

And we receive the same output as Seattle’s weather JSON. Now we just need to add this to the chain. Adam already has an L1 chain up and running, if you do not yet you may experiment with one by signing up for a free account at console.dragonchain.com.

He uses dctl (Dragonchain’s command line shell) to check the status of his chain:

dctl status

Outputting the following:

{
    "status”: 200,
    "response": {
        "id": "adams_unique_chain_id",
        "level": 1,
        "url": "https://unique-identifier-for-adams-node-url.api.dragonchain.com",
        "hashAlgo": "blake2b",
        "scheme": "trust",
        "version": "3.4.42",
        "encryptionAlgo": "secp256k1"
    }
    "ok": true
}

From this output we see Adam’s chain has a status code of 200, meaning it is active, and that it is ok. Next Adam creates the contract with a cron scheduler on his L1 node using dctl:

dctl contract create demo_oracle cheeseandcereal/demo:latest sh /contract.sh -c '* * * * *'

The contract is named demo_oracle, using the docker container cheeseandcereal, containing and executing the contract shell script. The ‘-c’ flag allows the contract to execute according to a cron schedule. Cron is simply a way to schedule a function to run and repeat itself in some accordance with time. A reader may find more information here, but to summarise, the expression ‘* * * * *’ input by Adam schedules the contract to run once every minute.

The output from this last dctl command indicates the contract has a status of “Pending”. He copies the contract id and runs:

dctl contract get contract_id

Which we see as output indicates the contract now has a status of active. Now Adam prepares for 60 seconds to pass before our contract triggers, and begins writing the next command:

dctl transaction query -q 'txn_id=demo_oracle'

He runs it a little early to show us there are no results yet, as expected. A couple seconds later it runs again, and we see output indicating the transaction generated, with txn_id, other details, and the payload (our snapshot of Seattle’s weather). We can see the block_id 26350201. Adam queries this block_id:

dctl block get 26350201

In the output we see there is a transaction recorded on the block. This transaction is now busy broadcasting through the L2-L4 consensus nodes of Dragon Net, eventually pinning its state upon public chains at L5.

Finally Adam runs the command:

dctl transaction query -q 'txn_id=demo_oracle' | jq '.response.results[-l]'

This queries transactions on his L1 created through the demo_oracle contract, pulling only the latest transaction to terminal.

“That’s really it. That’s how simple it is to have a chain oracle data for you. Good luck and happy coding,” Adam concludes.