Solidity

truffle/web3 事件監聽器不返回任何內容

  • December 3, 2017

我們在合約中觸發了一個事件,客戶端上的偵聽器無法接收返回值。

https://gist.github.com/stupeters187/9529b54fe0d48ee606ad06ced6b16031

更新:metamask 版本 3.12.1 修復了問題

元遮罩版本 3.12.1

*請注意底部更新(這是我們的問題)

**答:**您對 newbook() 的呼叫無法在 javascript 中返回值,因為它會更改狀態。

解釋: Truffle 區分了改變狀態的函式和只讀取區塊鏈的函式。每次更改狀態時,都必須將其廣播到網路,以便礦工可以將更改合併到下一個塊中。此外,每個節點都必須更新他們的區塊鏈副本。這就是為什麼狀態改變需要消耗gas。這也是為什麼您不應該期望更改狀態的函式返回值的原因,因為該操作是非同步的,並且可能需要 1 到 2 個塊才能完成。

另一方面,僅讀取區塊鏈現有狀態的函式呼叫不需要打擾任何礦工或節點。事實上,如果您執行自己的節點,那麼您只需要查詢區塊鏈的本地副本即可執行這樣的功能。這就是為什麼只讀函式不需要gas。要向 truffle 發出您正在呼叫一個自由函式(即不改變狀態的函式)的信號,您可以在函式呼叫之後使用關鍵字call。EG 假設您有一個名為 getBalance() 的可靠函式,那麼您將編寫

instance.getBalance.call()

在 JavaScript 中。

在上面的範例中,您需要將狀態更改和檢索分為兩個步驟,如下所示:

ParentContract.deployed().then((instance) => { instance.NewBook().watch((err, res) => { if (err) console.log(err); console.log('contract address', res.address); }); instance.newBook(weiPrice, issues, rateFormatted, {from: window.web3.eth.accounts[0]}).then((res) => { console.log('TX', res); return instance.getLatestBookId.call(); }).then(res=>{ //res will have the id in there somewhere. }) .catch((err) => console.log(err) ); });

這假設您有一個名為 getLatestBookId() 的可靠函式,它看起來像

function getLatestBookId returns (uint id){ //DO NOT PUT STATE CHANGE OPERATIONS }

請記住,映射沒有長度概念,因此無法從映射中獲取最新資訊。您可能需要稍微調整您的資料結構以使其成為可能。

還要記住,當我說狀態變化時,我只指區塊鏈上的儲存。你可以用局部變數對你的心臟(或solidity的嚴格心臟)內容做你想做的事情,而不會產生gas費用。

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