本文是對以太坊中可升級智慧合約領域的各種實現策略的總結,目的是彙總迄今為止的相關資源,以幫助我們在設計智慧合約時,考慮如何對其進行升級和更新。
100%可升級機制
目前有兩種主要策略用來實現可升級的智慧合約:
- 使用代理合約
- 將邏輯和資料分離成不同的合約。
這兩種方法要解決的根本問題是如何更新合同的邏輯,同時仍然保留對合同狀態的訪問。
代理合約
代理合約使用delegatecall
操作碼將函式呼叫轉發到可更新的目標合約。 由於delegatecall保留了函式呼叫的狀態,因此可以更新目標合約的邏輯,並且狀態將保留在代理合約中以供更新後的目標合約的邏輯使用。 與delegatecall一樣,msg.sender將保持代理合約的呼叫者身份。
由於最近的拜占庭硬分叉,現在可以獲取函式呼叫的返回大小了,因此與Nick Johnson首次提出的方法相比,目前這種方法可以通用。 在Daonomic的文章中可以看到一個通用代理合約的例子,你可以更詳細地瞭解這個機制。
分離邏輯和資料合約
這中方法到將智慧合約拆分兩個合約:
- 包含資料(變數,結構,對映等)以及getter/setter的資料合約
- 包含如何更新這些資料的業務邏輯的邏輯合約
邏輯合約通過setter更新資料,而資料合約只允許邏輯合約呼叫setter。這允許在保持資料不變的同時更換實現邏輯,從而實現完全可升級的系統。
通過引導使用者使用新的邏輯合約(通過諸如ENS的解析器)並更新資料合約的許可權來允許新的邏輯合約執行setter,就可以實現合約的更新。
檢視@Thomas Wiesner的視訊以更好地瞭解這一機制。
使用鍵值對資料模型分離邏輯和資料合約
這種策略的工作原理與上述類似,只是不使用最終期望資料結構(struct,mapping等)來定義合約資料模型,所有資料都被抽象化並儲存在鍵值對中,然後使用一個標準的命名系統以及sha256雜湊演算法用於查詢資料值。
可以查閱David Rugendyke的文章以更好地理解這種機制。
部分可升級策略
建立一個完全可升級的合約聽起來不錯,但需要一個很大的妥協:保證合約的不可變性。 因此在很多情況下實現部分可升級的合約可能是更合理的選擇。
在此策略中,智慧合約的核心功能可以保留為不可升級。 其他可能不太完整或更復雜的元件則採用可升級策略實施。
這方面已經有一些很好的案例:
- 以太坊名稱服務ENS:ENS核心合約是一個非常簡單的合約,不能更改。
域名註冊商則可以由管理員升級。 域名註冊商是一個合約工廠,如果使用一個新的域管理器,它可以與以前的所有資料狀態重新連結,而不會有太多麻煩。 - 0xProject :603DEX(去中心化交易所)核心智慧合約可以完全升級,而代理合約(每個使用者一個)保持不變。
0x“代理”合約(不同於前面介紹的代理策略)包含使用者資金和相關設定。 由於這個原因,它不是0x合約系統的可升級部分。
其他挑戰
- 在所有情況下,都需要對是否保持智慧合約的不變性進行取捨。
- 建立可選的可升級智慧合約系統對使用者來說是可能並且有價值的,但是增加了複雜性。
- 對Solidity編譯器的更改可能會破壞新舊合約之間的相容性。
- 制定可升級策略時需要考慮gas開銷。
結論
沒有一個策略是完美的,選擇正確的策略取決於要實施的智慧合約。 所有策略都非常複雜,智慧合約設計人員應該對他們所選擇的可升級策略非常瞭解,以避免安全漏洞。
- 為了建立一個可升級的智慧合約,代理機制似乎是最好的全面策略,因為它允許程式設計師將可升級機制
與合約設計區分開來,這使得一切變得更容易,並且會產生更少的錯誤,而錯誤是我們需要升級合約的主要原因。 - 在最簡單的核心邏輯不變的情況下,採用部分升級策略也是保持使用者信任的好主意。
- 首先設計不可升級的智慧合約系統,然後制定可升級的策略,這是一種實用且理想的方式。
參考資源
思路與觀點
- 2018-02-01 Zeppelin Solution : Zeppelin與智慧合約開發的演變
- 2016-2017: Stackexchange關於可升級的智慧合約的問答
- ConsenSys : 以太坊智慧合約最佳實踐
- Evoluchain : Evoluchain
代理合約
- 2018-02-22 Jorge Izquierdo : ERC DelegateProxy #897
- 2018-02-15 經濟學 : 可升級的以太坊智慧合約 , Github專案
- 2018-01-11 B9lab團隊 : upgradable – Github專案
- 2018-01-10 Manuel Araoz : olidity-proxy – Github專案
- 2017-06-02 @Ownage : Ether-routher – Github專案
- 2017-05-24 Nick Johnson : 瘋狂的區塊鏈科學:100%可升級的合約 , Gist File
- 2017-03-15 Jorge Izquierdo : Solidity程式碼部署高階技術
- 2017-03-07 Manuel Araoz : Solidity中的代理庫
- 2017-02-13 Jorge Izquierdo : Solidity中庫驅動的開發
- 2017-01-21 Tjaden Hess : 可升級的智慧合約
- 2016-06-16 @Martin Swende : 隱式方法代理技巧
分離邏輯和資料合約
- 2017-12-09 @Thomas Wiesner : 升級鏈上智慧合約
- 2017-11-13傑克坦納: 可升級的智慧合約 , Github專案
- 2017-08-21 Lukas K : 可升級的智慧合約。 我們學習了在區塊鏈上建立保險
- 2016-08-16 @nikolai : Dapp-a-day 6:可升級的通證合約
- @monax : Solidity 1:solidity五種合約模型
- @monax : Solidity 7:更新Solidity合約
- @Z.com-cloud-blockchain : 合約版本升級解決方案
使用鍵值對資料模型分離邏輯和資料合約
- 2018-01-20 Hassan Abdel-Rahman :Solidity可升級合約
- 2017-11-22 David Rugendyke : 可升級Solidity合約設計,Github專案
- 2017-06-29 Chandan Gupta : Solidity可升級合約介面設計 , Github專案
- 2016-06-08 Elena Dimitrova : 在Solidity中編寫可升級合約
如果你希望馬上開始學習以太坊DApp開發,可以訪問匯智網提供的線上互動教程:
轉自:http://blog.hubwiz.com/2018/04/27/ethereum-contract-upgrade-strategy/#more