Solidity
子契約與結構
假設我需要在智能合約中儲存和操作複雜數據的集合。可能存在復雜的規則來定義誰以及如何更改項目。集合中可能有數百萬個項目。
有兩種方法可以實現該邏輯
- 使用子契約:
合約數據項 { bytes32 鍵; 字元串值; 函式數據項(bytes32 k,字元串 v){ 鍵=k; 值 = v; } } 合約 DAppInterface { 映射(bytes32 => 地址)公共數據項; 函式 addDataItem(bytes32 k, string v) 外部 { 數據項[k] = 新數據項(k, v); } }
- 使用結構:
合約 DAppInterface { 結構數據項 { bytes32 鍵; 字元串值; } 映射(bytes32 => DataItem)公共數據項; 函式 addDataItem(bytes32 k, string v) 外部 { 數據項[k].key = k; 數據項[k].value = v; } }
使用一種方法與另一種方法有什麼優勢?選擇一個與另一個的準則是什麼?
在大多數情況下,資料結構,即使是複雜的,都應該是結構。
以下是選擇結構的一些原因:
- **契約更貴。**您最初必須為合約的創建付費,每次訪問它時,您都需要為呼叫另一個合約付費。這比在合約自己的儲存中查找的 sha3 貴得多。
- **合約必須複製程式碼。**每個合約都必須包含設置和更改值的邏輯,你必須用 gas 支付。一個結構只需要一組函式。
- **契約暴露。**任何人都可以向合約發送消息。如果您使用合約來儲存資料結構,則必須手動管理訪問。
- **庫可能是您真正想要的。**如果您發現自己在資料結構(即 )上尋找函式
foo.bar()
,您可以使用庫合約來完成它,而無需為每個實例創建合約的額外複雜性。以下是契約更優越的一些原因:
- **合約可以是多態的。**合約可能包含任意程式碼。這允許混合多種類型,甚至讓使用者自帶邏輯。
- **邏輯將被拆分。**在這個註冊商契約中,每個契約都可能是一個結構。通過讓 Deeds 成為自己的合約,Deeds 本身的攻擊面就更少了,從而減少了另一場 TheDAO 規模災難的機會。
- **契約暴露。**如果使用者必須配置他們的資料結構,那麼擁有一個可以直接與之互動的唯一地址可能會更簡單。
- **合約就是合約。**子契約可以做任何契約可以做的事情。如果出於某種原因,資料結構會像地址一樣擁有東西,那麼擁有合約會好得多。合約可以直接持有乙太幣,而不是與其他結構共享主合約餘額的結構。
但是,這些不太常見。我的建議:首先嘗試使用結構,最後使用資料結構契約。