什麼是可升級的智能合約?
你可能知道,智能合約是所有可編程區塊鏈(如以太坊上)的一個重要組成部分。通過確保事情按照預定的規則運行,智能合約強制執行秩序。沒有智能合約,就沒有加密代幣、 NFT ,也沒有DApps 。但是,什麼是可升級的智能合約?嗯,首先,你需要注意,在這種情況下, "可升級"這個詞並不意味著可變異。 EVM的基本規則之一是,一旦合同被部署,它就不能被改變。相反,可升級的智能合約使用特殊的代理模式。後者涉及部署代理合同和執行合同(邏輯合同)。
為什麼要使智能合約達到可升級
智能合約的特點之一就是部署到鏈上之後不能修改,這一機制使得合約的交互方都可以信任合約。但也帶來了一系列的問題,並且如果已部署的合約發現漏洞,也是無法修復的。假如發現了bug ,致命性的,必須修復,那如何處理?就是使用合約達到可升級優化才能滿足需求。
可升級智能合約如何工作?
看上面的示意圖,你可以看到用戶通過代理合同與邏輯合同進行互動。由於代理合同能夠存儲邏輯合同的地址,這才成為可能。然後,我們通過部署一個新的邏輯合約來整合升級。當然,我們也需要在代理合同中更新邏輯合同的相關值,以實際實現升級。
有許多代理模式可用,它們可以用來創建可升級的合約。此外,雖然也有很多類型的代理模式,但大多數代理模式都使用transparent透明代理和UUPS (通用可升級代理標準)。幸運的是,這兩種類型在OpenZeppelin也有提供,這讓開發者的工作變得簡單了許多。此外,這也是一個捷徑,在我們進行一個例子項目時,你會了解更多。
透明代理與UUPS代理
如上所述,透明和UUPS代理模式是最常見的兩種類型。雖然這兩種類型都遵循相同的基本原則(如上所述),但它們的設計卻截然不同。因此,我們需要對它們進行快速比較。以下是兩種代理模式類型各自的一些主要特徵:
透明代理模式類型:
l升級由代理合同處理
l部署成本更高
l易於維護
UUPS 代理模式類型:
l升級由實施合同處理。這也意味著您需要將升級功能實現到實現合同中。否則,您將無法升級您的智能合約
l部署更便宜
l它使維護更具挑戰性
可升級智能合約案例
Params.sol 邏輯合約
部署後的合約地址: 0x2CC6F64C688B0f9585B2fF4134420A5B74faD836 , initialize方法對應的code為0x8129fc1c (部署代理合約的時候會用到)
ProxyAdmin.sol 管理合約
部署後的合約地址: 0xcCFB00D3dd840dea0E4E258A07F870344d0fe9A4
TransparentUpgradeableProxy.sol 代理合約,DAPP直接交互的合約地址
部署需要參數,如下:
l _LOGIC:邏輯合約地址,這里為0x2CC6F64C688B0f9585B2fF4134420A5B74faD836 ( Params.sol合約部署地址)
l ADMIN_ :管理合約地址,這里為0xcCFB00D3dd840dea0E4E258A07F870344d0fe9A4 (ProxyAdmin.sol合約部署地址)
l _DATA :邏輯合約初始化方法調用數據,這里為0x8129fc1c(Params.sol initialize方法code) (只調用initialize方法, initialize方法沒有入參,如果有參數也是支持的)
部署後地址為: 0xfa01ae0B2854E1F7496F879b82547a7091Bd74d5
可以使用web3測試合約是否部署成功:
至此可升級合約部署完成。
合約升級
ParamsV2.sol 升級後的邏輯合約
部署後的合約地址: 0xeC05F7fFf671ae6c8368432AA8d3499D53B4F967
調用ProxyAdmin進行升級
ProxyAdmin提供兩個方法進行升級
l upgrade ,需要傳入proxy地址,新的邏輯實現地址
l upgradeAndCall ,需要傳入roxy地址,新的邏輯實現地址,初始化調用數據
本例中,由於數據是保存在代理合約中,這份數據已經初始化過了,不需要再初始化,所以調用upgrade方法即可,參數如下:
l proxy: 0xfa01ae0B2854E1F7496F879b82547a7091Bd74d5
l implementation: 0xeC05F7fFf671ae6c8368432AA8d3499D53B4F967
至此,合約升級完畢。
測試升級後的合約,同理使用代理合約調用新的合約
dapp鏈接: https://www.chainpip.com/dapp-view/6752
原文鏈接(含可複制代碼): https://www.chainpip.com/dynamic/234