Oracles operation

Understand Charli3's Oracles: Learn about the architecture and mechanism for generating reliable data.
This article assumes familiarity with the (E)UTXO model. It reviews Charli3's oracle contracts and its integration with the Vasil Hard Fork features, including inline datums, reference UTXOs, and reference scripts.
First, we will examine one of the most basic oracle contracts, including its UTXOs, datums, tokens, and NFTs, as well as the mechanism that incentivizes individuals towards active participation in data acquisition. Then, we will look at a more advanced oracle contract that uses multiple trusted data sources and examine how it's UTXOs work together to provide accurate, decentralized, and trustworthy data.

Oracle Contract's UTXOs

The simplest oracle contract consists of five essential UTXOs:
  1. 1.
    Node UTXO: Transports external blockchain data.
  2. 2.
    Aggregate UTXO: Contains the contract's configurations and reward tokens (Charli3 Tokens - C3).
  3. 3.
    Reward UTXO: Register the received C3s as compensation for node and contract operator.
  4. 4.
    Feed UTXO: Stores the consolidated and processed data from all Node UTXOs (oracle feed).
  5. 5.
    Reference Script UTXO: Stores the contract's script.
Figure 1. The simplest Oracle contract creates five UTXOs at its initiation stage.


Let's concentrate on the Node UTXO for now. Upon executing the start oracle transaction, the inline datum will only contain information about the wallet that is authorized to consume it. The individual, or entity, that holds the wallet access, can modify the information stored in the datum. As shown in Figure 2, the Update-Node transaction updates data A to B.
Figure 2. The Update-Node transaction modify the UTXO's inline datum.
The Node's NFT (NodeFee) serves as a unique identifier within the UTXO, distinguishing the contract's UTXO from other outputs at the same script address. NodeFee is specifically defined as a token for all oracle contracts since it interacts with multiple Node UTXOs, while the remaining UTXOs of the contract hold NFTs.

Aggregate UTXO

The Aggregate UTXO's datum holds the contract settings (oracle-settings), defining how information from the Node UTXOs is processed. These settings include the frequency of updated data, such as weekly, daily, hourly, or even minutes.
The UTXO values consist of the Aggregate's NFT (AggState) and a specific quantity of C3 tokens. These tokens serve as rewards for Node UTXO owners who consistently update their information. The consensus algorithm determines the recipients of these rewards.
A node operator receives an additional reward for creating a new feed within the aggregate transaction (Aggregate). The selected node executing this transaction is rewarded to cover the costs involved. Additionally, the contract operator (also known as the oracle operator) is rewarded for each feed generation, contributing to maintenance costs.
Figure 3. The Aggregate UTXO's datum and values.


The Feed UTXO stores data generated by the Aggregate transaction, including an NFT (OracleFeed). Multiple contracts can access this information simultaneously using the read-only UTXO feature in VHF PlutusV2, ensuring there are no race conditions.
Figure 4: The Feed UTXO's datum and values; initially, the datum is empty.

Reward UTXO

The Reward UTXO stores individual records for each node's earned reward, including the reward of the oracle operator. The corresponding NFT for this UTXO is known as Reward.
Figure 5: The reward UTXO's datum and values.

Reference Script UTXO

To minimize user fees and prevent blockchain bloat, scripts can be stored separately in the blockchain. Rather than including the complete script in each contract transaction, a spending transaction can reference the script's location and utilize it for validation when spending a UTXO. This approach eliminates the need to duplicate the script in every transaction, leading to more efficient and streamlined transactions.

Consensus algorithm with a single Node UTXO

When executing the Aggregate transaction in our simple oracle example, the contract read a single Node UTXO, and its information is reflected in the Feed UTXO through the consensus algorithm. The Node UTXO that supplies the information is rewarded twice with a fixed amount of C3 tokens. The first reward acknowledges the accurate data provided to the oracle contract, while the second reward covers the costs associated with the Aggregate transaction.
The Feed UTXO's datum now includes the processed node's information, also known as the oracle feed. Please refer to Figure 6 for a visual representation.
Although this example contract only involves mirroring information from one UTXO to another, it effectively demonstrates the collaborative functionality of each UTXO.
Note: To ensure decentralization and security, Charli3 does not provide contracts with a single source of data (single node). The example described introduces readers to the Aggregate transaction for educational purposes only.
Figure 6. The Aggregate transaction takes in all oracle UTXOs and calculates a new Feed UTXO's datum (A) through the consensus algorithm

Consensus algorithm with multiples Node UTXOs

In contracts involving multiple Node UTXOs (Node Pool), such as exchange rates between assets, the consensus algorithm calculates the final feed by taking the median value of all node's exchange rates. Nodes whose input datums do not exceed the MAD and DIV values specified in the oracle-settings are rewarded.
Specialized functions will be utilized to ensure the utmost precision and accuracy for oracles that involve data types that cannot be computed using the median formula.
The consensus algorithm's final feed, known as the oracle feed, is stored in the datum of the Feed UTXO. Third-party contracts can access the oracle feed by identifying the corresponding NFT at the contract address.

Oracle Settings

