# Attestation and Continuity Proving

{% hint style="danger" %}
**Outdated Documentation:** This page covers the architecture used for USC V1, which was deprecated on 2026-03-30. For the latest documentation, please visit: [usc documentation](https://docs.creditcoin.org/usc)
{% endhint %}

## **Overview**

A continuity proof is one of two key proofs the Creditcoin Decentralized Oracle needs to securely move data from one chain to another. It bridges gaps between attestations that don't link directly, ensuring an unbroken chain of source chain blocks.

Why do we need continuity proofs? Why can't attestors simply record consensus about every block? The answer is on-chain storage. Storing attestations for every source chain block on our Creditcoin chain would be too expensive—especially for chains like <img src="/files/Y5Dxqajg40K2KnM2wvwo" alt="" data-size="line"> `Solana` that produce blocks frequently. Instead, we store attestations at larger intervals (e.g., every 10 or 100 source chain blocks). Each attestation links to the previous one via digests. When there's a gap between attestations, a continuity proof fills it. This proof is a chain of digests of intermediate source chain blocks that:

* Starts from the block immediately after the last finalized attestation
* Ends at the block immediately before the new attestation
* Proves each block links to the previous one via digests

This lets the oracle handle queries for any source chain block—even if it wasn't explicitly stored—by proving continuity through the intermediate blocks. The continuity proof ensures that even though we only store attestations at intervals, we can still verify the integrity of the entire source chain.

## **Key Terms:**

📝 **Hash:** A cryptographic hash is a deterministic mathematical function that takes an input of arbitrary size and produces a fixed-size output, called a hash value.

***

📝 **Merkle Tree**: A Merkle tree is a balanced binary tree of cryptographic hashes that enables efficient and secure verification of integrity of large data sets. With the tree’s Merkle root and a small subset of hashes (a Merkle proof), one can efficiently verify whether a given piece of data is included in the set without revealing or re-hashing all the data. This property allows us to efficiently determine whether a part of a transaction is contained in the Merkle tree for a given block.

***

📝 **Root (Merkle Root)**: A Merkle root is the single cryptographic hash at the top of a Merkle tree. It uniquely summarizes all the data beneath it, allowing us to rapidly verify the integrity of all the data stored in that tree.

{% code title="Root in code" %}

```rust
let root = eth::starknet_pedersen_mmr(&block_data);
```

{% endcode %}

***

📝 **Digest:** Another term for any output from a hash function. In the context of the Creditcoin oracle, a digest usually describes the hash output uniquely identifying a block or attestation. The digest of a block is derived by hashing its block number, Merkle root, and previous digest.&#x20;

<pre class="language-rust" data-title="Digest in code"><code class="lang-rust"><strong>let digest = Self::hash_payload(&#x26;block_number.into(), &#x26;root, &#x26;prev_digest);
</strong></code></pre>

***

📝 **Previous Digest:** The previous digest of a block is just the digest of the block before it. We generate each new block digest using the previous digest. <br>

## **How Hashing "Chains" Blocks Together**

Continuity proving relies on one of the key properties of blockchains. Namely, that the digest of each block is generated using both the contents of that block and the digest of the previous block. Since each block uses part of the previous block, the blocks are said to form a *chain*. This gives us a very important property:

> If the contents of block `x` are changed, then the digests of blocks `x, x+1, ... x+n` are *all* *changed* as a result. This allows us to cheaply verify whether any part of the chain was changed using only the most recent block.

## &#x20;**Generating  Attestations**

An attestation is generated using the following process:

### 1. Determine which source chain blocks to attest to

This is calculated as:

```rust
let next_attestation_block = latest_attestation_block + attestation_interval;
```

For example, if the `attestation_interval` is `10` and the last attestation is at block `100`, attestors will fetch blocks `101-110`.

### 2. Fetch source chain blocks from source chain RPC nodes.&#x20;

Attestors either monitor the source chain directly or query an external trusted endpoint of their choice. As long as the attestor population represents a sufficiently diverse and distributed set of endpoints—rather than relying on just a few sources—it doesn't matter if individual attestors use external RPC endpoints.

### 3. Construct an attestation fragment

Attestors fetch source chain blocks to build the continuity proof—a sequence of digest that bridges from one attestation to the next. As digests are added, each new digest is calculated as:

<pre class="language-rust"><code class="lang-rust"><strong>let digest = Self::hash_payload(&#x26;block_number.into(), &#x26;root, &#x26;prev_digest);
</strong></code></pre>

Each block's digest integrates the previous block's digest, forming a verifiable chain. At the end, the new attestation's `prev_digest` is set to the digest of the continuity proof's head block. The attestation itself has its own digest, calculated from the attestation's `root` and `prev_digest`. This allows the attestation to be verified against the entire chain of intermediate digests, proving continuity even when blocks weren't explicitly stored.\
The following visual shows how digests bridge one attestation to the next.

<figure><img src="/files/8GA7UOmo58zeXKw5hktI" alt=""><figcaption></figcaption></figure>

### **Proving Continuity**

When processing specific queries, provers construct a continuity proof chain linking the queried block to the closest attestation (or checkpoint) after it. The prover:

* Determines the interval endpoints by finding the highest attestation/checkpoint before the query and the lowest attestation/checkpoint after the query.
* Fetches source chain blocks between these endpoints and constructs the continuity proof as done for attestations.
* Generates a cryptographic proof verifying that hashing was done correctly on the input blocks.
* Submits the cryptographic proof to Creditcoin, where validators check that the final digest matches the attestation digest at the same block height on-chain.

If a prover modifies a block, the digest for that block changes. This change cascades through subsequent block digests, eventually affecting the digest of the last block in the continuity proof. When this final digest doesn't match any attestation or checkpoint digest stored on-chain at the expected block height, the proof is rejected—disproving continuity.\
The following visual shows how the faulty proofs are detected.

<figure><img src="/files/V9TpLloa9McxXnkAtH7Q" alt=""><figcaption></figcaption></figure>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.creditcoin.org/usc/usc-v1/creditcoin-oracle-subsystems/attestation/attestation-and-continuity-proving.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
