October 26, 2022 12:30 PM
Oracles in the on-chain universe
Interesting applications rarely live in isolation. A blockchain system similarly connects in a variety of ways to other systems and data. One such approach has been named after the concept of an Oracle from antiquity. Beings that have the power to communicate outside of the physical universe, bringing meta-physical truths into the known reality. Following this metaphor, a blockchain would be its own little computational universe.
In this article, we dissect this metaphor by looking at the usage data of a handful of oracle smart contracts deployed on the Tezos blockchain. Before that though, we need to briefly go into on-chain data. To get to the practical computational nuts & bolts that "link" on-chain & off-chain data, powering their 'truth telling' abilities.
Blocks & the state
Data on a blockchain is stored as operations in blocks, the full set of blocks can be used to compute the most recent ledger state. This state is accessible by smart contracts as input. Multiple contracts can work together to generate and transform data based on user input. The current state, together with user input in the form of transaction parameters, can be used to generate new data, which is then stored in a new block.
This already indicates the basic way for data to enter this universe. Simply as a text or number input as part of a transaction.
Sidenote: Why would you want data to enter this universe? The promise made by blockchain systems is that the state and rule set for which transactions are permissible are strongly enforced by a distributed network of computers through a consensus mechanism. Creating strong guarantees on data immutability and smart contract behavior. This "universe" is very much unlike our own universe. Whereas the real universe is chaotic & un-deterministic, blockchain 'world computers' are in most cases designed to be explicitly fully deterministic. Previously we have looked at which entities have taken up that role of baking blocks for the Tezos blockchain.
on-chain / off-chain
There are various ways for implicitly link to information into and out of the chain.
Outside-in: Entities such as blocks, transactions, smart contracts within the chain have identifiers that can be referred to by outside systems to retrieve information from the chain. Tools such as indexers and block explorers extract this data from a chain node and often keep their own copy for faster access.
Inside-out: A smart contract can store and read data in the blockchain state in what is simply called the smart contract storage. For example most NFT smart contracts have a set of text strings in their storage pointing to an off-chain entity such as an IPFS url with the artistic assets.
The on-chain text string matches an off-chain url which usually is provided as one of the transaction parameters during the
mint call on a smart contract. Due to the common practice to refer to this metadata through IPFS links, an NFT marketplace front-end implicitly knows how to go outside-in to find the links by reading smart contract data through RPC calls or via an indexer and then to navigate inside-out to the IPFS url to retrieve the image data. This is a very simple example, but it shows how the on-chain universe can link outside to the off-chain world.
This is all very basic information copying & linking. What makes on-chain data "special" is that it can directly be accessed by smart contract code.
Back to Oracle contracts.
An oracle in its technical execution actually doesn't differ too much from how an NFT contract stores urls. In most designs, data also comes in simply as a transaction parameter. Instead of serving as a pointer to off-chain data, an oracle brings back data from the outside world and stores it to be accessed by other smart contracts in the on-chain universe.
To summarize, oracles bring external data on to the chain, making it available to other smart contracts in code execution.
As described in the Tezos documentation:
Oracles ... offer a way to obtain data from off-chain sources and to make it available on-chain.
The main approach we currently see on Tezos are Oracle mechanisms where data is pro-actively pushed to the chain into a smart contract by an off-chain system injecting wallet transactions. Making it directly available to other smart contracts through views. This requires a constant flow of transactions to be sent to the chain, which we will see in the data below. This is not necessarily ideal, as it can lead to a lot of unnecessary transactions and gas costs.
Oracle mechanisms can also be designed to bring data onto the chain in response to a request from another smart contract. A smart contract that is in need of data from the oracle would push a transaction to the oracle smart contract. An off-chain system continuously listens to these data request transactions and when it sees one, it will push a new transaction to the smart contract with the data as a transaction parameter. From there it can be passed back to the requesting contract in various ways. Either, a follow-up transaction in a later block is able to retrieve the data from a view with the hope that it was correctly updated by the off-chain system.
This data is maintained in contract storage and becomes available to other contracts through what is called a view. A view is similar to a contract entry point in that it can be called by other smart contracts. The main difference is that it doesn't have any direct effect, all it does is return a value.
With this mechanism, other smart contracts can request the data and use it in their own internal logic.
Oracle examples on Tezos
With all of that explanation out of the way, lets take a look at some Oracles on the Tezos chain.
Kaiko price oracle
The Kaiko price oracle is a simple example of an off-chain system continuously injecting transactions to maintain a value in contract storage. At a regular interval, a wallet address calls the
update_value entrypoint with values for the usd/chf, xtz/chf and xtz/usd change rates, including a timestamp to mark the values.
The chart below shows the number of times per day that values are updated in the contract. Which is about ~1,440 times per day or ~60 times per hour. Which for Tezos means that every other block, the value is updated.
The Kaiko Price Oracle currently regularly produces ~1% of all daily contract calls on the Tezos chain:
It's hard to say if it's worth it to update the value so many times, as currently there is no direct way to track if the value is actually used by other contracts.
Calling views by design do not produce an explicit transaction, so code analysis would have to be done to infer if calls to views were performed as part of smart contract execution. (Possibly events can enable logging of view usage in the future.)
A second example of a continuously updating oracle system is the Harbinger oracle, which also includes a normalizer contract, computing a weighted average of the raw data from the oracle.
Harbinger price oracle gets called about ~144 times per day, which is about once every 10 minutes.
Within the execution of the
update entrypoint call on the price oracle,
update on the Harbinger Normalizer is called as well.
The normalizer computes a weighted average based on a specified number of most recent price updates.
The Ubentic oracle system is a bit more complex. The Ubentic defi index oracle 2 contract serves as gateway to two other contracts capturing on-chain data.
Within this first contract, a list of wallets is maintained together with parameters for the interval, fees, gas and storage limits. Multiple wallets are calling the
fulfill entrypoint throughout the day, but not necessarily at a fixed interval.
THe below chart shows that in the range of 7 to 12 accounts are actively calling the contract on a daily basis.
The above contract then calls the below two contracts which maintain token prices as well as extra information about the provenance and validity of the data.
See the storage of the Ubentic index oracle for a detailed view of how the values, including metadata to document data provenance are captured in the on-chain data.
A last Oracle style contract to highlight is one not in the DeFi space but a more generic building block, which makes "random" values available on the chain:
The code of the Randomizer contract is available on Github.
As mentioned in the introduction section, what makes a blockchain "universe" different & valuable, comes in a large part from this being a fully deterministic system. If we go through and execute the same series of transactions on any of the nodes, the end state should be exactly the same. For this article we'll not go deep into the mechanics of how random values are generated.
The Randomizer contract makes its random number generator function available in a couple of ways both through views and through callbacks. You have the option to provide your own "entropy" value which should be some hard to predict sequence the caller of the contract still would need to produce. The contract also maintains an entropy seed value in its own storage, which is updated regularly by wallets from an off-chain source and is currently the main set of transactions generated for this contract. Using this entropy value
Why would we want randomness on a blockchain? There are a number of potential use cases but some practical relatable use cases are for example give-aways, lotteries, or randomized ticket queues for events that are in high demand. Bringing it back to the theme of Oracles, randomness is one of the attributes we as humans seem to associate with 'fairness' in a system and in the universe. Where whoever you are, any prior knowledge is worthless and you have an equal chance just like anyone else.
As applications leveraging blockchain smart contract technology continue to evolve, the need to move information into and out of the chain will most likely increase as well. Oracles are just one of multiple concepts to establish connections between external information systems. A related theme is for example the concept of bridging tokens from one chain to another.
Whereas a lot of attention is given to the decentralized nature of blockchain networks, these connecting systems between blockchains such as oracles often have quite a reliance on the trust of a centralized party providing the data. As can be seen in the Ubentic Oracle system, further data signatures and proofs about the process and system in which the data was collected can be provided to provide documentation on the provenance of the data as well. Also from a hardware perspective you might want to have a network of computers and accounts pushing data to the chain with a consensus mechanism to filter out bad data.
In the further research study below, other architectures for aggregating data are proposed to create more decentralized oracle systems.
As The Stack Report, we'll continue to keep a close eye on the developments of this interfacing layer between various parts of the tech stack in the new de-centralized era for the web.
- Kaiko Price Oracle
- Harbinger Oracle
- Harbinger Normalizer
- Ubentic defi index oracle 2
- Ubentic index oracle
- Randomizer by asbjornenge