Loading vLEI.wiki
Fetching knowledge base...
Fetching knowledge base...
This comprehensive explanation has been generated from 176 GitHub source documents. All source documents are searchable here.
Last updated: October 7, 2025
This content is meant to be consumed by AI agents via MCP. Click here to get the MCP configuration.
Note: In rare cases it may contain LLM hallucinations.
For authoritative documentation, please consult the official GLEIF vLEI trainings and the ToIP Glossary.
A receipt in KERI is a cryptographically signed message that acknowledges observation of a key event, consisting of a reference to the event (via identifier, sequence number, and digest) along with one or more witness signatures, serving as proof that designated witnesses have validated and recorded the event.
A receipt (also called a key event receipt) is a fundamental data structure in KERI that provides cryptographic proof of event observation by witnesses or validators. The receipt serves as an acknowledgment mechanism where designated parties attest to having received, validated, and recorded a specific key event.
A receipt consists of two essential parts:
Event Reference: The body of the receipt message contains identifying information about the key event being receipted:
Cryptographic Attestations: The attachments section contains one or more signatures from witnesses or validators, proving they have observed and validated the referenced event.
Receipts serve multiple critical functions in KERI's architecture:
Implementations must maintain separate storage for:
Use efficient indexing on (identifier, sequence number) tuples for fast retrieval.
Receipts may arrive out of order due to network conditions. Implementations should:
When verifying receipts:
Batch Verification: When processing multiple receipts, batch cryptographic operations:
# Batch signature verification
signatures_to_verify = [(receipt.body, sig, pubkey) for receipt, sig, pubkey in batch]
results = crypto.verify_batch(signatures_to_verify)
Caching: Cache witness public keys to avoid repeated KEL lookups:
witness_key_cache = LRUCache(maxsize=1000)
Duplicity Detection: When receiving conflicting receipts from the same witness:
if existing_receipt.digest != new_receipt.digest:
log_duplicity_event(witness_aid, event_seq, [existing_receipt, new_receipt])
trigger_duplicity_alert()
Invalid Receipts: Log but don't fail on invalid receipts from individual witnesses—other witnesses may provide valid receipts.
Receipt Promulgation: Witnesses should broadcast receipts to:
Use efficient multicast or pub-sub patterns for large witness pools.
Receipts follow KERI's standard message format using CESR (Composable Event Streaming Representation) encoding. The structure includes:
Receipt Message Body (JSON serialization example):
{
"v": "KERI10JSON0000ed_",
"t": "rct",
"d": "ELvaU6Z-i0d8JJR2nmwyYAZAoTNZH3UfSVPzhzS6b5CM",
"i": "EH7Oq9oxCgYa-nnNLvwhp9sFZpALILlRYyB-6n4WDi7w",
"s": "3"
}
Field Definitions:
v: Version string indicating KERI protocol version and serialization formatt: Message type, always "rct" for receipts (or "vrc" for validator receipts)d: Digest (SAID) of the event being receiptedi: Identifier of the controller whose event is being receipteds: Sequence number of the event (hexadecimal encoding for values >9)Signature Attachments: Following the message body, receipts include CESR-encoded signature attachments:
-AAB
AA<base64-signature-from-witness-1>
AB<base64-signature-from-witness-2>
The -AAB prefix is a CESR count code indicating the attachment type and count.
Receipts use CESR's dual text-binary encoding:
Witness Receipt Generation:
Controller Receipt Collection:
Controllers collect receipts from their designated witness pool to achieve the threshold of accountable duplicity (TOAD). Once sufficient receipts are gathered, the event is considered "established" within the witness network.
Receipts are immutable once created. They represent a specific witness's observation of a specific event at a specific point in time. However, the collection of receipts for an event can grow:
Receipt Verification Process:
Duplicity Detection:
When validators receive multiple receipts from the same witness for events at the same sequence number but with different digests, this indicates duplicitous behavior by either the controller or the witness. This is a critical security event that triggers duplicity detection protocols.
KERI Indirect Mode:
Receipts are fundamental to KERI's indirect mode operation, where controllers designate witnesses to provide high availability and distributed consensus. The receipt mechanism enables:
Direct Mode Receipts:
Even in direct mode, where controllers exchange events peer-to-peer, receipts serve as acknowledgments. The receiving controller acts as a validator and may generate receipts to confirm event observation.
Transaction Event Logs (TELs):
Receipts also apply to TEL events for credential issuance and revocation, where registrars (analogous to witnesses) receipt transaction events.
Receipt Storage:
Receipt Retrieval:
Validators query witnesses for receipts using KERI's query protocol:
{
"v": "KERI10JSON000091_",
"t": "qry",
"d": "EaU6JR2nmwyZ-i0d8JZAoTNZH3ULvYAfSVPzhzS6b5CM",
"dt": "2024-01-15T10:30:00.000000+00:00",
"r": "logs",
"rr": "",
"q": {
"i": "EH7Oq9oxCgYa-nnNLvwhp9sFZpALILlRYyB-6n4WDi7w",
"s": "5"
}
}
Witnesses respond with the requested event and all associated receipts.
Key Event Logs (KELs):
Receipts are intimately connected to KELs. A KEL without receipts is just a sequence of self-signed events. Adding receipts transforms it into a KERL, providing distributed validation.
Key Event Messages:
Receipts reference key event messages. The relationship is:
Witness Lists:
Each establishment event (inception or rotation) specifies a witness list. Receipts must come from witnesses in this list to be valid for that event.
Duplicity Event Logs (DELs):
When receipts reveal duplicity (multiple receipts from the same witness for conflicting events), this information is recorded in a DEL for that identifier.
When receipting events from multi-sig AIDs, receipts may use indexed signatures to indicate which specific witness provided the receipt. This is particularly important when witness pools contain multiple witnesses.
KERI implementations maintain escrow databases for receipts that arrive before their corresponding events (due to network asynchrony). These receipts are held until the referenced event arrives, then processed.
While individual receipts don't chain to each other, the collection of receipts for sequential events creates an implicit chain of witness observations, providing a verifiable history of witness participation.
Receipts themselves are not transferable—they represent a specific witness's observation at a specific time. However, they receipt both transferable and non-transferable identifiers.
Receipts provide:
Replay Attacks: Receipts include sequence numbers and event digests, preventing replay of old receipts for new events.
Forgery: Without access to a witness's private key, attackers cannot forge valid receipts.
Duplicity: The receipt mechanism itself enables duplicity detection—conflicting receipts from the same witness expose malicious behavior.
CREATE TABLE receipts (
id SERIAL PRIMARY KEY,
event_identifier TEXT NOT NULL,
event_sequence INTEGER NOT NULL,
event_digest TEXT NOT NULL,
witness_aid TEXT NOT NULL,
signature BYTEA NOT NULL,
received_at TIMESTAMP DEFAULT NOW(),
INDEX idx_event (event_identifier, event_sequence),
INDEX idx_witness (witness_aid),
UNIQUE (event_identifier, event_sequence, witness_aid)
);
Unit Tests: Test receipt generation, verification, and storage independently
Integration Tests: Test receipt exchange between witnesses in a simulated network
Duplicity Tests: Verify that conflicting receipts are properly detected and logged
Performance Tests: Measure receipt processing throughput under load