無法接收事件?
我的 web3 版本是 web3@1.0.0-beta.26,我在 localhost:8545 上部署合約。
這是我的契約範例。
pragma solidity ^0.4.18; contract LocalEthereum { address public owner; event Created(bytes32 _tradeHash); function createEvent() onlyOwner external { Created(0x01); } }
這是我的js程式碼
初始化合約實例
var Contract = new this.web3.eth.Contract(abi_json,address);
按鈕點擊事件
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); }
觀看活動
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);
js 應用可以載入合約並連接乙太坊網路,當我點擊按鈕時,Contract 會生成一個 ‘Created’ 對乙太坊的 rpc 呼叫,可以立即收到交易。在 testrpc 界面上,我還可以看到如下所示的事務。
Transaction: 0x2469f2085c8f6f23ad8aa30bc6cf99ade40ea2f0368b9bb008496ba05d927d84 Gas usage: 21272 Block Number: 6 Block Time: Thu Dec 28 2017 20:38:02 GMT+0000 (GMT)
一切正常,但是在方法呼叫之後永遠不會啟動事件呼叫。應用程序初始化中只有一次事件呼叫,但仍然是
this.Contract.events.Created({},{ fromBlock: 0, toBlock: 'latest' }, function(error, event){ console.log(event); }) .on('data', function(event){ console.log(event); })
控制台輸出空值。
想知道是什麼問題?
我想知道是因為 web3 提供商嗎?目前我使用的是 web http 而不是 ws。目前我正在對 ganache-cli 和 testrpc 進行測試。
this.web3 = new Web3(new Web3.providers.HttpProvider('http://localhost:8545'));
是 http 提供者不提供事件嗎?
實際上我發現 HttpProvider 不支持訂閱 web3.js 1.0.0 中的事件。來自https://web3js.readthedocs.io/en/1.0/web3.html#value:
對象 - HttpProvider:不推薦使用 HTTP 提供程序,因為它不適用於訂閱。
所以我確實需要使用 WebsocketProvider(或本地節點的 IpcProvider)。
您只能過濾屬於事件一部分的參數的事件,並且您要在過濾器中使用的參數必須像
indexed
在契約的事件定義中一樣定義。因此,為了讓您的 web3.js 程式碼正常工作,您需要將_from
參數添加到事件定義中,indexed
並在您拋出事件時將參數設置為 msg.sender: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); } }
一個事件中最多可以有三個
indexed
參數。但是,查看您的合約程式碼,只有合約的所有者才能創建 event
Created
。因此,除非所有者更改,否則過濾_from
不會有太大用處。因此,如果您不需要此過濾,請嘗試var event = instance.Created({},{fromBlock:0,toBlock:'latest'});
在您的 javascript 程式碼中,這應該可以在不修改您的契約的情況下工作。