> ## Documentation Index
> Fetch the complete documentation index at: https://docs.boundless.network/llms.txt
> Use this file to discover all available pages before exploring further.

# Proof Composition

> Proof composition allows you to build upon existing proofs by verifying them within new zkVM guest programs.

## Overview

<Check>
  For example code of composition in action, please see the [Proof Composition Example](https://github.com/boundless-xyz/boundless/tree/main/examples/composition)
</Check>

Proof composition enables you to build upon existing proofs by verifying them within new zkVM guest programs. This is particularly useful when you want to prove a sequence of related statements without reproving each step.

For example, let's say you have:

1. A proof that block `n` is valid
2. You want to prove that both blocks `n` and `n+1` are valid

Instead of reproving block `n`, you can:

1. Use the existing proof of block `n`
2. Prove only block `n+1` under the assumption that `n` is valid
3. Resolve this assumption by verifying the previous proof within your new proof

This approach is more efficient than reproving everything from scratch.

## How Composition Works

Proof composition works by:

1. Requesting a raw Groth16 proof from the Boundless Market
2. Using this proof as input to a new zkVM guest program
3. Verifying the proof within the guest program
4. Building upon the verified result to prove new statements

## Example: Composing Echo and Identity Proofs

The [Proof Composition example](https://github.com/boundless-xyz/boundless/tree/main/examples/composition) demonstrates how to compose proofs using the Echo and Identity guest programs.

First, we request a raw Groth16 proof from the Echo guest program:

```rust theme={null}
let mut requirements = Requirements::new(Predicate::digest_match(image_id, journal.digest()));
if groth16 {
    requirements = requirements.with_groth16_proof();
}
```

We then use this proof as input to the Identity guest program:

```rust theme={null}
// Build the IDENTITY input from the ECHO receipt
let identity_input = (Digest::from(ECHO_ID), echo_receipt);
let identity_guest_env =
    RequestInput::builder().write_frame(&postcard::to_allocvec(&identity_input)?).build_env();

// Request a proof from the Boundless market using the IDENTITY guest
let (identity_journal, identity_seal) =
    boundless_proof(&boundless_client, IDENTITY_ELF, identity_guest_env, false)
        .await
        .context("failed to prove IDENTITY")?;
```

Finally, we can use the composed proof to interact with a smart contract:

```rust theme={null}
alloy::sol! {
    #[sol(rpc)]
    interface ICounter {
        function increment(bytes calldata seal, bytes32 imageId, bytes32 journalDigest) external;
    }
}

// Interact with the Counter contract using the composed proof
let counter_address = address!("0x000000000000000000000000000000000c0077e5");
let counter = ICounter::ICounterInstance::new(counter_address, boundless_client.provider().clone());
let journal_digest = B256::from_slice(identity_journal.digest().as_bytes());
let image_id = B256::from_slice(Digest::from(IDENTITY_ID).as_bytes());
let call_increment =
    counter.increment(identity_seal, image_id, journal_digest).from(boundless_client.caller());

// Execute the transaction
let pending_tx = call_increment.send().await?;
let tx_hash = pending_tx
    .with_timeout(Some(TX_TIMEOUT))
    .watch()
    .await?;
```
