Überwachung von Ereignissen aus mehreren Verträgen

Ich arbeite an einem Projekt, das es Benutzern ermöglicht, einen bestimmten Vertrag, den ich erstellt habe, automatisch bereitzustellen. Es ist wichtig, dass das System bestimmte Ereignisse (z. B. neue Transaktionen) bei ALLEN bereitgestellten Verträgen überwachen kann.

Hinweis: Ich verwende nodejs über web3 json rpc, um Ereignisse zu überwachen.

Eine mögliche Lösung, an die ich dachte, ist die Verwendung eines Wrapper-Vertrags, der alle Transaktionsanforderungen tunnelt und die Ereignisse selbst sendet. Dies ermöglicht es, nur Ereignisse aus einem einzigen Vertrag abzuhören, aber ich finde diese Lösung nicht sehr elegant.

Gibt es eine effiziente und skalierbare Möglichkeit, dies zu erreichen, ohne einen Listener für jeden einzelnen Vertrag zu erstellen?

Antworten (2)

Es hört sich so an, als ob die Sorge besteht, dass sich die Zuhörer auf eine Weise vermehren könnten, die möglicherweise nicht skaliert wird. Soweit ich weiß, gibt es keine Wunderwaffe, mit der ein einzelner Listener Ereignisse so filtern könnte, wie Sie es benötigen würden. Dieser dritte Weg ist eine Variante der beiden Optionen, die Sie meines Wissens nach in Betracht ziehen.

Erwägen Sie, Transaktionen so zu handhaben, wie Sie es möchten, und logisch zentralisierte Protokollierungsfunktionen hinzuzufügen. Zum Beispiel die Auftragsfabrik. Ordnen Sie die Dinge so an, dass sich werkseitig erstellte Verträge auf die zentralisierten Protokollierungsfunktionen statt auf interne Ereignisemitter verlassen.

Wenn Sie haben:

contract Factory { ...
contract Created {
  event LogSomething(bytes32 Id); 
  ...
  LogSomething(Id);

Neu anordnen als

contract Hub {
  event LogSomething(address contract, bytes32 Id);
  ...
  function logSomething(bytes32 Id);
    LogSomething(msg.sender, Id); // msg.sender will be the "spoke" that called Hub function.

contract Created{ 
   ...
   function important(bytes32 id) {
      .. 
      Hub.logSomething(Id);

Factory sollte wahrscheinlich Hub genannt werden, falls man sich auf sie für mehr als nur Prägeverträge verlässt.

Ich hoffe es hilft.

Anfangs dachte ich, dass wir auch Ereignisse überwachen wollen, die von Verträgen generiert werden, die außerhalb des Systems eingesetzt werden, aber ich denke, das könnte zu viel sein und vielleicht nicht einmal notwendig sein. Die von Ihnen vorgeschlagene Lösung könnte also tatsächlich für uns funktionieren. Vielen Dank!
Jetzt, wo ich genauer darüber nachdenke, könnte es immer noch ein Problem sein, denn das bedeutet, dass jeder Ereignisse vom Hub ohne die Erlaubnis des Hubs versenden kann. Eine Möglichkeit, dies zu lösen, wäre, den Hub eine Liste von Verträgen führen zu lassen, denen es erlaubt ist, den Protokollierungsmechanismus des Hubs zu verwenden, aber ich bin mir nicht sicher, ob dies als saubere Lösung akzeptiert wird. Ist es?
Mit der Sicherung hast du recht. Beim weiteren Nachdenken wurde mir klar, dass es schwer zu sagen ist, ob Ihre App einen einzigen Vertrag, ein Hub & Spoke oder etwas anderes verwenden sollte. Ich würde eher zustimmen, dass es ein Zeichen dafür ist, dass die Dinge aus dem Ruder laufen, wenn es zu kompliziert wird.
Es gibt einen anderen Weg zu prüfen. Sie können eine aktualisierbare Vertragsstruktur verwenden, die Daten getrennt von der Anwendungslogik durch einen Vertrag für Datenverantwortliche überträgt. Möglichkeit des zentralen Logins dort.
Protokollieren Sie als allgemeine Faustregel alle Zustandsänderungen innerhalb von Verträgen und stellen Sie auch Getter und iterierbare Datenstrukturen bereit. Es wäre nicht besonders schwierig, ein Berechtigungssystem zu erstellen, damit nur Nachkommen auf eine zentralisierte Funktion zugreifen können.
Ja, ich habe über einen zentralen Daten-/Protokollierungsvertrag nachgedacht, aber das Sicherheitsproblem scheint auf diese Weise noch schwieriger zu implementieren - wenn der Protokollierungsvertrag nicht auch die Vertragsfabrik ist, kann er nicht einmal sagen, welche Verträge seine Einrichtungen nutzen dürfen.
Sie können eine Registrierung von autorisierten Benutzern haben. Es ist eine natürliche Erweiterung einer Fabrik, die die erstellten Verträge verfolgt. Dieser Hub ist ziemlich nah dran: ethereum.stackexchange.com/questions/10878/… . Wenn wir eine Hub-Funktion wollten, auf die nur die untergeordneten Verträge (im Beispiel Personen) zugreifen können, könnten wir einen Modifikator haben: modifier onlyPerson() { if(persontIndex[personMap[msg.sender]] != msg.sender) throw ; _; // Dies ist wahr, wenn der Hub den msg.sender erstellt hat. } Hoffe, es ist hilfreich.
Ja, das meinte ich im 2. Kommentar - also scheint es dann eine legitime Lösung zu sein. Vielen Dank!

web3.eth.filter() (die Low-Level-Methode, nicht die Art, die Sie von Vertragsobjekten erhalten können) ermöglicht es, eine Liste von Adressen anzugeben, die mit einem Filter überwacht werden sollen. Sie müssen die Themen manuell interpretieren, aber das sollte nicht allzu schwierig sein.

Es ist etwas schwieriger, darauf zu achten, wann ein Vertrag erstellt wird (damit Sie wissen, auf welche Adressen Sie hören müssen). Sie können die gleiche Methode verwenden, ohne eine Liste von Adressen anzugeben, und dann das topicsArgument verwenden, um sicherzustellen, dass Sie nur Ereignisse aus Verträgen erhalten , die vorgeben , Ihnen zu gehören. Die Unterscheidung ist wichtig – jeder kann ein Ereignis dazu bringen, alles zu sagen, daher wäre es ratsam, zu überprüfen, ob es aus einem Vertrag stammt, der Ihren Code enthält.

In meinem speziellen Fall halte ich es für sinnvoll, nur Ereignisse abzufangen, die von Verträgen generiert werden, die über das System erstellt wurden, sodass dies einfacher sein sollte. Es ist jedoch immer noch nicht großartig, mehrere Adressen abhören zu müssen, da dies schließlich wachsen kann und wir dann wieder das Problem der Skalierbarkeit haben.