Solidity

單獨的儲存契約是否會增加交易的 gas 成本?

  • January 23, 2017

我一直在閱讀很多關於智能合約可升級性的文章,似乎主要的流行做法是,將合約邏輯與合約儲存分開通常是一個好主意,因此可以升級一個而不必更改另一個。

我的問題如下:一個契約必須呼叫另一個契約這一事實是否會增加該邏輯所消耗的氣體量。例如,假設我有一份契約查找數字 X,然後將其添加到數字 5。

在一種情況下,合約儲存在 X 本身中,因此它可以直接查找它。在另一種情況下,一個單獨的合約負責儲存 X,導致一個合約呼叫函式來獲取 X。一個會花費更多的 gas 嗎?如果是這樣,是否有可能告訴更多?

謝謝!

我會說是的,有一點,但在大多數情況下,這並不是非常重要。撇開一次性部署成本不談,每個事務都會執行額外的程式碼。它不是免費的,但在大多數情況下,附加程式碼的執行成本不會特別高。

查看每次操作的 gas 成本(不暗示保證):https ://docs.google.com/spreadsheets/d/15wghZr-Z6sRSMdmRmhls9dVXTOpxKy8Y64oy9MvDZEQ/edit#gid=0 。

一個基本的啟發式方法是,與不改變區塊鏈的計算操作碼相比,狀態改變操作碼(例如 SSTORE)相當高。人們通常可以添加額外的低成本成本步驟(例如查找合約地址並形成消息),而不會大大增加狀態更改的總體成本。無論如何,狀態變化都是昂貴的。

讀取操作通常使用常量函式或根本不使用 gas 的本地呼叫來處理。因此,交易成本問題通常僅限於會導致狀態變化的交易。因此,創建/插入、更新和刪除是有成本的(來自 SSTORE 等操作的最大份額)。無論複雜程度如何,讀取通常都是免費的。還要考慮到許多系統使用由事件發射器提供的鏈下儲存,這些事件發射器出於性能原因維護“官方”事實的副本。另一個例子,其中只有更新的成本是完全值得關注的。

要使用特定範例並比較成本,您可以考慮以兩種方式編寫代表性函式並比較實際氣體消耗。Solidity Realtime 編譯器將在編譯後顯示字節碼。您可以跳過原始碼以查看哪些實際步驟“昂貴”並進行相應優化。

作為腳註,請注意額外複雜性的隱藏成本。雖然可升級合約在許多方面都具有優勢,但對於每個案例,都需要考慮一組類似陰陽的權衡。例如,在某些情況下,可升級性可能會降低可信度,並可能成為新的錯誤來源。

希望它有幫助。

的,但建議權衡增加的 gas 成本,以及它為您的應用程序提供的可升級性。

大多數可升級合約將涉及庫和 DELEGATECALL 操作碼,其中一些成本在庫的 Solidity 文件中有所描述:

庫可以被視為使用它們的合約的隱含基礎合約。它們在繼承層次結構中不會顯式可見,但對庫函式的呼叫看起來就像對顯式基礎合約的函式的呼叫(如果 L 是庫的名稱,則為 Lf())。此外,庫的內部功能在所有合約中都是可見的,就像庫是基礎合約一樣。當然,對內部函式的呼叫使用內部呼叫約定,這意味著所有內部類型都可以傳遞,記憶體類型將通過引用傳遞而不是複制。為了在 EVM 中實現這一點,內部庫函式(以及從其中呼叫的所有函式)的程式碼將被拉入呼叫合約,並且將使用正常 JUMP 呼叫而不是 DELEGATECALL。

基本上,當一切都在合約中時,它可以使用引用、避免複製並使用 JUMP 操作碼。

當涉及到外部合約時,DELEGATECALL 比 JUMP 貴很多(目前 700 gas vs 10 gas),還有複製數據等其他成本。

但重要的是還要分析特定案例並進行比較。對於上面給出的簡單範例,CALL/DELEGATECALL 的成本將是巨大的。但在其他案例中,這些額外的天然氣成本總體上可能產生的影響要小得多。

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