---
title: State Proofs
description: Understand the C SDK state proof structs, proof types, and the
  sizing helpers needed for variable-length proofs.
source_url:
  html: https://thru.org/docs/sdks/c-reference/state-proofs/
  md: https://thru.org/docs/sdks/c-reference/state-proofs.md
---

# State Proofs

Use this page when you need to carry, inspect, or size state proofs in C instruction payloads.

## Public proof types

The C SDK exposes:

- `tsdk_state_proof_hdr_t`
- `tsdk_state_proof_t`
- `tsdk_state_proof_header_type(...)`
- `tsdk_state_proof_header_slot(...)`
- `tsdk_state_proof_footprint_from_header(...)`

All of these live in `tn_sdk_txn.h`.

## Header layout

`tsdk_state_proof_hdr_t` contains:

| Field | Meaning |
| - | - |
| `type_slot` | Top 2 bits encode proof type; lower 62 bits encode slot. |
| `path_bitset` | Bitset used to derive sibling-hash count. |

The helper functions decode this packed header:

| Helper | Meaning |
| - | - |
| `tsdk_state_proof_header_type(hdr)` | Returns the proof type encoded in the top 2 bits. |
| `tsdk_state_proof_header_slot(hdr)` | Returns the slot encoded in the lower 62 bits. |
| `tsdk_state_proof_footprint_from_header(hdr)` | Returns the actual byte footprint of the full proof payload based on type and sibling-hash count. |

## Proof body variants

The full `tsdk_state_proof_t` body covers three logical shapes:

| Variant | Layout |
| - | - |
| Existing | Sibling hashes only |
| Updating | Existing leaf hash plus sibling hashes |
| Creation | Existing leaf pubkey, existing leaf hash, then sibling hashes |

The public struct is intentionally oversized to cover the max shape. Real proof payloads are often shorter.

## Most important sizing rule

Do not assume `sizeof( tsdk_state_proof_t )` is the size of the proof payload you received.

Instead:

1. read a `tsdk_state_proof_hdr_t`
2. call `tsdk_state_proof_footprint_from_header(...)`
3. validate the instruction buffer contains that many bytes

## Minimal parsing pattern

```c
if( instr_sz < sizeof( tsdk_state_proof_hdr_t ) ) tsdk_revert( 1UL );

tsdk_state_proof_hdr_t const * hdr =
  (tsdk_state_proof_hdr_t const *)proof_bytes;

ulong proof_sz = tsdk_state_proof_footprint_from_header( hdr );

if( instr_sz < proof_offset + proof_sz ) tsdk_revert( 2UL );

tsdk_state_proof_t const * proof =
  (tsdk_state_proof_t const *)proof_bytes;
```

## Where proofs usually show up

| Use case | Related syscall or pattern |
| - | - |
| Account creation | `tsys_account_create` |
| Compression | `tsys_account_compress` |
| Decompression | `tsys_account_decompress` |
| Custom instruction payloads | Packed instruction header plus trailing proof bytes |

## Notes

- Proofs are one of the most layout-sensitive parts of the SDK.
- Always validate the available byte count before casting proof tails.
- Use the header helper, not `sizeof`, to reason about how many bytes the proof consumes.
