Ich verwende React, um das Frontend für meine dApp zu schreiben, und tue dies, um den Status von React über einen asynchronen sendTransaction
Aufruf zu aktualisieren (zu versuchen):
var thisJS = this
web3.eth.sendTransaction({from: adminAccount, to: contractAddress, value: web3.toWei(funds,"ether")}, function(error, result) {
if (error) {
console.error(error)
} else {
console.log("Send transaction successful " + result)
const contractFunds = web3.fromWei(web3.eth.getBalance(contractAddress),"ether").toString()
thisJS.setState({contractFunds: contractFunds})
}
})
Das scheint nicht ganz so zu funktionieren, wie ich gehofft hatte, da der Reaktionsaufruf setState
(oft) nicht die neuen Gelder an der Vertragsadresse widerspiegelt. Ich muss etwas falsch machen - was ist der richtige Weg, um auf das Mining der Transaktion zu warten, damit ich den Status von React korrekt aktualisieren kann?
Verwenden Sie einen Filter , um nach Änderungen zu suchen. In diesem Fall könnten Sie zum Beispiel:
web3.eth.filter('latest', function(error, result){
if (!error) {
thisJS.setState({contractFunds:
web3.fromWei(web3.eth.getBalance(contractAddress),"ether").toString()})
} else {
console.error(error)
}
});
Hinweis: Sie werden wahrscheinlich .stopWatching
irgendwann (wahrscheinlich in componentWillUnmount()
)
Ich habe einen Gist erstellt , der den Knoten abfragt, bis die Transaktion abgebaut wurde:
web3.eth.getTransactionReceiptMined = Funktion (txnHash, Intervall) { var transactionReceiptAsync; Intervall = Intervall ? Intervall: 500; transactionReceiptAsync = function(txnHash, auflösen, ablehnen) { Versuchen { var Empfang = web3.eth.getTransactionReceipt (txnHash); if (Empfang == null) { setTimeout(Funktion () { transactionReceiptAsync(txnHash, auflösen, ablehnen); }, Intervall); } anders { lösen (Empfang); } } Fang(e) { ablehnen (e); } }; if (Array.isArray(txnHash)) { var verspricht = []; txnHash.forEach(Funktion (einTxHash) { Promises.push (web3.eth.getTransactionReceiptMined (oneTxHash, Intervall)); }); return Promise.all (Versprechen); } anders { return new Promise(function (auflösen, ablehnen) { transactionReceiptAsync(txnHash, auflösen, ablehnen); }); } };
Wenn es länger als 50 Blöcke dauert, ist mir jedoch aufgefallen, dass es fehlschlägt.
Dem Vorschlag von Derek Tiffany folgend, kam ich auf die folgende Antwort.
Zuerst richte ich einen Filter für den neuesten Block ein:
const latestFilter = web3.eth.filter('latest')
Dann erhalte ich den Transaktions-Hash und setState auf diesen Hash:
const tx = web3.eth.sendTransaction({from: adminAccount, to: contractAddress, value: web3.toWei(funds,"ether")})
this.setState({txHash: tx})
Schließlich drehe ich eine Uhr für den Filter auf und versuche, den Transaktionshash meines Zustands abzugleichen. Wenn ich eine Übereinstimmung erhalte, aktualisiere ich den Status entsprechend:
_latestBlock() {
const thisJs = this
const filter = this.state.latest
const web3 = this.state.web3
const contractAddress = this.state.contractAddress
const adminAccount = this.state.account
filter.watch(function (error, result) {
if (error) {
console.error(error)
} else {
let thisTx = thisJs.state.txHash
console.log("State transaction " + thisTx)
const block = web3.eth.getBlock(result, true)
let transactions = block.transactions
for(let i = 0; i < transactions.length; i++)
{
console.log("block transaction " + transactions[i].hash)
if( thisTx == transactions[i].hash ){
console.log("Got match!")
const contractFunds = web3.fromWei(web3.eth.getBalance(contractAddress),"ether").toString()
thisJs.setState({contractFunds: contractFunds})
break
}
}
}
})
}
Bisher scheint es gut zu funktionieren...
eth
Glühwächter
0xcaff