Solidity
在實際設置數據之前觸發事件
假設這是我的智能合約:
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 }
這是我的 nodeJS 文件:
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);
如果我
partAmount
使用函式將數組記錄在 web3 中.call
,則仍會返回事件之前的舊值。這告訴我事件觸發得太早了。設置數據後是否有呼叫事件?
編輯:更多程式碼。
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. }); })
注意:如果我像這樣在呼叫函式周圍設置超時:
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);
它確實返回了正確的數組,但這不是我希望腳本執行的方式。
問題是您沒有等待交易被探勘,然後
.call
再檢查結果。它去:
- 簽署並發送交易。獲取交易收據。
- 交易被探勘,合約按順序執行指令。
- 區塊與確認的交易一起到達。
- 現在你可以
call
一個函式來看看效果。或者,注意一個事件,就像您的範例 JS 出現的那樣。直到交易被包含在一個塊中,事件才會到達。
希望能幫助到你。
正如 Rob 指出的那樣,您很可能不會在提取數據之前等待交易被完全探勘。我不確定 web3js,但 Golang 提供了在交易被探勘之前讀取待處理狀態數據的能力。我個人更喜歡用 golang 編寫與智能合約互動的後端程式碼,並且只在需要時使用 web3(即前端程式碼)
不過要小心,我建議不要讀取待處理的狀態數據,因為這可能會根據插入到記憶體池中的任何事務而改變。
強烈建議在處理任何數據之前等待交易被探勘,我個人建議使用 golang over web3 與智能合約進行互動,並且僅在需要編寫前端程式碼時才使用 web3。
我有一個函式,只要在區塊鏈上發送特定交易,就會呼叫它,並在收到事件後自動完成處理並退出。