Solidity

代理升級的邏輯合約如何共享數據

  • February 17, 2020

我一直在研究如何使我的合約可升級,並查看 Zeppelin 文件和原始碼以試圖解決這個問題。

我無法解決的一件事是:

  • 新的邏輯合約如何共享數據(當它們沒有相互引用並且部署在不同的交易中時)?

    • 從安全的角度來看,是什麼阻止了一些不良行為者實施新的邏輯合約並劫持我的數據(似乎 Zeppelin 使用ifAdmin修飾符來處理這個問題)?

例如,假設我有契約MyLogicV1.sol

contract MyLogicV1 {
 uint256 public foo;
 // ...
}

我現在有 v2,它必須確保其數據的順序相同,並且只在現有數據之後附加新數據:

contract MyLogicV2 is MyLogicv1 {
 uint256 public foo;
 uint256 public bar;
 // ...
}

在上面的 MyLogicv1 中,與部署的第一個 MyLogicV2 的地址不同,因此數據會有所不同。

Zeppelin SDK 中提供的測試範例並沒有真正闡明任何意義,因為它們都部署在同一個測試中,這意味著合約相互引用。實際上,v1 已部署並獲得地址,v2 將在稍後的任意時間部署,可能在完全不同的交易中,不參考原始合約。

總而言之,v2 是 v1 的升級版,如何查看 v1 的數據以及如何保護?

考慮代理合約從邏輯合約中導入字節碼供自己使用可能在認知上很有用,因為它們在代理的上下文中執行並使用代理進行儲存。我意識到這對實施細節具有誤導性。

Proxy - execution context. data goes here
 |
 |
Implementation - logic 

升級後,你會得到這樣的東西:

Proxy - execution context. data still goes here
 |
 +-------------------------+
                           |
               Implementation V2 - new logic

代理需要知道合約的地址以用於實現細節。這將進入狀態變數或來自系統資料庫,並且將(必須!)特別注意以確保代理的儲存要求不會與實現的儲存佈局發生衝突。

實現的 V2 可以避免與 V1 的儲存佈局衝突的一種方法是繼承 V1,然後覆蓋函式,根據需要擴展儲存佈局,等等。在我看來,這可能比傾注程式碼和編譯器優化設置等更清晰、更可靠、更明確地陳述意圖,以確保佈局不會以任何方式改變。

contract V2 is V1 {
 // describe changes
}

最好從一種不需要對契約設計方式進行重大改變的最小方法開始。這個實現系統資料庫的範例可能會有所幫助:https ://github.com/rob-Hitchens/TrustlessUpgrades

另外,請嘗試使用此解釋器了解相同的方法:https ://medium.com/hackernoon/trustless-upgrades-in-solidity-bf0bd4047d28

希望能幫助到你。

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