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

# Receipt Attestation (EAS)

> Learn the EAS schema behind a Usage Root, how salting keeps epoch totals private, and how the publisher avoids double-attesting.

Signed receipts become an on-chain Usage Root through one EAS attestation per `(epoch, subject_wallet, subject_epoch)`. The pattern comes from Dojang.

## The pattern: Dojang's Balance Root, applied to usage

Dojang (도장, the seal) is GIWA's attestation system. One of its schema pairs is a ready-made template for proving private per-user numbers against a public commitment:

* **Balance Root**: one attestation per `(coinType, snapshotAt)` carrying a Merkle root over all users' balances at a snapshot.
* **Verified Balance**: a per-user Merkle proof against that root, provable without revealing anyone else's balance.

Tokscale applies the same commitment idiom to AI usage. The Usage Root mirrors the Balance Root; the per-receipt inclusion proof mirrors the Verified Balance. It is Dojang's own design language, readable by anyone who already understands GIWA attestations. See [Dojang: On-Chain Attestations](/builder-passport/dojang).

## The attestation: an eight-word data tuple

There is no global cross-builder root: the EAS `recipient` is the builder's wallet, and wallet-bound leaves prove membership for that Passport only. The schema string is:

```text theme={null}
bytes32 receiptRoot,uint64 epoch,uint32 subjectEpoch,uint32 receiptCount,bytes32 summaryCommitment,bytes32 dojangAttesterId,bytes32 dojangVerifiedAddressUid,uint16 schemaVersion
```

ABI-encoded, this is eight 32-byte words:

| Field                                           | Meaning                                                                                    |
| ----------------------------------------------- | ------------------------------------------------------------------------------------------ |
| `receiptRoot`                                   | Merkle root over the subject's signed receipts this epoch                                  |
| `epoch`                                         | The gateway usage epoch                                                                    |
| `subjectEpoch`                                  | The builder's own epoch counter (a wallet change starts a new subject epoch)               |
| `receiptCount`                                  | Number of leaves under the root                                                            |
| `summaryCommitment`                             | Salted commitment to the epoch's totals (below)                                            |
| `dojangAttesterId` / `dojangVerifiedAddressUid` | Optional Dojang context captured at publication; zero means no Dojang reference            |
| `schemaVersion`                                 | Schema evolution counter; any layout change registers a new schema UID and increments this |

The attestation is non-revocable, has no resolver, and evolves only by new schema registration: EAS schema content participates in the schema UID, so a changed layout is a new schema, never an in-place upgrade.

## Leaves, salt, and the provable tier

Membership leaves bind each receipt to one wallet and one subject epoch:

```text theme={null}
leafDomain = keccak256("TOKSCALE_RECEIPT_LEAF_V1")
leaf       = keccak256(abi.encode(leafDomain, receiptDigest, subjectWallet, subjectEpoch))
```

Privacy comes from what stays off the chain. Per-request model and cost data never leaves the holder's receipt payload. On-chain, the epoch's totals sit behind a salted commitment:

```text theme={null}
summaryCommitment = keccak256(abi.encode(totalTokens, costUsd1e4, uint8(1), salt))
```

The salt stays server-side, so the public anchor reveals the root and the count but not the totals. A builder who wants to disclose totals reveals them with the salt, and anyone can recompute the commitment.

The `uint8(1)` discriminator is the `gateway-observed-v1` protocol code: the class of evidence behind the root is committed on-chain, not asserted in copy. A tier-in-the-leaf design, `leaf = hash(builderAddr, tokens, cost, tier, receiptRoot, salt)`, would make the verification tier part of the committed data so the tier itself is provable; the frozen V1 implementation instead carries that evidence class as the protocol discriminator inside `summaryCommitment` and keeps leaves minimal (digest, wallet, subject epoch). Either way, a verifier checks the class cryptographically rather than trusting a label. The five-tier vocabulary is defined in [Verified Usage and the Evidence Ladder](/builder-passport/evidence-ladder).

## The attestation worker pipeline

The publisher is a background worker following the reconciler pattern: its own pool, an advisory lock, and exactly one replica publishing.

<Steps>
  <Step title="Check cryptographic eligibility">
    Before a receipt commitment can enter a candidate set, the worker recomputes the fixed V1 typed data and digest and verifies a canonical low-S ECDSA signature against the versioned production signer registry. The registry excludes the local Anvil fixture signer. A job state of `issued`, a 65-byte blob, or a digest-shaped value is never proof; a poisoned row yields no candidate.
  </Step>

  <Step title="Construct the root">
    Per `(epoch, subject_wallet, subject_epoch)`, collect commitments, order leaves by raw RFC 4122 UUID bytes, and build the `receiptRoot`.
  </Step>

  <Step title="Persist the durable intent outbox">
    Write the intent before broadcast, keyed unique on `(epoch, subject_wallet, subject_epoch, eas_schema_uid)`. A submit timeout is `pending`, never permission to issue a second attestation for the epoch.
  </Step>

  <Step title="Publish and reconcile">
    Broadcast one `attest()` call, retain the transaction nonce and hash, and reconcile the receipt and canonical block before recording the EAS UID.
  </Step>

  <Step title="Persist the proof">
    Store the attestation UID, transaction hash, root, leaf version, and the ordered leaves or proofs so the public proof page survives retention and project deletion.
  </Step>
</Steps>

The worker and its vector suite are covered by the three-language vectors described in [UsageReceiptV1](/gateway/usage-receipt-v1):

```sh theme={null}
bun run attestation-vectors:verify
# runs: cargo test -p giwa-onchain --test attestation_vectors
#       bun attestation-vectors:verify (viem)
#       forge test --match-contract ReceiptAttestationV1Test
```

## Next steps

* For the receipt format that feeds the leaves, see [UsageReceiptV1](/gateway/usage-receipt-v1).
* For the attestation rail this schema publishes onto, see [Dojang: On-Chain Attestations](/builder-passport/dojang).
* To verify one receipt against a published root, see [Verifying a Receipt](/builder-passport/verify-a-receipt).
* For what is anchored on the public chain today, see [Live Evidence](/overview/live-evidence).
