Nehmen wir an, dies ist mein Smart Contract:
event NewUser(
address userAddress,
uint amount
);
function addUser() public payable{
require(msg.value <= maxValue && msg.value > 0);
require(allowedValues[msg.value]);
require(accountAmount() < 5);
if (users[msg.sender] > 0) {
userPullout(); //Remove senders data
}
userAddresses.push(msg.sender);
partAmounts.push(msg.value);// This value doesn't get pushed before the event is finished
users[msg.sender] = msg.value;
emit NewUser(msg.sender, msg.value);//This is called to soon
}
Dies ist meine nodeJS-Datei:
app.contract.events.NewUser({}, function(error, event){})
.on('data', function(event){
io.emit('new user', event.returnValues);
}).on('change', function(event){
io.emit('new user', event.returnValues);
})
.on('error', console.error);
Wenn ich das partAmount
Array in web3 mit einer .call
Funktion logge, werden immer noch die alten Werte vor dem Ereignis zurückgegeben. Dies sagt mir, dass das Ereignis zu früh ausgelöst wird.
Gibt es trotzdem ein Ereignis aufzurufen, nachdem die Daten gesetzt sind?
EDIT: etwas mehr Code.
const socket = openSocket('http://localhost:3000'); // subscribed to the socket server firing the events from node back-end
socket.on('new user', (event) => {
console.log(event) // returns for example 7 which is CORRECT
this.props.contract.methods.getCertainArray().call(this.props.contractObject, (err, res) => {
console.log(res); // old data from before the event so if the previous array was [0, 6 , 6], this would still be returned NOTICE: no 7 in the array yet.
});
})
HINWEIS: Wenn ich ein Timeout um die Anruffunktion wie folgt setze:
setTimeout(() => {
this.props.contract.methods.getCertainArray().call(this.props.contractObject, (err, res) => {
console.log(res); // old data from before the event so if the previous array was [0, 6 , 6], this would still be returned NOTICE: no 7 in the array yet.
});
}, 5000);
Es gibt das richtige Array zurück, aber es ist nicht die Art und Weise, wie das Skript ausgeführt werden soll.
Das Problem ist, dass Sie nicht darauf warten, dass die Transaktion abgebaut wird, bevor Sie .call
nach einem Ergebnis suchen.
Es geht:
call
eine Funktion verwenden, um den Effekt zu sehen.Oder achten Sie auf ein Ereignis, wie es Ihr Beispiel-JS zu tun scheint. Ereignisse kommen erst an, wenn die Transaktion in einem Block enthalten ist.
Ich hoffe es hilft.
Wie Rob betonte, warten Sie höchstwahrscheinlich nicht, bis die Transaktion vollständig abgebaut ist, bevor Sie Daten abrufen. Ich bin mir bei web3js nicht sicher, aber Golang bietet die Möglichkeit, ausstehende Zustandsdaten zu lesen, bevor die Transaktion abgebaut wird. Ich persönlich bevorzuge viel Golang zum Schreiben von Backend-Code, der mit intelligenten Verträgen interagiert, und würde nur bei Bedarf web3 verwenden (dh Frontend-Code).
Vorsicht, ich würde jedoch davon abraten, ausstehende Zustandsdaten zu lesen, da sich dies ändern kann, je nachdem, welche Transaktionen in den Mempool eingefügt werden.
Es wird dringend empfohlen, auf das Mining einer Transaktion zu warten, bevor Daten verarbeitet werden, und ich persönlich würde Golang über Web3 für die Interaktion mit Smart Contracts empfehlen und Web3 nur verwenden, wenn ich Frontend-Code schreiben müsste.
Ich habe eine Funktion, die immer dann aufgerufen wird, wenn eine bestimmte Transaktion an die Blockchain gesendet wird, und die Verarbeitung automatisch beendet und nach Erhalt des Ereignisses beendet wird.
Jetzt, wo ich mit dem Ropsten-Testnet verbunden bin, funktioniert es wie erwartet (wenn der WebSocket-Server aktiv ist).
Ich weiß nicht genau, was das Problem ist, aber ich weiß, dass das Problem in Ganache liegt, das die Ereignisse ausgelöst hat, bevor der nächste Block tatsächlich fertig war und alle Variablen aktualisiert wurden.
Lösung: Arbeiten Sie entweder von Ihrem eigenen lokalen Geth-Server aus oder laden Sie Ihren Vertrag in eines der Testnetze hoch.
Jaspis
Rob Hitchens
call
bevor die Transaktion abgebaut wird. Der erste Rückruf gibt einen Transaktions-Hash zurück. Das ist keine Bestätigung von "abgebaut". Es ist nur eine Bestätigung der Anfrage. Es ist üblich, dies mit einer Mining-Bestätigung zu verwechseln. Schau mal hier: gist.github.com/xavierlepretre/88682e871f4ad07be4534ae560692ee6Jaspis
Rob Hitchens
Rob Hitchens
Jaspis
Jaspis