In today’s world, blockchain is enabling decentralization in the world. But, on analyzing the applications of blockchain technology you’ll see that most of the time cryptocurrencies or decentralized finance applications are involved. Now, wherever cryptocurrencies go, their prices have to follow. And so an extensive number of decentralized applications need real-world data. This real-world data comes from resources that reside outside of the blockchain. So, oracles were very much needed.
Chainlink is a fully decentralized oracle network that enables access to real-world data to smart contracts in blockchain.
Also, read about Flash Ecosystem.
This section focuses on Chainlink’s architecture. The core-purpose of Chainlink is to create a bridge between on-chain and off-chain transactions.
Users who want to request queries for data, create a UserContract which essentially inherits the ChainlinkClient contract to do so.
The UserContract contract implements the ChainlinkClient contract. With every variable being private and every function being internal, users cannot make changes in the ChainlinkClient contract.
The Chainlink contracts are designed in a modular way. And so users may configure and change the contracts as needed.
Chainlink ecosystem has three components; DeviationFlaggingValidator, PreCoordinator, and Aggregator contracts.
The Reputation(DeviationFlaggingValidator) is for tracking the performance of oracle, the order-matching(PreCoordinator) matches user’s requests with oracles(Oracle), and lastly, the aggregator aggregates the latest responses of oracles.
• DeviationFlaggingValidator Contract
This contract, also known as the reputation contract, keeps track of the oracle’s performance metric. This contract checks the current value against the previous value and makes sure that it does not deviate outside of some relative range. If the deviation threshold is passed then the validator raises a flag on the designated flag contract.
The validate function verifies that the current answers submitted by oracles don’t deviate 100% from the previous value.
On every flagging of an oracle, an event is emitted. However, only owner and owner-approved addresses can flag an oracle. Also, only the owner can remove the flag of any flagged oracle. When the oracles are flagged the raiseFlag function is called which checks whether the address is allowed to raise the flag. This function then calls the private function of tryToRaiseFlags.
The tryToRaiseFlag function flags the oracle named as the subject.
The reputation of every oracle on Chainlink can be viewed at Chainlink Block Explorer.
Chainlink security services also make use of oracles reputation, see section 4
• PreCoordinator Contract
The PreCoordinator contract also referred to as order-matching contract essentially deals with the order-matching mechanism in Chainlink. This contract creates on-chain service level agreements.
• Aggregating Contract
Aggregating contracts collects the results and finds aggregate of all the responses from all the oracles. The aggregated result is also stored on-chain so the users can obtain the latest price feed. This latest price feed can be fetched without any gas fees.
By implementing the AggregtorV3Interface, the periodic price updates can be accessed. After completing the requests, oracle contracts updates the aggregating contract with the submit function. And pass on the results in the parameter. Then the contract validates the result through AggregatorValidatorInterface.
Also read about Uniswap v2 Protocol.
The oracle nodes on Chainlink gather responses to off-chain requests. These responses are sent to Chainlink contracts.
How these responses are sent to Chainlink contracts is discussed in section 2.4.
The core node is responsible for interfacing with the blockchain. It is also responsible for scheduling and balancing work across various services.
Assignments i.e. the work done by the Chainlink node consists of subtasks. Assignments are the core of the system, they are composed of one or more sequential subtasks, a schedule, a fee specification, and an optional name and description. Subtasks are the smaller job specification of the assignment, as they are work specifications for distinct job types.
Once an oracle receives an assignment, they sign the hash of the assignments. Upon receiving affirmative confirmation the user pays the oracle.
Assignments can essentially be triggered in two ways.
• Scheduled Updates
Scheduled updates are set when assignments are created. As each assignment has a set deadline, the number of updates can be determined upfront, and the cost of all scheduled updates is paid with the creation of the assignment. Additionally, any upfront costs of the assignment can be covered at the time the assignment is created.
• On-Demand Updates
The word on-demand is quite self-explanatory but if payment is required it must be paid with the request, not upfront. Any adapter may trigger an update on the entire assignment. However, the update triggers at the start of the earliest subtask and follows the full progression through all subtasks. To accommodate this, adapters often need to be stateful i.e. they store the data that triggered their snapshot and use it when they are next in the pipeline.
Also, oracles may choose to charge a service availability fee similar to an SLA. The baseline of this agreement is that the requester deposits the total fee amount into a contract where the oracle retrieves it in a prorated fashion. If the oracle fails to respond to requests, the requester gets the deposit back.
Chainlink’s software node comes with built-in subtasks which include HTTP requests, JSON parsing, and conversion to various blockchain formats.
Adapters are services an oracle runs to expand the functionality they offer. Programs, irrespective of the programming language, can easily be implemented simply by adding an intermediate API. Oracle providers can specify their offered services and requirements by following the adaptor specification and protocol.
Several external adaptors are available on https://chainlinkadapters.com. The node operators can easily access and use these tools and services.
The oracles specify the adapter’s subtask requirements using the adapter schema.
Now that we have an overview of all involved contracts, grasping the workflow would be less complicated.
The on-chain architecture workflow can be performed in two ways.
- Using Oracle contracts for direct data feed.
- Using PreCoordinator contracts and SLA to fetch data from multiple oracle contracts.
Let’s discuss both of the approaches individually.
Interact With Oracle Contract Directly
In this scenario, consider a UserContract which has implemented a ChainlinkClient contract.
- Contract first has to build a request from the buildChainlinkRequest.
- In the function parameter it specifies the callback function address and selector address.
- This is the function that the oracle will trigger when it’ll complete the request made by the user.
- After generating the request, the smart contract triggers sendChainlinkRequestTo function.
- In this function the smart contract will specify the oracle address it wants to use.
- sendChainlinkRequestTo function will trigger LINK token’s transferAndCall function, it will first transfer the fees to the oracle contract for the query. And it will then call the oracleRequest function of the oracle.
- The function is called by delegatecall functionality. In this call, the data parameter is also passed which contains the callback function address and selector address.
- An oracle request will be created in the oracle contract. Off-chain nodes will fetch the request and will work on it.
- After completion, only the authorized nodes will call the fulfillOracleRequest function of the oracle.
- The fulfillment request will be filtered by requestId, and along with that requestId all the information of the requester is also retrieved.
- The result is sent back to the callback function address and the function selector.
- The ChainlinkClient smart contract will now have the desired result in the callback function in the smart contract.
Interact With PreCoordinator And Multiple Oracles
- Users will inherit the ChainlinkClient contract as explained above.
- The client smart contract will first have to create a service level agreement specifying the number of oracles that are to be used and minimum number of responses as well.
- After receiving saId (service agreement id), the client smart contract will use the buildChainlinkRequest function to generate the request and pass in the callback address of itself, and the function selector as well of its own contract.
- After generating the request, the smart contract triggers sendChainlinkRequestTo function, in which instead of specifying oracle address, PreCoordinator address will be used.
- sendChainlinkRequestTo will trigger the LINK token’s transferAndCall and which will in return call oracleRequest of the PreCoordinator contract.
- In the PreCoordinator contract, createRequest function is called in which the callback address of the PreCoordinator is passed and also the function selector of this contract as well.
- It then becomes a kind of stack, where again the LINK token and the oracleRequest function of the oracle is triggered.
- Only authorized nodes can fulfill this request.
- After the completion the data is sent to the callback function of the PreCoordinator contract.
- As the function has the saId of the request, the callback address of the ChainlinkClient is retrieved.
- After taking Median, the result is forwarded to the client contract.
Chainlink initially used the flux aggregator model. While this method is quite straight-forward, it comes with increased cost. As every single node is submitting the response on-chain, they all have to pay the gas fee. Off-chain reporting enables nodes to aggregate their observation in a single report. This is done using a secure P2P network. Then a quorum of nodes sign the aggregated reports and then a single node submits the report on-chain.
All nodes watch the final on-chain result on blockchain for any single point of failure. In case the submitter node fails to get transmission confirmation with-in the specified time, a round-robin algorithm comes into action. In this scenario, other nodes also submit their final result report until one of them is confirmed.
Chainlink’s Decentralization Approach
Chainlink comprises three ways to decentralize the network.
To ensure that the result of a query is obtained from multiple resources is valid, distributed sources are used. When oracles work on an assignment, they may retrieve data from multiple sources and aggregate them. However, one data provider may obtain and release information obtained by another data provider. Faulty data may get forwarded by multiple data providers.
The high degree of tamper-resistance and reliability is ensured by Chainlink as it exclusively pulls data from premium data aggregators. Volume-adjusted aggregated price point from all centralized and decentralized exchanges represented by each data source. This makes it inherently resistant to numerous attack vectors like flash loans or abnormal deviations.
To avoid unsolicited correlations, Chainlink pursues research into mapping and reporting the independence of data sources.
Just as the sources can be distributed, the same can happen for oracle nodes. These distributed oracles may get data from multiple sources. Some of these sources may overlap but will return a single answer.
The first solution provided for the aggregation to get that single answer is in-chain aggregation. The aggregated answer of each node goes through a contract and then a refined answer is returned. However, the problem of freeloading persists.
To deal with freeloading a commit / reveal scheme is used.
Commit / Reveal Scheme
In this approach, oracles commit their cryptographic responses to Chainlink thus hiding their responses from other nodes. After enough responses are submitted, the nodes reveal their answer.
This solution deals with the problem of the transaction cost. As more and more oracles are used the transaction costs increase. The off-chain aggregation approach allows Chainlink to send a single aggregated answer to the smart contracts. The consensus is accomplished by allowing each oracle to generate a partial signature of its answer which together would create a verifiable signed answer from the collection of answers provided by all participating oracles. For this, Schnorr signatures are implemented. This enables the receiver to verify the sender.
To prevent freeloading in off-chain aggregation, it is required that each oracle obtain their data from the data provider instead of from one another.
A PROVIDER waits until enough nodes have committed their answers and de-commitment messages are received. Then, it sends the reward to oracles included in the accepted de-commitment set. Hence, incentivizing them for being honest.
Chainlink Security Services
Chainlink security services subsume of four key services.
The on-chain behavior of oracle nodes is monitored by the Chainlink network for availability and correctness. Thus, a performance metric is formed. This performance metric is available on-chain that will help users in the selection of oracles.
The reputation system will publicly reference the on-chain history maintained by it. The factors on which individual nodes are rated other than availability and correctness are:
the node’s total number of assigned, completed, accepted requests, the average time to respond, and the number of penalty payments.
The overall purpose of the reputation system is to provide incentives for nodes to produce honest data in a timely manner.
The certification system deals with Sybil and mirror attacks. The long-term solution is to use trusted hardware. However, certification service design’s short-medium solution issues endorsements of high-quality oracle providers. These endorsements are based on the stats in the validation system and would perform post-hoc spot-checking of data with reputable sources. In case oracles submit false responses, the answers will be visible in post-hoc review.
Contract Upgrade Service
The use of contract upgrade service is optional. When vulnerabilities are discovered, users can choose to use this service.
Contract upgrade service will essentially make a new smart contract based on the existing one and migrate all of its assignments to the upgraded contract. The use of a flag MIGFLAG would act as an indicator to use the new upgraded contract and not the existing one. If the flag is missing, automatic forward i.e. FALSE default value, would be used by the contract. The changes made by the contract upgrade service will be available on-chain.
LINK tokes are the native tokens of the Chainlink network used to pay for services of the network. These services include retrieving off-chain data, formatting data into blockchain readable data, off-chain computation, and but not limited to uptime guarantee as operators.
LINK token is an ERC667 token that inherits from the ERC20 standard. This allows token transfers to contain a payload.
- Freeloading: Freeloading is when an oracle instead of working to get the answer to a query, takes and submits the answer of another honest oracle.
- Availability: It is the ability of an oracle to respond to queries in a timely way.
- Correctness: It is the ability of oracles to provide correct responses and not erroneous ones.
- Sybil Attacks: Sybil attack refers to when one entity takes over the majority of the network.
- Mirror Attacks: Mirror attacks cause oracles to send individual responses based on data obtained from a single data-source query.
- Flux Aggregator Model: In this model, every oracle node must submit its price value individually. Once all responses are received on-chain, the contract aggregates them and confirms the price.
- Post-hoc: Analyses that were specified after the data were seen.
Learn about Categories Of Decentralized Finance.