Abonnieren von Events in Moonbase Alpha

Einleitung

Dmytriiev Petro
Moonbeam-DE translations
6 min readJul 29, 2021

--

Die Möglichkeit, Ethereum-Stil Events zu abonnieren, wurde mit der Veröffentlichung von Moonbase Alpha v2 hinzugefügt. In dieser Anleitung werden die verfügbaren Abonnementtypen und die aktuellen Einschränkungen beschrieben.

Voraussetzungen Prüfen

Die Beispiele in dieser Anleitung basieren auf einer Ubuntu 18.04-Umgebung. Sie benötigen außerdem Folgendes:

  • Einen Installierten Metamask welcher zu Moonbase verbunden ist
  • Einen Account mit Tokens. Sie können diese von Mission Control bekommen.
  • Einen eigenen ERC-20 Token auf Moonbase basiert haben. Sie können unserem Remix Tutorial folgen nachdem Sie Metamask mit Moonbeam verbunden haben.

Wir müssen Node.js (wir verwenden v15.x) und den npm-Paketmanager installieren. Sie können direkt von Node.js oder in Ihrem Terminal herunterladen:

Ubuntu

curl -sL https://deb.nodesource.com/setup_15.x | sudo -E bash -

sudo apt install -y nodejs

MacOS

# You can use homebrew (https://docs.brew.sh/Installation)

brew install node

# Or you can use nvm (https://github.com/nvm-sh/nvm)

nvm install node

Wir können überprüfen, ob alles richtig installiert ist, indem wir die Version für jedes Paket abfragen:

node -v

npm -v

Zum Zeitpunkt der Erstellung dieser Anleitung waren die verwendeten Versionen 14.6.0 bzw. 6.14.6. Wir müssen auch das Web3-Paket installieren, indem wir Folgendes ausführen:

npm install — save web3

Um die installierte Version von Web3 zu überprüfen, können Sie den Befehl ls verwenden:

npm ls web3

As of writing this guide, the version used was 1.3.0.

Abonnieren von Event Logs in Moonbase Alpha

Jeder Contract, der dem ERC-20-Token-Standard folgt, gibt ein Event aus, das sich auf eine Übertragung von Tokens bezieht, d. h.event Transfer(address indexed from, address indexed to, uint256 value) Für dieses Beispiel abonnieren wir die Protokolle solcher Ereignisse. Mit der web3.js-Bibliothek benötigen wir den folgenden Code:

const Web3 = require(‘web3’);

