kann das Ereignis nicht empfangen?

Meine Web3-Version ist web3@1.0.0-beta.26, ich stelle den Vertrag auf localhost:8545 bereit.

Hier ist mein Vertragsbeispiel.

pragma solidity ^0.4.18;
contract LocalEthereum {

    address public owner;
    event Created(bytes32 _tradeHash);
    function createEvent() onlyOwner external {
        Created(0x01);
    } 
}

und hier ist mein js-code

Init der Vertragsinstanz

  var Contract = new this.web3.eth.Contract(abi_json,address);

Schaltflächenklick-Ereignisse

  Created(account){
      Contract.methods.Created().send({from: account,gas:210000,gasPrice:5000000000})
                      .on('transactionHash', function(hash){
                          console.log('hash',hash);
                      })
                      .on('receipt', function(receipt){
                          console.log('receipt',receipt);
                      })
                      .on('confirmation', function(confirmationNumber, receipt){
                          console.log('confirmation',confirmationNumber);
                      })
                      .on('error', console.error);
  }

Ereignisse ansehen

  this.Contract.events.Created({},{ fromBlock: 0, toBlock: 'latest' }, function(error, event){ console.log(event); })
                        .on('data', function(event){
                              console.log(event);
                        })
                        .on('changed', function(event){
                             console.log('on changed');
                        })
                        .on('error', console.error);

Die js-App kann den Vertrag laden und das Ethereum-Netzwerk verbinden. Wenn ich auf die Schaltfläche klicke, generiert der Vertrag einen „Created“-RPC-Aufruf an das Ethereum, die Transaktion kann sofort empfangen werden. Auf der testrpc-Oberfläche konnte ich die Transaktion auch wie unten gezeigt sehen.

  Transaction: 0x2469f2085c8f6f23ad8aa30bc6cf99ade40ea2f0368b9bb008496ba05d927d84
  Gas usage: 21272
  Block Number: 6
  Block Time: Thu Dec 28 2017 20:38:02 GMT+0000 (GMT)

Alles funktioniert gut, aber der Ereignisaufruf wird nie nach dem Methodenaufruf aktiviert. Es gibt nur einen Zeitereignisaufruf bei der App-Initialisierung, aber immer noch der

  this.Contract.events.Created({},{ fromBlock: 0, toBlock: 'latest' }, function(error, event){ console.log(event); })
                        .on('data', function(event){
                              console.log(event);
                        })

Die Konsole gibt die Null aus.

Frage mich, was ist das Problem?


Ich frage mich, ob es am Web3-Anbieter liegt? derzeit verwende ich web http nicht ws. Und derzeit teste ich auf ganache-cli und testrpc.

this.web3 = new Web3(new Web3.providers.HttpProvider('http://localhost:8545'));

stellt der http-Anbieter kein Ereignis bereit?

Antworten (3)

Tatsächlich habe ich festgestellt, dass der HttpProvider das Abonnieren von Ereignissen in web3.js 1.0.0 nicht unterstützt. Von https://web3js.readthedocs.io/en/1.0/web3.html#value :

Objekt – HttpProvider: Der HTTP-Anbieter ist veraltet, da er für Abonnements nicht funktioniert.

Ich muss also tatsächlich den WebsocketProvider (oder IpcProvider für lokale Knoten) verwenden.

Sie können Ereignisse nur nach Parametern filtern, die Teil des Ereignisses sind, und die Parameter, die Sie im Filter verwenden möchten, müssen wie indexedin der Ereignisdefinition des Vertrags definiert sein. Damit Ihr web3.js-Code funktioniert, müssen Sie den _fromParameter zur Ereignisdefinition hinzufügen indexed, erstellen und den Parameter auf msg.sender setzen, wenn Sie ein Ereignis auslösen:

pragma solidity ^0.4.18;
contract LocalEthereum {

    address public owner;
    event Created(adress indexed _from, bytes32 _tradeHash);
    function createEvent() onlyOwner external {
        Created(msg.sender, 0x01);
    } 
}

Sie können bis zu drei indexedParameter in einem Ereignis haben.

Wenn Sie sich jedoch Ihren Vertragscode ansehen, kann nur der Eigentümer des Vertrags ein Ereignis erstellen Created. Wenn sich der Eigentümer also nicht ändert, ist das Filtern nach _fromnicht von großem Nutzen. Wenn Sie diese Filterung also nicht benötigen, versuchen Sie es

var event = instance.Created({},{fromBlock:0,toBlock:'latest'});

in Ihrem Javascript-Code, sollte dies funktionieren, ohne Änderungen an Ihrem Vertrag vorzunehmen.

Danke, ich kenne die Verwendung von indiziert. aber dein js-code funktioniert immer noch nicht. Auch wenn ich onlyOwner im Solidity-Code entfernt habe. Der js-Code empfängt immer noch alle vergangenen Ereignisse und gibt kein Ereignis aus, wenn createEvent() ausgeführt wird
Ihr js-Code scheint also korrekt zu sein, das ist gut. Haben Sie überprüft, ob Sie die Ereignisse aus Ihrem Vertrag korrekt senden? Sie können dies einfach mit etherscan.io tun, sich eine Transaktion ansehen, die das Ereignis korrekt erstellt hat, und eine spätere, die dies nicht getan hat, und die Einträge auf der Registerkarte "Ereignisprotokolle" vergleichen

Dies ist direkt aus den Web3 Docs übernommen . Das sollte funktionieren.

var event = myContractInstance.MyEvent({valueA: 23} [, additionalFilterObject])

// watch for changes
event.watch(function(error, result){
  if (!error)
    console.log(result);
});

// Or pass a callback to start watching immediately
var event = myContractInstance.MyEvent([{valueA: 23}] [, additionalFilterObject] , function(error, result){
  if (!error)
    console.log(result);
});

Außerdem sieht es so aus, als wäre dies eine Beta-Version. Könnte daran liegen, da es einige Breaking Changes gibt.

VORSCHAU-VERSION Dies ist eine Beta-Vorschau-Version mit wichtigen Änderungen! Die aktuelle stabile Version ist 0.20.0

Wenn Sie eine stabile Version von web3 verwenden, dh 0.20.0, und den obigen Code ausprobieren, sollte es funktionieren.

Wenn die obige Methode nicht funktioniert, können Sie alternativ die JSON-RPC-Methode verwenden eth_getLogs. Nachfolgend finden Sie ein Beispiel für die Verwendung:

let request = require('request);
request.post({
                url: <geth_parity_client_IP_with_port>,
                form: JSON.stringify({
                    "jsonrpc":"2.0",
                    "method":"eth_getLogs",
                    "params":[
                        {
                            "topics": ["<get_your_Event_Hex_replace_this_string>"],
                            "address": <contractAddress>,
                            "fromBlock": "0x"+_fromBlock.toString(16),
                            "toBlock": "0x"+_toBlock.toString(16)
                        }
                    ],
                    "id":3 //Network To connect to (test/Main Net)
                }),
                headers: {
                    'Content-Type': 'application/json'
                }
            }, (error, response)=>{
                if(!error && response.statusCode == 200){
                    let result = JSON.parse(response.body).result;
                    console.log(result); //Prints the event details
                }
            });

Lassen Sie mich wissen, ob das oben genannte hilft.

wissen Sie, wie man es in web3 1.0 zum Laufen bringt
Nein. Ich hatte noch keine Gelegenheit, mit der Beta zu arbeiten. Aber haben Sie versucht, den alternativen Ansatz zu verwenden?