Zum Hauptinhalt springen

Merkle-Beweise

Jede Auflösung, die die API zurückgibt, kommt mit einem Merkle-Beweis. Damit können Sie die Antwort gegen einen Zustands-Root prüfen, statt dem Server zu vertrauen, der sie geschickt hat.

Der Baum

PiNS hält alle Namen in einem kompakten Sparse Merkle Tree über einem 128-Bit-Schlüsselraum. Der Schlüssel eines Namens sind die ersten 16 Bytes von SHA-256(domain_name), sodass sich Namen gleichmäßig verteilen und niemand bestimmen kann, wo sein Name landet.

„Kompakt“ heißt: Ein Blatt sitzt auf der geringsten Tiefe, in der sein Schlüsselpräfix eindeutig ist, statt auf einer festen Tiefe von 128. In einem Baum mit einigen tausend Namen bestehen die meisten Beweise nur aus einem guten Dutzend Hashes — klein genug, um sie auf einem Telefon, in einer Browsererweiterung oder in einer Wallet zu prüfen.

Zwei Konsequenzen, die man kennen sollte, bevor man einen Verifizierer schreibt:

  • Die Beweislänge variiert. Lesen Sie proof_depth aus der Antwort; nehmen Sie nie eine feste Größe an.
  • Ein leerer Teilbaum ist auf jeder Höhe 32 Nullbytes. Der Root eines leeren Baums besteht daher aus lauter Nullen — ein frisch initialisierter Indexer, der 0000…0000 meldet, ist korrekt und nicht defekt.

Was ein Beweis enthält

FeldBedeutung
merkle_proofGeschwisterhashes, [0] am tiefsten (dem Blatt am nächsten)
proof_depthAnzahl der Geschwister — muss merkle_proof.length entsprechen
proof_terminalwas am Ende des Pfads steht: Occupied, Vacant oder Blocked
smt_rootder Root, den diese Geschwister rekonstruieren

Anwesenheit und Abwesenheit

Erst das Terminal erlaubt es einem Beweis, „dieser Name ist nicht registriert“ ebenso überzeugend zu sagen wie „er ist es“:

  • Occupied — am Ende des Pfads steht das eigene Blatt des Schlüssels. Der Name existiert, und der Datensatz, den Sie erhalten haben, ist der im Baum.
  • Vacant — dort steht ein leerer Teilbaum. Der Name ist nicht registriert.
  • Blocked — an dieser Position steht das Blatt eines anderen Namens. Der Name ist nicht registriert; die Antwort enthält den blockierenden Datensatz, sodass Sie prüfen können, dass er zum dort gefundenen Blatt hasht und dass sein Schlüssel das Präfix tatsächlich teilt.

Ohne Blocked könnte ein Indexer eine Registrierung verbergen, indem er einen Platz für leer erklärt. Da der blockierende Datensatz vollständig enthalten ist, können Sie die Behauptung prüfen, statt sie hinzunehmen.

Prüfen

Hashen Sie den Datensatz zu einem Blatt und falten Sie dann die Geschwister zurück zum Root, wobei die Bits des Schlüssels bei jedem Schritt über links oder rechts entscheiden. Kommen Sie bei smt_root an, ist der Datensatz genau das, worauf sich der Baum festlegt.

Eine Frage bleibt: Ist smt_root der echte Root? Beantworten Sie sie, indem Sie den Anchor-Vertrag auf der BNB Smart Chain fragen. Beide Schritte, mit getestetem Code in Python, PHP und JavaScript, stehen unter Beweise prüfen.