The oracle-settings store adjustable variables that cater to the oracle feed's focus and target audience requirements, including:
  1. 1.
    List of authorized wallet's (PHKs) for updating each Node's UTXOs.
  2. 2.
    Minimum percentages of Nodes updated required to execute the Aggregate transaction.
  3. 3.
    Timeframe for determining the freshness of Node's datum information.
  4. 4.
    Aggregation transaction frequency period.
  5. 5.
    Percentage change in the feed data.
  6. 6.
    The minimum quantity required to replenish the C3 token pool, serving as a reward for entities that generate new feeds.
  7. 7.
    A specific timeframe is defined within which an Aggregation transaction must be submitted to the blockchain. If the transaction surpasses this designated window, it will be considered invalid. This precautionary measure is in place to prevent the acceptance of outdated data, which could be a result of system delays or network congestion.
  8. 8.
    C3 reward quantity for each participant in the contract, including:
    1. 1.
      Amount for Node operators participating in the consensus algorithm.
    2. 2.
      Amount to cover the Aggregation transaction costs for Node operators.
    3. 3.
      Amount for Oracle operator for maintenance purposes.
  9. 9.
    Measures the spread of C3 node data to identify outliers, interquartile range algorithm (IQR).
  10. 10.
    The threshold for data variation from C3 nodes. If this threshold is exceeded, network actions are triggered to maintain data integrity, often involving outlier detection measures
  11. 11.
    Individuals/entities (PKHs) allowed to adjust the smart contract settings.
  12. 12.
    The least number of authorizations required for modifying the contract.
Settings 4 and 5 dictate the execution of the Aggregate transaction. Setting 4 triggers the transaction at a fixed frequency, while Setting 5 activates it when there is a percentage change in the oracle feed that exceeds the previous feed.

Exception handling

Node Downtime

In cases where certain UTXO Nodes fail to update regularly, oracle-setting 3 evaluates and excludes inactive Nodes during data processing. Setting 2 allows the oracle operator to specify the minimum percentage of Nodes with recent information required to trigger an Aggregate transaction. For example, if there are 8 Node UTXOs in the oracle contract, the operator can set the requirement to have at least 50% of them providing active information.
Charli3's oracles and nodes are strategically distributed globally to ensure uninterrupted data access. The Charli3 team implements robust monitoring systems for each node and feed, promptly sending notifications in the event of any issues or disruptions.

Outlier Detection

Cheating attempts within the system, such as providing false node information, are deterred by the consensus algorithm. Submitting an Update Node transaction to the Cardano blockchain incurs a fee, discouraging false submissions as it would lead to exclusion from the consensus algorithm.
Oracle settings 9 and 10 allow for setting a threshold for outliers and selecting values closest to the median from all participants. Consequently, only a limited number of nodes with up-to-date data, such as 5 out of 7 nodes, may receive C3 token rewards. This ensures that rewards are distributed to the most reliable and accurate contributors.
The oracle operator has the capability to remove underperforming Node UTXOs by executing the Delete Nodes transaction. This transaction can only be performed by the oracle operator to maintain the quality of the contract's output. Similarly, the Add Nodes transaction allows for an increase in the number of participant nodes, enhancing the overall participation in the oracle network.

On-Chain Code

The Charli3 on-chain contract code ensures secure identification of the contract owner by storing their wallet ID, token reward information (C3), and NFTs in the Oracle data type. This data is included as part of the validator's argument, protecting against unauthorized tampering by external parties.
A valid argument for a contract validator could be:
Validator's argument
oracle :: Oracle
oracle = Oracle
{ oracleCreator = PaymentPubKeyHash
, oracleNFT =
( "e36cd9189099d7bedae87e8702e86e38122a62141743e1a64a5349ff"
, "OracleFeed")
, aggStateNFT =
( "e36cd9189099d7bedae87e8702e86e38122a62141743e1a64a5349ff"
, "AggState")
, rewardNFT =
( "e36cd9189099d7bedae87e8702e86e38122a62141743e1a64a5349ff"
, "Reward")
, feeToken =
( "436941ead56c61dbf9b92b5f566f7d5b9cac08f8c957f28f0bd60d4a"
, "C3")
, nodeToken =
( "e36cd9189099d7bedae87e8702e86e38122a62141743e1a64a5349ff"
, "NodeFeed")
Please note that the validator argument of the Charli3 contract stores important information such as the token name and minting policy for NFTs and tokens. This includes NFTs for the feed UTXO (OracleNFT), reward UTXO (RewardNFT), and Aggregate UTXO (aggStateNFT), as well as N tokens for different Node UTXOs (nodeToken).

Off-chain Code

Oracle owner transactions

The Oracle owner has the ability to perform several transactions, which are implemented as off-chain code in both the Haskell and Python versions of the contract:
  1. 1.
    Remove-Nodes: This operation allows the Oracle owner to eliminate specific Node UTXOs by burning the Node tokens associated with the specified wallet IDs.
  2. 2.
    Add-Node: The Add-Node transaction enables the creation of new Node UTXOs. The Oracle owner provides a list of wallet IDs, and additional Node tokens are minted and distributed to these new UTXOs.
  3. 3.
    Oracle-close: In the Oracle-close transaction, all contract UTXOs, including associated NFTs, ADAs, and C3 tokens, are collected and consumed. If the Node UTXOs contain C3 tokens, these tokens are paid to the corresponding node wallet operators. This transaction marks the end of the contract since no usable UTXOs are left.
  4. 4.
    Platform-Collect: The Platform-Collect transaction allows the Oracle owner to collect the rewards earned by the oracle operator, also known as platform operator rewards. These rewards are accumulated in the Reward UTXO.
  5. 5.
    Edit-Oracle-Settings: The Edit-Oracle-Settings transaction provides the ability to modify the datums of the Aggregate UTXO by changing the values of the oracle settings.

Node operator transactions

  1. 1.
    Aggregate: Execute the Aggregate transaction to generate a new oracle feed.
  2. 2.
    Update-Node: The node operator can modify data in the Node UTXO, but not the wallet ID or NFT information.
  3. 3.
    Node-collect: The Node UTXO owner can withdraw the rewarded C3 tokens from the Reward UTXO to their personal wallet.