Nachweis der Existenz von Protokollen für die Blockchain

Um dies vorwegzunehmen: Ich bin mir nicht ganz sicher, ob diese Frage Sinn macht. Nur ein Gedanke, den ich hatte, den ich auf Machbarkeit prüfen wollte.

Ich bin mir ziemlich sicher, dass es möglich ist, einen Merkle-Beweis zu verwenden, um zu zeigen, dass eine Transaktion in einem Block enthalten war, und ich frage mich, ob dies auch mit Protokollen möglich ist.

Wäre es im Wesentlichen möglich zu beweisen, dass ein Protokoll erstellt wurde, indem ein Merkle-Beweis von entweder 1) der Transaktion, die das Protokoll erstellt hat, oder 2) dem Protokoll beigefügt wird (ich weiß, dass Protokolle anders gespeichert werden als Transaktionen, daher bin ich mir nicht sicher). ist überhaupt möglich).

Könnte es im Wesentlichen einen Beweis für einen Vertrag geben, dass ein Protokoll durch eine Transaktion in einem bestimmten Block generiert wurde?

Antworten (4)

Update: https://github.com/PISAresearch/event-proofs hat etwas Code. Aus seiner Readme:

Ereignisbeweise

Ein POC, um zu untersuchen, wie Ethereum-Protokolle in einem Smart Contract verifiziert werden könnten. Beweise werden mit eth-proof erstellt und mit der Merkle Patricia Tree-Implementierung von Peace Relay verifiziert. Wenn Sie die Tests gegen Infura ausführen, seien Sie geduldig mit ihnen, da das Generieren von Beweisen viele RPC-Aufrufe erfordert.


Ursprüngliche Antwort:

Ja , ein Merkle-Nachweis einer Transaktionsquittung kann verwendet werden, um die Existenz von Protokollen zu überprüfen.

Ein Ethereum-Block-Header hat die Merkle-Wurzel des (Transaktions-) Quittungstrie.

Ein Transaktionsbeleg enthält alle Protokolle .

Durch Hashing des Transaktionsbelegs und der Hashes, die den Merkle-Beweis enthalten, kann der resultierende Hash mit der Merkle-Wurzel im Header verglichen werden. Eine Übereinstimmung würde anzeigen, dass das Protokoll vorhanden ist.

Beschreibung aus dem Yellow Paper:

Jede Quittung, die für die i-te Transaktion mit BR[i] bezeichnet wird, wird in einen indexverschlüsselten Trie gestellt, und die Wurzel wird im Header als He aufgezeichnet. Der Transaktionsbeleg ist ein Tupel aus vier Elementen, bestehend aus dem Zustand nach der Transaktion, Rσ, dem kumulativen Gas, das in dem Block verwendet wird, der den Transaktionsbeleg enthält, unmittelbar nachdem die Transaktion stattgefunden hat, Ru, dem Satz von Protokollen, die durch die Ausführung der Transaktion erstellt wurden , Rl und der Bloom-Filter, der sich aus Informationen in diesen Protokollen zusammensetzt ...:

In https://blog.ethereum.org/2015/11/15/merkling-in-ethereum gab Vitalik Buterin ein Beispiel für die Verwendung von Quittungen sowie andere Beispiele, die mit Merkle-Beweisen beantwortet werden können:

  • Wurde diese Transaktion in einen bestimmten Block aufgenommen?
  • Nennen Sie mir alle Instanzen eines Ereignisses vom Typ X (z. B. ein Crowdfunding-Vertrag, der sein Ziel erreicht), das von dieser Adresse in den letzten 30 Tagen ausgegeben wurde
  • Wie hoch ist der aktuelle Saldo meines Kontos?
  • Existiert dieses Konto?
  • Geben Sie vor, diese Transaktion für diesen Vertrag auszuführen. Was wäre die Ausgabe?

