Skip to Content
DocsContractsOverview

Introduction

This document provides a quick-start guide to smart contracts as part of our Blocksense protocol. Here you can get a high-level overview of the architecture and the role of smart contracts in the Blocksense network.

Folder Structure

Smart contracts for Blocksense network are stored inside our public GitHub repository. The contracts folder is organized as presented below:

Smart Contracts Architecture

The Blocksense network utilizes a modular architecture, with smart contracts serving as the foundation for data storage and retrieval. The core components of the architecture include:

Components Overview

  • Client: Represents users and external systems interacting with the Blocksense protocol.

  • CLFeedRegistryAdapter: Represents an on-chain mapping of assets, base or quote pairs, to their corresponding feeds. It provides users and clients with Chainlink interface functions to query feed data using asset addresses, eliminating the need-to-know specific feed contract address.

  • CLAggregatorAdapter: Proxy instance, that allows users and clients to retrieve data for a specific feed through Chainlink interface methods.

  • AggregatedDataFeedStore: Represents the data feed contract, which stores historical data feed values of different sizes, allowing users to retrieve past data points for specific data feed IDs.

Core contracts

AggregatedDataFeedStore (ADFS)

The AggregatedDataFeedStore contract is the core contract responsible for storing and retrieving data feed values. It is designed to be upgradeable, allowing for future contract upgrades and improvements.

⚠️

In practice, the UpgradeableProxyADFS contract is the central storage for all data. The AggregatedDataFeedStore contract provides the logic for reading from and writing to the UpgradeableProxyADFS contract’s storage.

Each data feed is represented by a unique ID, which is used to identify and retrieve the corresponding data feed values. The contract supports multiple data feed sizes as well as historical data in the form of a ring buffer (i.e. the historical data is limited and will be overwritten with new data when the buffer is full).

Data can be stored in any format and in any size (up to ~64GB).

Subscribe to update events

When an update is posted to the contract, an event is emitted - “DataFeedsUpdated(uint256 blockNumber)” (topic: 0xe64378c8d8a289137204264780c7669f3860a703795c6f0574d925d473a4a2a7). Block number is an internal counter for the Blocksense system. Through this event off-chain programs can subscribe to updates and trigger on-chain actions when needed.

Read from storage

See the Integration guide for more information.

Access Control

This contract ensures the caller has the necessary permissions to perform specific actions.

CL Adapters

The cl-adapters folder contains Chainlink aggregator adapter contract (CLAggregatorAdapter.sol) and a feed registry contract (/registries/CLFeedRegistryAdapter.sol). The CL aggregator adapter contract implements the Chainlink aggregator interface, enabling it to interact with the ADFS contract to fetch stored data. The feed registry contract is responsible for mapping asset addresses to their corresponding Chainlink data feeds. It provides a mechanism for users to retrieve the address of a specific data feed based on the asset address.

Interfaces

The interfaces folder includes the following key interfaces:

Libraries

The libraries folder contains CLAdapterLib.sol - used as an internal library in CLFeedRegistryAdapter, CLAggregatorAdapter to call ADFS, and ADFS.sol - used in the example contracts to demonstrate how the client can query ADFS directly. Both provide utilities for low-level static calls to ADFS or the CL adapters to ensure maximum gas optimizations. Moreover, CLAdapterLib enables historical data parsing handlers to decode raw data from the storage in the form of a Chainlink aggregator, whereas the ADFS library is designed for client contracts as a low-gas call library.

Test Contracts

test folder:

  • This folder includes example consumer contracts and reference implementations primarily for gas comparison purposes during testing. These examples provide a basis for evaluation of the gas efficiency.

Prologue Optimization

Overview

Prologue optimization aims to reduce gas costs associated with smart contract calls by skipping the Solidity dispatching prologue and instead using the selector as a data feed ID.

Call Handling Mechanism

All calls are managed by a fallback function based on the selector, ensuring efficient handling of setter and getter operations.

Key Points

  • A custom entry point, that bypasses the Solidity dispatching prologue.
  • Selectors utilize reserved bits to determine which function to call, while the remaining bits indicate the data feed they should handle.
  • The optimization reduces gas costs by eliminating the need for the Solidity compiler to generate “Linear If-Else Dispatcher” statements for different selectors.

Benefits

  • Reduced gas costs for smart contract calls.
Last updated on