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?
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 indexed
in der Ereignisdefinition des Vertrags definiert sein. Damit Ihr web3.js-Code funktioniert, müssen Sie den _from
Parameter 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 indexed
Parameter 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 _from
nicht 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.
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.
Benutzer824624
gisdev_p