Anleitungen · Teil 6 von 6
Aufnahmezertifikate
Du hast eine Merkle-Wurzel unter Label 309 veröffentlicht und dazu die off-chain Blätterliste, die ihr zugrunde liegt. Diese Wurzel ist eine vollkommen solide Festlegung — aber nichts, das du einer Kollegin in die Hand drücken, an einen Vertrag anhängen oder einem Gerichtsschriftsatz beilegen könntest. Genau diese Übergabe leistet ein Aufnahmezertifikat: eine kleine, in sich geschlossene Datei, die ein oder mehrere Blätter an die veröffentlichte Wurzel bindet, jeden zur Neuableitung dieser Wurzel nötigen Geschwisterknoten einbettet und die Cardano-Transaktion benennt, deren Blockzeitpunkt das Ganze bezeugt. Jede und jeder kann es offline verifizieren, gegen jeden beliebigen Explorer, ohne Konto und ohne Vertrauen in die Person, die es erstellt hat.
Wenn dir OpenTimestamps geläufig ist: Es ist dieselbe Idee — eine portable
Quittung über einen Existenznachweis — mit zwei bewussten Unterschieden. Die
Zeitstempel-Autorität ist die Blockzeit der Cardano-Blockchain, kein
Kalender-Server. Und der Nachweis wird vollständig clientseitig erzeugt und
verifiziert: kein Gateway, kein Aussteller-Server, an keiner Stelle Vertrauen in
uns. Es ist das Existenznachweis-Pendant zu einer .ots-Datei, auf Cardano
verankert und eigenständig verifizierbar.
Was ein Zertifikat beweist — und was nicht
Ein Zertifikat erhebt genau zwei kryptografische Behauptungen, jede von jeder und jedem unabhängig überprüfbar:
- Aufnahme. Ein gegebenes
leafsitzt an Positionindexeines RFC 9162-SHA-256-Merkle-Baums der Größetree_size, dessen Wurzelrootist. Bewiesen wird dies, indem die Wurzel aus dem Blatt, seinem Index, der Baumgröße und dem eingebetteten Geschwisterpfad neu berechnet wird. Das ist in sich geschlossen — die Zertifikatsdatei allein genügt. - Verankerung. Diese
roottaucht wortgleich im Feldmerkle[].rootdes Label-309-Datensatzes auf, den die Transaktiontx_hashträgt. Bewiesen wird dies, indem man diese Transaktion auf irgendeinem öffentlichen Cardano-Explorer ausliest und die Bytes vergleicht. Dafür braucht es die Zertifikatsdatei plus einen Explorer — sonst nichts.
Zusammen beweisen sie, dass der Inhalt des Blattes zu oder vor dem
Blockzeitpunkt von tx_hash existierte.
Was ein Zertifikat NICHT beweist
Die Zeit wird von der öffentlichen Blockchain behauptet, nicht kryptografisch in den Nachweis eingebunden — genau wie bei OpenTimestamps und Chainpoint vertraust du der Blockzeit der Chain, niemals der Person, die das Zertifikat erstellt hat. Ein Zertifikat ist kein eIDAS-„qualifizierter" elektronischer Zeitstempel (RFC 3161 / eine qualifizierte TSA); es ist ein blockchain-verankerter Zeitstempel — ein starkes, untermauerndes Beweismittel für eine zeitliche Behauptung, in derselben Kategorie wie andere Blockchain-Zeitstempel, und der Wortlaut in der Datei sagt genau das. Es sagt nichts darüber aus, wer den Inhalt verfasst hat (das ist eine optionale Datensatzsignatur — siehe Signaturen), und es beweist nicht, dass der Inhalt nicht schon früher bekannt war. Es beweist Existenz bis zu einem Stichtag, nicht Urheberschaft und nicht Neuheit.
Warum der Nachweis unsigniert ist
Eine strikte IETF-COSE-Quittung ist ein COSE_Sign1, dessen Payload die
Merkle-Wurzel ist, signiert von einer Autorität. Hier ist die Autorität die
Blockchain, kein Schlüssel, den wir besitzen — die Wurzel mit unserem
Schlüssel zu signieren würde also Server-Vertrauen wiedereinführen und die
Eigenschaft der eigenständigen Verifizierbarkeit brechen, auf der der gesamte
Standard ruht. Stattdessen gibt das Zertifikat die IETF-CBOR-Struktur des
Aufnahmebeweises exakt wie spezifiziert aus und trägt den Blockchain-Anker
anstelle der Signatur. Die Beweismathematik ist byteidentisch mit der
IETF-Kodierung; sie ist bewusst unsigniert und blockchain-verankert.
Das JSON-Zertifikat
Das primäre Artefakt ist label-309-inclusion-certificate-v1: eine sowohl für
Menschen als auch für Maschinen lesbare JSON-Datei. Eine Datei deckt ein ODER
viele Blätter ab, und jeder Eintrag bettet seinen vollständigen Geschwisterpfad
ein, sodass die Datei für immer neu verifizierbar bleibt — kein Arweave-Abruf,
kein Gateway, kein ursprünglicher Veröffentlicher nötig.
{
"format": "label-309-inclusion-certificate-v1",
"generated_at": "2026-06-16T12:00:00.000Z", // informational only, never trusted
"anchor": {
"chain": "cardano",
"network": "mainnet",
"tx_hash": "…64hex…",
"metadata_label": 309,
"block_time": 1781611200, // POSIX seconds — explorer-asserted
"block_time_iso": "2026-06-16T12:00:00.000Z",
"block_height": 12345678, // optional; explorer-asserted
"explorer_urls": [
"https://cardanoscan.io/transaction/…",
"https://adastat.net/transactions/…"
]
},
"merkle": {
"tree_alg": "rfc9162-sha256",
"root": "…64hex…",
"tree_size": 1024, // === the on-chain leaf_count
"leaves_list_uri": "ar://<txid>" // optional source reference
},
"items": [
{
"leaf": "…64hex…", // the content hash committed as a leaf
"leaf_alg": "sha2-256", // how to hash a file to reproduce `leaf`
"index": 42,
"proof": ["…64hex…", "…64hex…"], // siblings, leaf→root; [] for a single-leaf tree
"verified": true, // proof recomputes to merkle.root at build time
"label": "contract.pdf" // optional note/filename
}
],
"claim": "Each listed hash was included in a Merkle tree whose root was published on the Cardano blockchain in the referenced transaction under metadata label 309; therefore each hash provably existed on or before the stated block time.",
"verification": {
"method": "RFC 9162 (Certificate Transparency) SHA-256 inclusion proof. For each item, recompute the Merkle root from leaf+index+tree_size+proof and compare to merkle.root; then confirm merkle.root equals the merkle[].root in the label 309 record of anchor.tx_hash on any public Cardano explorer.",
"requires_trust_in_cardanowall": false,
"time_asserted_by": "Cardano blockchain (block time), via public explorers"
}
}Ein paar Details, die zu kennen sich lohnt:
root,leafund jeder Eintrag vonproof[]sind rohe 32-Byte-Werte, dargestellt als Hex. Erzeuger geben Kleinbuchstaben aus; ein Verifizierer akzeptiert beide Schreibweisen und weist jedes Nicht-Hex-Zeichen oder jede Zeichenkette ungerader Länge zurück.- Das gespeicherte
"verified": trueist das Ergebnis des Erzeugers zur Erstellungszeit. Ein Verifizierer vertraut ihm nie — er berechnet den Beweis selbst neu und meldet sein eigenes Urteil. Ein Blatt, das im Baum nicht gefunden wurde, wird mit"verified": falseund einem"error"-Feld vermerkt, niemals stillschweigend verworfen, damit die Datei über Fehlschläge ehrlich bleibt. block_timeist der vom Explorer behauptete POSIX-Zeitstempel des einschließenden Blocks.block_time_isoist dessen UTC-Darstellung — nur zur Bequemlichkeit.
Der CBOR-Aufnahmebeweis (COSE / RFC 9162-konform)
Neben dem JSON kann jeder Eintrag als kompaktes .cbor-Artefakt exportiert
werden, dessen Beweisstruktur byteidentisch mit
draft-ietf-cose-merkle-tree-proofs
ist. Das bedeutet: Jeder RFC 9162- / COSE-Verifizierer für verifizierbare
Datenstrukturen kann die Beweismathematik direkt lesen — der Interop-Kern ist
standardgemäß, nicht hausgemacht. Es trägt keine absolute Blockzeit und keinen
juristischen Text (das lebt im JSON); es ist nur der portable Beweiskern, und es
ist aus dem oben genannten Grund blockchain-verankert und unsigniert.
Der nackte IETF-Aufnahmebeweis — bstr .cbor [tree_size, leaf_index, inclusion_path], der Wert 1 der verifizierbaren Datenstruktur (vds) für
RFC 9162 SHA-256 — lässt sich für einen reinen COSE-Verifizierer für sich allein
extrahieren; der Cardano-Anker wird daneben als kleine Map anstelle der
Sign1-Signatur getragen.
Erstellen und verifizieren mit dem Werkzeug
Das Zertifikatsformat ist Teil des öffentlichen, Gateway-agnostischen Werkzeugs:
das SDK @cardanowall/sdk-ts (mit byteidentischen Zwillingen in Python und
Rust), die cardanowall CLI und die Verifizierer-Oberflächen in den Apps. Die
Erstellungs- und Verifizierungsmathematik ist rein und offline — nur das
Auflösen frischer Chain-Fakten berührt das Netzwerk.
Mit dem CLI
certificate build nimmt die Blätterliste, die Ziele (rohes Blatt-Hex oder zu
hashende Dateien) und die Transaktion entgegen, deren Anker-Fakten es auflöst.
certificate verify führt den Aufnahmebeweis je Eintrag erneut aus und gibt den
Anker aus, den du noch on-chain bestätigen musst:
# Build a certificate for two files against a published root.
cardanowall certificate build \
--leaves-list leaves.cbor \
--tx <tx-hash> \
--file contract.pdf --file exhibit-a.png \
--out contract.cert.json
# Re-verify the proofs offline — no network, no trust in the producer.
cardanowall certificate verify contract.cert.jsonExit-Code 0 bedeutet, dass sich jeder Eintragsbeweis zur Wurzel neu berechnet;
ein Code ungleich null kennzeichnet einen Aufnahmefehler, fehlerhafte Eingabe
oder einen E/A-Fehler — damit fügt es sich direkt in CI ein. Jeder einzelne
Eintrag lässt sich auch in die kanonische Form
{ tree_alg, tree_size, index, leaf, proof[] } extrahieren und mit
cardanowall merkle verify prüfen.
Mit dem TypeScript-SDK
Die certificate-API ist rein — du holst die Bytes der Blätterliste mit dem
plattformeigenen fetch und reichst sie hinein; der Krypto-Pfad erreicht nie
das Netzwerk:
import { certificate, merkle } from '@cardanowall/sdk-ts';
// `leaves` comes from decodeLeavesList(...) over the fetched leaves-list bytes.
const cert = certificate.buildInclusionCertificate({
anchor, // chain facts resolved from the tx
merkle: { treeAlg: 'rfc9162-sha256', root, treeSize: leaves.length },
leaves,
targets: [{ leaf, leafAlg: 'sha2-256', label: 'contract.pdf' }],
});
// Pure re-verification from the certificate alone — no Arweave, no chain.
const result = certificate.verifyInclusionCertificate(cert);
console.log(result.ok); // true when every item's proof recomputes to root
console.log(result.anchorClaim); // the anchor you confirm on a public explorer
// Each item also re-verifies through the plain Merkle predicate.
const item = cert.items[0];
const ok = merkle.merkleSha2256VerifyInclusion(
leafBytes, item.index, cert.merkle.tree_size, proofBytes, rootBytes,
);verifyInclusionCertificate meldet das Beweisurteil und gibt den
behaupteten Anker wieder; diesen Anker on-chain zu bestätigen ist dein
separater, expliziter Schritt — das Ergebnisobjekt sagt es dir. Dasselbe Modul
ist Byte für Byte in den Python- (certificate) und Rust- (certificate) SDKs
gespiegelt.
Im Browser, auf einer Transaktionsseite
Ein Label-309-Datensatz, der eine merkle[]-Festlegung trägt, zeigt auf seiner
Transaktionsseite ein Aufnahme-Panel. Füge einen oder mehrere Hex-Hashes ein
oder ziehe die Originaldateien hinein, um sie clientseitig zu hashen; die Seite
holt die Blätterliste direkt aus dem inhaltsadressierten Speicher in deinem
Browser, berechnet jeden Beweis neu, zeigt je Eintrag ein grünes/rotes Urteil
und bietet das JSON, das CBOR und ein druckbares PDF zum Download. Das PDF bettet
das vollständige JSON als Dateianhang ein, sodass es selbst das
maschinenverifizierbare Artefakt ist — nicht nur ein Bild davon. Nichts davon
berührt einen privaten Server.
Der Verifizierungsalgorithmus, von Anfang bis Ende
Um ein Zertifikat unabhängig zu verifizieren — in deinem eigenen Code, ganz ohne Werkzeug von uns — tu genau Folgendes:
- Verwirf fehlerhafte Felder. Jeder
root/leaf/proof[]-Eintrag muss Hex gerader Länge sein, das zu 32 Byte dekodiert;tree_sizeund jederindexmüssen sichere Ganzzahlen mitindex < tree_sizeund1 ≤ tree_size ≤ 2³² − 1sein. - Berechne die Wurzel jedes Eintrags neu. Falte gemäß RFC 9162 §2.1.3.2 das
Blatt (
leaf = SHA-256(0x00 ‖ leaf_digest)) mit seinem Geschwisterpfad (node = SHA-256(0x01 ‖ L ‖ R)), wobei du an der größten Zweierpotenz strikt unterhalb der laufenden Teilbaumgröße aufspaltest, und vergleiche das Ergebnis Byte für Byte mitmerkle.root. Ein Baum mit einem einzigen Blatt hat einen leeren Beweis. - Bestätige den Anker on-chain. Rufe
anchor.tx_hashauf irgendeinem öffentlichen Cardano-Explorer ab, lies seine Label-309-Metadaten und bestätige, dassmerkle.rootgleich demmerkle[].rootdes Datensatzes ist. Die Blockzeit, die du dort abliest, ist der Zeitstempel, den das Zertifikat behauptet.
Schritte 1–2 sind der in sich geschlossene Teil — sie verlassen deine Maschine nie. Schritt 3 ist der eine Netzwerk-Lesevorgang, und er geht an einen Explorer deiner Wahl, niemals an die Person, die das Zertifikat erstellt hat.
Eine Datei, für immer verifizierbar
Weil jeder Geschwisterknoten auf dem Pfad eingebettet ist, verifiziert ein Zertifikat noch lange weiter, nachdem die Blätterliste, das ursprüngliche Gateway oder der Erzeuger verschwunden sind. Die zwei Prüfungen — die Wurzel aus der Datei neu berechnen, die Wurzel on-chain bestätigen — sind alles, was jemals jemand braucht. Wie Wurzel und Blätterliste überhaupt erst entstehen, beschreibt Stapelweise mit Merkle, und Verifizierung zeigt das vollständige Verifizierer-Modell, in das sich die Chain-seitige Prüfung einfügt.