交易和通話有什麼區別?
交易和通話有什麼區別?在某些界面中,我可以通過呼叫或交易與合約進行互動。兩者有什麼區別,合約也可以做交易和呼叫嗎?
稱呼
呼叫是合約函式的本地呼叫,不會在區塊鏈上廣播或發布任何內容。
這是一個只讀操作,不會消耗任何乙太幣。它模擬事務中會發生的情況,但在完成後丟棄所有狀態更改。
它是同步的,立即返回合約函式的返回值。
它的 web3.js API 是web3.eth.call並且是用於Solidity
view
,pure
,constant
functions的。它的底層 JSON-RPC 是eth_call
交易
交易被廣播到網路,由礦工處理,如果有效,則在區塊鏈上發布。
這是一個寫入操作,會影響其他賬戶,更新區塊鏈的狀態,並消耗 Ether(除非礦工以零的 gas 價格接受它)。
它是非同步的,因為可能沒有礦工將交易包含在一個區塊中(例如,交易的 gas 價格可能太低)。由於它是非同步的,因此事務的立即返回值始終是事務的雜湊值。 要將事務的“返回值”傳遞給函式,需要使用事件(除非是下面討論的案例 4)。以 ethers.js 為例:使用 ethers.js 監聽合約事件?
它的 web3.js API 是web3.eth.sendTransaction,如果沒有標記 Solidity 函式,則使用它
constant
。它的底層 JSON-RPC 是eth_sendTransaction
sendTransaction 將在需要動詞時使用,因為它比簡單的事務更清晰。
建議先呼叫,再發送事務
由於 sendTransaction 需要 Ether,因此在 sendTransaction 之前先發出呼叫來“試水”是一種很好的做法。這是一種免費的方式來調試和估計 sendTransaction 是否會出現任何問題,例如是否會遇到 Out of Gas 異常。
這種“試執行”通常效果很好,但在某些情況下,請注意呼叫是一個估計值,例如返回前一個區塊雜湊的合約函式,將根據呼叫執行時間和交易執行時間返回不同的結果實際開採。
最後,請注意,即使呼叫不消耗任何 Ether,有時也可能需要指定呼叫的實際 gas 量*:* Geth 等客戶端呼叫的預設 gas 可能仍然不足,仍然會導致 Out氣體。
案例4:合約可以創建交易嗎?
如何呼叫合約函式有 4 種情況。
以下是 4 種情況,前 3 種情況已在上面介紹過:
- 直接呼叫合約函式,源於呼叫
- 直接呼叫合約函式,源自 sendTransaction
- 合約函式的合約呼叫,源於呼叫
4.合約函式的合約呼叫,起源於sendTransaction
雖然 Case4 聽起來像是合約“也可以做交易”,但因為它在交易中,所以交易的定義是由外部 Actor 簽署的數據。因此,Case4 不是交易。
來自黃皮書:
交易:一段數據,由外部參與者簽名。它代表消息或新的自治對象。交易記錄在區塊鏈的每個區塊中。
上面早些時候說過,必須使用事件來獲取合約函式的返回值,該函式起源於 sendTransaction。這適用於 Case2 並且是正確的。對於Case4,合約直接獲取一個合約函式的返回值,就可以使用了。黃皮書用粗體字是這樣說的:
消息呼叫:將消息從一個帳戶傳遞到另一個帳戶的行為。如果目標帳戶與非空 EVM 程式碼相關聯,則 VM 將以所述對象的狀態和所作用的消息啟動。如果消息發送者是自治對象,則呼叫傳遞從 VM 操作返回的任何數據
通過黃皮書的這些定義,可以看出 Case4 是事務中的消息呼叫(因此狀態發生變化),沒有事務嵌套,並且乙太坊區塊鏈上的一個活動單元都在單個事務中可能包含多個Message Calls。
更新:由於呼叫函式可能是模棱兩可的(是 eth_call 還是 eth_sendTransaction?),因此有一個eth_simulateTransaction的提議。