Go-Ethereum

Web3.js eth.subscribe: on(‘changed’, function(event){}) 不適用於 Metamask?

  • April 10, 2022

我用這個 javascript 寫了一個展示 DApp 網站

   const web3 = new Web3(ethereum);
   const contractAddr = "0x0Aa27e4B13D5c08A8767B36a0ACb76ED4549B7EA";
   const abi = ...;

   let inst = new web3.eth.Contract(abi, contractAddr);
   web3.eth.subscribe('logs', {
       address: contractAddr,
   }, function (error, result) {
       if (!error)
           console.log(result);
       else
           console.log("default:", error);
   })
       .on("connected", function (subscriptionId) {
           console.log(subscriptionId);
       })
       .on("data", function (log) {
           console.log("data:", log);
       })
       .on("changed", function (log) {
           console.log("changed:", log)
       }).on("error", function (log) {
           console.log("err:", log);
       });

在我使用ethereumwindow.ethereum由 MetaMask 提供)作為 Web3.js 的提供程序的程式碼中。

我的 MetaMask 連接到一個名為node1使用 Geth on的私有區塊鏈localhost:8545。與此同時,我還有另一個名為node2.

一開始,node1node2沒有連接。node1我向將發出事件的合約發送並探勘了一筆交易,contractAddress並且由於我訂閱了“日誌”,我確實在瀏覽器中獲得了控制台日誌。

然後我讓node2我的塊比我多node1,然後我連接它們。這將觸發node1鏈重組。重組後,恢復的交易留在了 txPool 中,我沒有再挖任何塊。

正如 web3.js文件中所指定的那樣,我希望console.log("changed:", log)被執行,但它沒有。

同時,我也使用了低級的 Json-rpc 方法eth_getFilterChanges,確實得到了一個帶"removed": true欄位的日誌,這意味著事務確實被還原了。

我認為 web3.js 應該注意到這一點並執行on('changed')回調。但是為什麼 web3.js 在這裡不起作用呢?由於 web3.js 不能直接使用 HTTP 乙太坊提供者訂閱日誌,而 MetaMask 使用 HTTP 連接乙太坊,那麼這個問題與 MetaMask 有關係嗎?

順便說一句:我正在使用 web3.jsv1.2.6

對我來說,這也不起作用,我不知道為什麼,但我使用 web3 找到了以下解決方案。

由於 Metamask 中的 web3 將被棄用,我不是從 Metamask 中獲取 web3,而是通過:

web3 = new Web3(Web3.givenProvider);

然後稍後在程式碼的其他地方設置事件偵聽器:

web3.eth.Contract(TokenABI, TokenAddress);

嘗試 {

eventHandlerTransfer = await contract.events.Transfer({ fromBlock: 0 }, function (err, data) {

//INFO: 你的數據可以在例如

data.returnValues._from

if(err) {

console.log(err);

}

});

}catch (error) {

console.log(error); 這是使用“async function() {”風格編寫的

……

希望這可以幫助。快樂的非同步編碼…

我使用 “contract.events.Transfer({ fromBlock: 0 }, function (err, data) {”

而不是 “web3.eth.subscribe(’logs’, {” …

以便了解所有不同的事件發生這種情況(在這種情況下是 Transfer 事件,但您也可以添加其他事件。)

如果傳輸中有錯誤,例如我在 catch(error) 部分收到錯誤。

“契約來自

contract = new web3.eth.Contract(TokenABI, TokenAddress);

這對你有用嗎?

引用自:https://ethereum.stackexchange.com/questions/79962