const web3 = new Web3(‘wss://wss.testnet.moonbeam.network’);

web3.eth.subscribe(‘logs’, {

address: ‘ContractAddress’,

topics: [‘0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef’]

}, (error, result) => {

if (error)

console.error(error);

})

.on(“connected”, function (subscriptionId) {

console.log(subscriptionId);

})

.on(“data”, function (log) {

console.log(log);

});

Beachten Sie, dass wir eine Verbindung zum WebSocket-Endpunkt von Moonbase Alpha herstellen. Wir verwenden die Methode web3.eth.subscribe(‘logs’, options [, callback]) um die Logs zu abonnieren, gefiltert nach den gegebenen Optionen. In unserem Fall sind die Optionen die Vertragsadresse, von der aus die Ereignisse gesendet werden, und die Themen, mit denen das Ereignis beschrieben wird. Weitere Informationen zu Themen finden Sie in diesem Medium-Post. Wenn keine Themen enthalten sind, abonnieren Sie alle vom Vertrag ausgegebenen Ereignisse. Um nur das Transfer-Ereignis zu filtern, müssen wir die Signatur des Ereignisses einschließen, die wie folgt berechnet wird:

EventSignature = keccak256(Transfer(address,address,uint256))

Das Ergebnis der Berechnung wird im vorherigen Code-Snippet angezeigt. Wir werden später auf das Filtern nach Themen zurückkommen. Der Rest des Codes verarbeitet die Callback-Funktion. Sobald wir diesen Code ausführen, erhalten wir eine Abonnement-ID und das Terminal wartet auf jedes Ereignis durch dieses Abonnement:

Als nächstes wird ein ERC-20-Token-Transfer mit den folgenden Parametern gesendet:

  • Von der Adresse: 0x44236223aB4291b93EEd10E4B511B37a398DEE55
  • Zu der Adresse: 0x8841701Dba3639B254D9CEe712E49D188A1e941e
  • Wert (Tokens): 1000000000000000000 — das ist eine 1 mit 18 Nullen

Sobald wir die Transaktion gesendet haben, wird das Protokoll des von der Transaktion ausgegebenen Ereignisses im Terminal angezeigt:

Lassen Sie uns die erhaltene Antwort aufschlüsseln. Unser Zielereignis sendet zwei indizierte Informationen: die from- und die to-Adresse (in dieser Reihenfolge), die wie Themen behandelt werden. Das andere Datenelement, das von unserem Ereignis geteilt wird, ist die Anzahl der Tokens, die nicht indiziert sind. Daher gibt es insgesamt drei Topics (maximal vier), die dem Opcode LOG3 entsprechen:

Folglich können Sie sehen, dass die from- und to-Adressen in den von den Protokollen zurückgegebenen Themen enthalten sind. Ethereum-Adressen sind 40 Hex-Zeichen lang (1 Hex-Zeichen sind 4 Bit, daher 160 Bit oder H160-Format). Daher werden die zusätzlichen 24 Nullen benötigt, um die Lücke zu H256 zu füllen, die 64 Hex-Zeichen lang ist.

Im Datenfeld der Protokolle werden nicht indizierte Daten zurückgegeben, die jedoch in bytes32/hex kodiert sind. Um es zu entschlüsseln, können wir zum Beispiel dieses Online-Tool verwenden und überprüfen, ob die Daten tatsächlich 1 (plus 18 Nullen) sind.

Wenn das Ereignis mehrere nicht indizierte Werte zurückgibt, werden diese nacheinander in der Reihenfolge angehängt, in der das Ereignis sie ausgibt. Daher wird jeder Wert dann erhalten, indem Daten in separate 32 Bytes (oder 64 Hex-Zeichen lange) Stücke zerlegt werden.

Verwenden von Wildcards und Conditional Formatting

In der Version v2, in der die Funktion zum Abonnieren von Protokollen eingeführt wurde, gab es einige Einschränkungen bei der Verwendung von Wildcards und der bedingten Formatierung für die Themen. Mit der Veröffentlichung von Moonbase Alpha v3 ist dies jedoch nun möglich.

Unter Verwendung des gleichen Beispiels wie im vorherigen Abschnitt können wir die Ereignisse des Token-Vertrags mit dem folgenden Code abonnieren:

const Web3 = require(‘web3’);

const web3 = new Web3(‘wss://wss.testnet.moonbeam.network’);

web3.eth

.subscribe(

‘logs’,

{

address: ‘ContractAddress’,

topics: [

null,

[

‘0x00000000000000000000000044236223aB4291b93EEd10E4B511B37a398DEE55’,

‘0x0000000000000000000000008841701Dba3639B254D9CEe712E49D188A1e941e’,

],

],

},

(error, result) => {

if (error) console.error(error);

}

)

.on(‘connected’, function (subscriptionId) {

console.log(subscriptionId);

})

.on(‘data’, function (log) {

console.log(log);

});

Hier filtern wir durch die Verwendung des Wildcard null für die Ereignissignatur, um alle Ereignisse abzuhören, die von dem Vertrag ausgegeben werden, den wir abonniert haben. Aber mit dieser Konfiguration können wir auch ein zweites Eingabefeld (topic_1) verwenden, um wie oben erwähnt einen Filter nach Adresse zu definieren. Im Falle unseres Abonnements teilen wir mit, dass wir nur Events erhalten möchten, bei denen topic_1 eine der von uns angegebenen Adressen ist. Beachten Sie, dass die Adressen im H256-Format vorliegen müssen. Beispielsweise muss die Adresse 0x44236223aB4291b93EEd10E4B511B37a398DEE55 als 0x00000000000000000000000044236223aB4291b93EEd10E4B511B37a398DEE55 eingegeben werden. Wie zuvor zeigt die Ausgabe dieses Abonnements die Ereignissignatur in topic_0 an, um uns mitzuteilen, welches Ereignis vom Vertrag ausgegeben wurde.

Wie man sieht, haben wir, nachdem wir die beiden Adressen mit bedingter Formatierung versehen haben, zwei Protokolle mit derselben Abonnement-ID erhalten. Ereignisse, die von Transaktionen von verschiedenen Adressen ausgegeben werden, werden keine Protokolle an dieses Abonnement senden.

Dieses Beispiel zeigt, wie wir nur die Ereignisprotokolle eines bestimmten Vertrags abonnieren können, aber die web3.js-Bibliothek bietet andere Abonnementtypen, die in den folgenden Abschnitten behandelt werden.

Subscribe to Incoming Pending Transactions

Um ausstehende Transaktionen zu abonnieren, können wir die Methode web3.eth.subscribe(‘pendingTransactions‘, [, callback]) verwenden, die dieselbe Callback-Funktion implementiert, um die Antwort zu überprüfen. Dies ist viel einfacher als unser vorheriges Beispiel und gibt den Transaktions-Hash der ausstehenden Transaktionen wieder.

Wir können überprüfen, ob dieser Transaktions-Hash mit dem angegebenen in MetaMask (oder Remix) übereinstimmt.

Eingehende Block-Header abonnieren

Ein anderer in der Web3.js-Bibliothek verfügbarer Typ besteht darin, neue Blockheader zu abonnieren. Dazu verwenden wir die Methode web3.eth.subscribe(‘newBlockHeaders’ [, callback]) und implementieren dieselbe Callback-Funktion, um nach der Antwort zu suchen. Dieses Abonnement stellt eingehende Blockheader bereit und kann verwendet werden, um Änderungen in der Blockchain zu folgen.

Beachten Sie, dass im Bild nur ein Blockheader angezeigt wird. Diese Meldungen werden für jeden produzierten Block angezeigt, also können sie das Terminal recht schnell füllen.

Überprüfen Sie, ob ein Knoten mit dem Netzwerk synchronisiert ist

Mit pub/sub kann auch überprüft werden, ob ein bestimmter von Ihnen abonnierter Knoten gerade mit dem Netzwerk synchronisiert ist. Dafür können wir die Methode web3.eth.subscribe(‘syncing‘ [, callback]) nutzen und dieselbe Callback-Funktion implementieren, um nach der Antwort zu suchen. Dieses Abonnement gibt ein Objekt zurück, wenn der Knoten mit dem Netzwerk synchronisiert wird.

Aktuelle Einschränkungen

Die Pub/Sub-Implementierung in Frontier befindet sich noch in der aktiven Entwicklung. Diese erste Version ermöglicht es den DApp-Entwicklern (oder Benutzern im Allgemeinen), bestimmte Ereignistypen zu abonnieren, aber es gibt noch einige Einschränkungen. Sie haben vielleicht aus früheren Beispielen bemerkt, dass einige der Felder in der aktuellen Version nicht die richtigen Informationen anzeigen, und das liegt daran, dass bestimmte Eigenschaften noch von Frontier unterstützt werden.

Original article: https://docs.moonbeam.network/integrations/pubsub/

--

--