Die erste wird vom Transaktionsbaum gehandhabt; die dritte und vierte werden vom Zustandsbaum und die zweite vom Empfangsbaum behandelt . Die ersten vier sind ziemlich einfach zu berechnen; Der Server findet einfach das Objekt, holt den Merkle-Zweig (die Liste der Hashes, die vom Objekt zur Baumwurzel aufsteigen) und antwortet dem Light-Client mit dem Zweig zurück.

Der fünfte wird ebenfalls vom Zustandsbaum behandelt, aber die Art und Weise, wie er berechnet wird, ist komplexer. Hier müssen wir einen sogenannten Merkle-Zustandsübergangsbeweis konstruieren ...

Vitalik hielt auch eine Präsentation auf der DevCon1 und einen Abschnitt über Protokolle:

https://www.youtube.com/watch?v=gjwr-7PgpN8&t=2106

Ich habe versucht, genau dieses Problem zu lösen und einen Proof of Concept geschrieben, der dies tun kann:

https://github.com/figs999/Ethereum/blob/master/EventStorage.sol

Grundsätzlich benötigen Sie zwei Komponenten: 1: Eine Möglichkeit, die Gültigkeit eines Blockheaders zu lesen und zu bestätigen. 2: Eine Möglichkeit, den Bloomfilter auf das Vorhandensein eines Protokolleintrags zu überprüfen

In meinem Proof of Concept ruft ein Client, um einen Protokolleintrag aufzunehmen und seine Gültigkeit zu bestätigen, eine Methode auf und übergibt sowohl den RLP-codierten Blockheader, aus dem das Protokoll stammt, als auch den Inhalt des Protokolls selbst.

Der RLP-codierte Header wird im Vertrag decodiert. Nach der Dekodierung kann der korrekte Block-Hash für diesen Block über block.blockhash abgerufen werden. Sie vergleichen dann einfach den keccak256-Hash der rlp-codierten Header-Bytes und den echten Hash, wenn sie übereinstimmen, ist der Header gültig.

Sobald Sie einen gültigen Header haben, können Sie die Protokollblüte daraus lesen. Die Protokollblüte ist eine 256-Byte-Zahl, die überprüft werden kann, um das Vorhandensein eines Protokolls zu bestätigen, solange Sie die Adresse des Vertrags kennen, der das Protokoll geschrieben hat, die Signatur des Protokollereignisses und alle Themen, die das Protokoll enthält.

Der Trick zum Validieren eines bestimmten Blobs von Protokolldaten daraus besteht darin, den protokollierten Datenblob als Protokollwert UND als indiziertes Thema einzuschließen. Wenn Sie es als indiziertes Thema einschließen, ist der keccak256-Hash des Blobs in der Protokollblüte vorhanden.

Das Vorhandensein eines bestimmten Baumstamms in der Baumstammblüte zu überprüfen, ist relativ einfach, erfordert jedoch ein wenig abgefahrene Mathematik, die in Solidität etwas schwierig zu handhaben ist. Mein Beispiel musste für diesen Teil auf die Montage zurückgreifen.

