Wie kann ich einen Listener für neue Transaktionen mit Ethereum-RPC-Aufrufen erstellen?

Ich versuche, einen Minidienst zu erstellen, der es mir ermöglichen würde, eingehende Ethereum-Transaktionen zu abonnieren ( Coinbase-Beispiel ).

Ich dachte, dass es in Ethereum mit eth_newFilterund eth_getFilterChanges( JSON RPC ) Methoden gemacht werden könnte, aber ich mache etwas falsch. Könnten Sie bitte einen Hinweis geben oder habe ich das Konzept der Filter völlig falsch verstanden? Ich weiß, dass es eth_newPendingTransactionFilterMethode gibt, aber ich dachte, vielleicht gibt es einen besseren Weg, um mein Ziel zu erreichen? Im Moment folge ich diesen Schritten:

Starten Sie geth

Ich weiß, dass ich RPC nicht so öffnen sollte, aber im Moment habe ich dies der Einfachheit halber getan.

geth --dev --rpc --rpcapi "personal,miner,db,shh,admin,eth" --rpcaddr "localhost" --rpcport "8545"

Girokonten:

➜  curl -X POST --data '{"jsonrpc":"2.0","method":"eth_accounts","params": [],"id":1}' localhost:8545
{"id":1,"jsonrpc":"2.0","result":[]}

Erstellen Sie zwei Konten :

➜  curl -X POST --data '{"jsonrpc":"2.0","method":"personal_newAccount","params":["password"],"id":1}' localhost:8545
{"id":1,"jsonrpc":"2.0","result":"0x0199147554059ce1fa572600256dd6030db19658"}
➜  curl -X POST --data '{"jsonrpc":"2.0","method":"personal_newAccount","params":["password"],"id":1}' localhost:8545
{"id":1,"jsonrpc":"2.0","result":"0x350060daba130bed0809126c67240d38f27c4cff"}

Bergmann starten:

➜  curl -X POST --data '{"jsonrpc":"2.0","method":"miner_start","params":["1"],"id":1}' localhost:8545
{"id":1,"jsonrpc":"2.0","result":true}

Neuen Filter erstellen:

➜  curl -X POST --data '{"jsonrpc":"2.0","method":"eth_newFilter","params":[{"address": "0x350060daba130bed0809126c67240d38f27c4cff", "fromBlock":"latest","toBlock":"latest"}],"id":2}' localhost:8545
{"id":2,"jsonrpc":"2.0","result":"0x0"}

Konto entsperren und Transaktion senden:

➜  curl -X POST --data '{"jsonrpc":"2.0","method":"personal_unlockAccount","params":["0x0199147554059ce1fa572600256dd6030db19658","password"],"id":1}' localhost:8545
{"id":1,"jsonrpc":"2.0","result":true}
➜  curl -X POST --data '{"jsonrpc":"2.0","method":"eth_sendTransaction","params":[{"from": "0x0199147554059ce1fa572600256dd6030db19658","to": "0x350060daba130bed0809126c67240d38f27c4cff", "value":"0x1" }],"id":1}' localhost:8545
{"id":1,"jsonrpc":"2.0","result":"0xd0e910765a920b30fc2e70de6fc4557e74ad69c584d810f70188d254db7119bb"}

Warten Sie, bis die Transaktion vom lokalen Knoten fortgesetzt wird:

➜ curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getBalance","params":["0x350060daba130bed0809126c67240d38f27c4cff"],"id":1}' localhost:8545
{"id":1,"jsonrpc":"2.0","result":"0x01"}

Filter prüfen und nichts bekommen :(

➜ curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getFilterChanges","params":["0x00"],"id":1}' localhost:8545
{"id":1,"jsonrpc":"2.0","result":[]}

Antworten (1)

Filter funktionieren etwas anders. Filter erfordern , dass LOGs von einer EVM-Ausführung (dh einem Vertrag) ausgegeben werden. Solidity erleichtert Ihnen dies, indem es Ihnen erlaubt, events abzufeuern (kompilierte events erzeugen LOGs).

Nehmen wir folgenden Vertrag:

contract T {
    event res(uint indexed out)
    function echo(uint in) {
         res(i);
    }
}

Wenn die Methode echofür den Vertrag aufgerufen wird, löst sie das Solidity- Ereignis res aus . Diese Ereignisse können mit abgefangen eth_newFilterund mit abgefragt werden eth_getFilterChanges.

Beim Erstellen eines Filters für ein bestimmtes Ereignis (z. B. res) müssen wir zuerst die Ereignissignatur ableiten . Signaturen werden unter Verwendung der ersten 4 Bytes des keccakHashs der Definition des Ereignisses generiert (dh res(uint)): keccak("res(uint)"). Dies wird dann zum ersten Argument für die eth_newFilterThemen des .

Alle Argumente in der Definition des Ereignisses, die das indexedSchlüsselwort enthalten (wie im oben aufgeführten Beispielvertrag), können auch zum Filtern verwendet werden. Nehmen wir an, wir wollen nur Ereignisse für die Zahl 6 abfangen , dann würden wir den folgenden JSON-RPC konstruieren:

curl -X POST --data '{"jsonrpc":"2.0","method":"eth_newFilter","params":[{"address": "0xaddress", topics:["KECCAK_HASH", "0x6"], "fromBlock":"latest","toBlock":"latest"}],"id":2}' localhost:8545 {"id":2,"jsonrpc":"2.0","result":"0x0"}

Wann immer die Methode echo(6)für den Vertrag aufgerufen wird, können Sie jetzt das Ergebnis mit der eth_getFilterChanges.

Weitere Informationen finden Sie in den solidity-Dokumenten zu Ereignissen .

Ich bin gespannt, wie Sie dieselbe Aufgabe mit web3.js erledigen würden. Ich glaube, es würde über github.com/ethereum/wiki/wiki/JavaScript-API#contract-allevents funktionieren , aber ich kann keine guten Beispiele dafür finden, wie man das Themen-Array erstellt.
@Jeffrey W. top github.com/ethereum/wiki/wiki/JSON-RPC#eth_newFilter sagte: Ein Hinweis zur Angabe von Themenfiltern: Themen sind reihenfolgeabhängig. Eine Transaktion mit einem Protokoll mit den Themen [A, B] wird mit den folgenden Themenfiltern abgeglichen: [] "alles" [A] "A an erster Stelle (und alles danach)" [null, B] "alles an erster Stelle UND B an zweiter Stelle (und alles danach)" [A, B] "A an erster Stelle UND B an zweiter Stelle (und alles danach)" [[A, B], [A, B]] "(A ODER B ) an erster Stelle UND (A ODER B) an zweiter Stelle (und alles danach)" was bedeutet Themen? Es scheint Arra
Wissen Sie, wie ich alle „Transfer“-Ereignisse erfassen kann, die durch einen Vertrag in vergangenen Blöcken ausgelöst werden? Beispiel: Angenommen, Token T wurde erstellt, also möchte ich jede Übertragungstransaktion seit ihrer Erstellung erfassen, damit ich sehen kann, wohin alle Token gegangen sind. Vielen Dank