Attestation and Continuity Proving

Continuity proving is the process by which attestations are used to certify that a block is part of its source chain. Continuity proving and merkle proving guarantee the veracity of Oracle results.

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 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.

Root in code
let root = eth::starknet_pedersen_mmr(&block_data);

📝 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.


📝 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.

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.

Generating Attestations

An attestation is generated using the following process:

1. Determine which source chain blocks to attest to

This is calculated as:

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.

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:

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.

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.

Last updated