Der Ablauf ist wie folgt:

  1. Rufen Sie die drei Hashes ab, die in der Protokollblüte enthalten sein sollten: den Hash der Vertragsadresse, den Hash des Hashs der Ereignissignatur [keccak256(keccak256("DataStored(bytes,bytes)"]) und den Hash des Hashs von die protokollierten Daten.
  2. Extrahieren Sie für jeden der Hashes die ersten drei Bytepaare. Nennen wir diese [B1,B2,B3]
  3. Prüfen Sie für jedes Bytepaar B das Vorhandensein des Markierungsbits (m) in der Protokollblüte, wobei m = 1<<(B%2048).
  4. Wenn die Protokollblüte alle 9 Bits enthält, die Sie überprüfen, ist das Protokoll (höchstwahrscheinlich) gültig.

Mit dieser Methode können Sie historische Protokolle in einen Smart Contract aufnehmen, um Daten zu validieren oder als Speicherplatz für niedrigere Gaskosten zu fungieren. Der Kompromiss besteht darin, dass die Gaskosten für den Datenabruf/die Datenvalidierung erheblich höher sind.

Ich würde davon abraten, den Bloom-Filter als Beweis dafür zu verwenden, dass Ereignisse passiert sind. Bloom-Filter sind anfällig für Fehlalarme. Sie sind nützlich, um das Scannen von Transaktionen in einem Block zu vermeiden, wenn das gesuchte Ereignis nicht vorhanden ist. Es ist jedoch möglich, dass der Bloom-Filter auf ein Ereignis hinweist, das eingetreten ist, obwohl dies nicht der Fall war. Für das Scannen von Ereignissen bedeutet dies, dass Sie die Transaktionen scannen und nichts finden, was Zeit verschwendet. Wenn Sie es als Beweis dafür verwenden, dass etwas passiert ist, könnte es falsch sein. Jemand könnte ein paar Protokolle erstellen, um den Bloom-Filter dazu zu bringen, ein falsches Positiv zu erzeugen, wodurch Ihre Sicherheit absichtlich gefährdet wird.
Es ist wahr, dass Bloom-Filter falsch positive Ergebnisse haben können, aber ich glaube, dass die Kollisionsrate für diesen speziellen Anwendungsfall ausreichend niedrig sein wird. Die für Ethereum-Protokolle verwendeten Bloom-Filter sind relativ groß, während die Anzahl der Transaktionen, die in einem einzigen Block verarbeitet werden, relativ gering sein wird. Hinzu kommen die Formatanforderungen des Vertrags für die protokollierte Nachricht und die Tatsache, dass Sie das Vorhandensein des Hash-Protokolls in der Blüte prüfen, und die Wahrscheinlichkeit, dass jemand eine sinnvolle Kollision findet, geht gegen Null.
AusIV hat jedoch Recht, dass dies keinen kryptografischen BEWEIS dafür liefern kann, dass das Protokoll vorhanden ist. Sie müssen also die Wahrscheinlichkeit abwägen, dass eine Kollision gefunden wird, und wie unternehmenskritisch Ihr Anwendungsfall ist. Es gibt einige Techniken, die man anwenden kann, um sich weiter gegen Kollisionen zu schützen, z. B. sicherzustellen, dass es kein Feld in Ihrem Protokollformat gibt, das als Nonce verwendet werden könnte (was es ermöglichen würde, Variationen eines falschen Protokolls von einem Angreifer auf Kollisionen zu überprüfen ) oder erfordern, dass die gehashte Größe des Protokolls auch in die Themen aufgenommen wird.
Wenn Sie den Block-Bloom-Filter verwenden, spielt es keine Rolle, ob die Ereignisse im Bloom-Filter aus Ihrem Vertrag stammen. Jemand könnte einen Vertrag konstruieren, der willkürliche Ereignisse ausgibt, die dem Bloom-Filter hinzugefügt werden. Da 9 Bits zu überprüfen sind, könnten sie 9 Ereignisse erstellen, von denen jedes ein relevantes Bit (und 8 irrelevante Bits) setzt. Die Eingaben zu den Ereignissen könnten ziemlich billig außerhalb der Kette berechnet werden, und dann würde der Bloom-Filter ein falsches positives Ergebnis liefern, dass das Ereignis des Vertrags vorhanden war. Sie sind wahrscheinlich ziemlich sicher vor wahrscheinlichen Kollisionen, aber es wäre einfach, Kollisionen zu erstellen.

Dies können Sie ganz einfach mit ProvenDB erreichen . Hier ist ein in Go geschriebener Beispielcode, um die Existenz und den Besitz Ihrer Protokolle auf Blockchain kontinuierlich nachzuweisen: https://github.com/SouthbankSoftware/provenlogs . Hoffe es hilft :P

Transaktionen enthalten Verweise auf alle Protokolle, die während ihrer Ausführung ausgegeben werden, daher denke ich, dass es ausreichen würde, die Existenz oder den Ort der Transaktion selbst zu beweisen.