淺談以太坊智能合約的設計模式與升級方法__智能合約

來源:互聯網
上載者:User
淺談以太坊智能合約的設計模式與升級方法 1. 最佳實務 2. 實用設計案例 2.1 控制器合約與資料合約: 1->1 2.2 控制器合約與資料合約: 1->N 2.3 控制器合約與資料合約: N->1 2.4 控制器合約與資料合約: N->N 2.5 總結 3. 升級 3.1 控制器合約升級,資料合約不升級 3.2 控制器合約不升級,資料合約升級 3.3 控制器合約升級,資料合約升級 4. 資料移轉 4.1 寫入程式碼遷移法 4.2 硬拷貝遷移法 4.3 默克爾樹遷移法 淺談以太坊智能合約的設計模式與升級方法

以太坊EVM是當前區塊鏈行業應用最為廣泛的虛擬機器。其所支援的智能合約語言是圖靈完備的。該語言支援各種基礎類型(Booleans,Integers,Address,String,Enum,Address等)、複雜類型(Struct,Mapping,Array等)、複雜的運算式和控制結構及介面繼承等物件導向的特性。

正是由於強大的智能合約語言,原本在真實世界中的複雜商業邏輯和應用都能在區塊鏈上輕鬆實現。然而需要注意的是,儘管公有鏈可以實現合理的GAS機制自我保護,聯盟鏈可以用其他機制替代GAS的計算及代幣化來保障EVM沙箱安全,但由於區塊鏈運行機制的原因,智能合約的運行即使是異常運行都會在所有區塊鏈節點上獨立重複運行。因此,無論是在公有鏈還是聯盟鏈運行智能合約都是非常昂貴(運算資源、儲存資源)的操作。

另外,智能合約與傳統應用程式有一個不同的地方在於智能合約一經發佈於區塊鏈上就無法篡改,即使智能合約中有Bug需要修複或者商務邏輯變更,它也不能直接在原有的合約上直接修改再重新發布。因此在設計之初就需要結合業務情境考慮合理的升級機制。

總而言之,智能合約實現上要達到的目標是:完備的業務功能、精悍的代碼邏輯、良好的模組抽象、清晰的合約結構、合理的安全檢查、完備的升級方案。

智能合約的生命週期主要有設計、開發、部署、運行、升級、銷毀。在下文中主要是基於目標在設計階段、升級階段的一些梳理總結。 1. 最佳實務

從業務視角來看,智能合約只需要做兩件事,其一是如何定義資料的結構和讀寫方式,其二是如何處理資料並對外提供服務介面。

為了更好的做好模組抽象和合約結構分層,將這兩件事分開,既是將業務控制邏輯和資料從合約代碼層面就做好分離,這樣的處理在複雜商務邏輯情境中經過實踐是當前被認為最佳的模式。

這個模式簡稱為CD(Controller-Data)模式。將合約分為兩類:控制器合約(Controller Contract)與資料合約(Data Contract)。

控制器合約通過訪問資料合約獲得資料,並對資料做邏輯處理,然後寫回資料合約。�它專註於對資料的邏輯處理和對外提供服務。根據處理邏輯的不同,常見的有命名空間控制器合約、代理控制器合約、業務控制器合約、工廠控制器合約等。一般情況下,控制器合約不需要儲存任何資料,它完全依賴外部的輸入來決定對資料合約的訪問。特殊情況下,控制器合約可以儲存某個固定的資料合約的地址或者命名空間(通過命名空間在運行時獲得合約地址)。

資料合約專註於資料結構定義與所儲存資料的讀寫裸介面。為了達到資料統一訪問管理和資料存取權限控制的目的,最好是將資料讀寫介面只暴露給對應的控制器合約。禁止其他方式的讀寫訪問。

基於這個模式,遵循從上至下的分析方式,從對外提供的服務介面開始設計各類控制器合約,再逐步過渡到服務介面所需要的資料模型和儲存方式,進而設計各類資料合約,可以較為快速的完成合約架構的設計。 2. 實用設計案例

在CD模式下,根據控制器合約與資料合約之間的操作關係,從邏輯上歸結為四類: 控制器合約與資料合約 1->1 控制器合約與資料合約 1->N 控制器合約與資料合約 N->1 控制器合約與資料合約 N->N

假設一個業務情境:將全國所有銀行的業務和資訊上鏈。 2.1 控制器合約與資料合約: 1->1

假設全國只有兩家銀行,A銀行和B銀行。A銀行只有存款業務,B銀行只有取款業務。一種可能的設計是這樣的:

代理控制器合約:面向Dapp,是所有業務合約的入口,提供命名空間服務,提供了命名空間到合約地址的映射。使得Dapp對鏈上合約升級導致的地址變更無感知。例如,Dapp對A銀行的存款請求只需要(“BankA",deposit,args) 即可。對B銀行的取款請求只需要(”BankB",withdraw,args)即可。代理器控制合約實現上應該是區塊鏈底層內建的、固化的,或者是業務上極少變更的。Dapp在業務運行之前已經明確知道代理控制器合約的地址。

命名控制器合約:面向鏈上合約,提供命名空間服務,提供了命名空間到合約地址的映射。使得鏈上合約可以在運行時根據命名獲得實際的合約地址。例如,A銀行控制器合約向命名控制器合約請求(“BankA-Data"),可以獲得A銀行資料合約地址,使得A銀行控制器合約可以在運行時訪問A銀行資料合約。它與代理控制器合約的主要不同在於服務物件的不同,代理控制器合約面向Dapp,命名控制器合約面向鏈上合約。另外,命名控制器合約包含有版本控制的設計(下文第3.2節介紹),可以根據需要配合灰階策略的實施。

A銀行控制器合約:提供了存款服務介面deposit。部署初始化時已經明確知道自己的身份”BankA"。並且可以在運行時通過命名控制合約獲得”BankA“的資料合約“BankA-Data"的地址。

A銀行資料合約:儲存了A銀行的當前餘額。提供add和sub介面給A銀行控制器合約來更新喻額資訊。

B銀行控制器合約:提供了存款服務介面withdraw。部署初始化時已經明確知道自己的身份”BankB"。並且可以在運行時通過命名控制合約獲得”BankB“的資料合約"BankB-Data"的地址。

B銀行資料合約:儲存了B銀行的當前餘額。提供add和sub介面給B銀行控制器合約來更新喻額資訊。

對A銀行的存款請求的流程是這樣的: Dapp指定代理控制器合約地址,請求存款交易(“BankA",deposit,money) 代理控制器合約,運行時得到”BankA"對應的A銀行控制器合約地址,並向A銀行控制器合約請求存款交易(deposit,money) A銀行控制器合約的deposit介面向命名控制器合約請求A銀行的資料合約“BankA-Data"的地址,並訪問到A銀行資料合約的資料,然後執行一些存款商務邏輯。返回結果。 依次返回結果到Dapp。 2.2 控制器合約與資料合約: 1->N

假設全國有N家銀行,所有銀行都有存款業務和取款業務,並且商務程序都是一樣的。一種可能的設計是這樣的:

這個設計與上面的2.1不一樣的地方在於,將存款服務介面和取款介面都集中歸結到銀行業務控制器合約裡面了。這意味著任何銀行的存款和取款業務都由銀行業務控制器合約來統一處理,處理邏輯上不再區分是A銀行還是B銀行,只是在資料訪問的時候需要根據入參的不同來決定訪問不同的銀行資料合約。

還有,於2.1相比,對於Dapp而言,它發出請求的時候只需要將請求發往固定的”Bank"就可以了,不用具體關心某個銀行。

另外,由於銀行有很多個,並且它們的儲存結構都是一樣的,因此可以設計一個銀行資料合約的工廠控制器合約,來負責對新的資料合約的產生實現模板化。

對A銀行的存款請求的流程是這樣的: Dapp指定代理控制器合約地址,請求存款交易(“Bank",deposit,”BankA“,money) 代理控制器合約,運行時得到”Bank"對應的銀行業務控制器合約地址,向銀行業務控制器合約請求存款交易(deposit,”BankA“,money) 銀行業務控制器合約的deposit介面向命名控制器合約請求A銀行的資料合約“BankA-Data"的地址,並訪問到A銀行資料合約的資料,然後執行一些存款商務邏輯。返回結果。 依次返回結果到Dapp。 2.3 控制器合約與資料合約: N->1

假設全國有N家銀行,所有銀行都有存款業務和取款業務,並且商務程序都是一樣的,但是由於商務邏輯較為複雜,出於模組化維護的需要,需要將存款業務和取款業務做分拆。一種可能的設計是這樣的:

這個設計與上面的2.2不一樣的地方在於,將存款服務介面和取款介面拆分到了不同的業務控制器合約裡面了。這意味著不同的商務邏輯從模組上做了清晰的切分。對於Dapp而言,它發出請求的時候需要明確指向所對應的業務介面。

對A銀行的存款請求的流程是這樣的: Dapp指定代理控制器合約地址,請求存款交易(“deposit",”BankA“,money) 代理控制器合約,運行時得到”deposit"對應的存款業務控制器合約地址,向存款業務控制器合約請求存款交易(”BankA“,money) 存款業務控制器合約的deposit介面向命名控制器合約請求A銀行的資料合約“BankA-Data"的地址,並訪問到A銀行資料合約的資料,然後執行一些存款商務邏輯。返回結果。 依次返回結果到Dapp。 2.4 控制器合約與資料合約: N->N

此類情況可以拆解為上面三種情況的組合。不再贅述。 2.5 總結

從Dapp視角考慮,可以總結如下:

CD模式 特點
1->1 面向業務對象
1->N 面向商務程序
N->1 面向業務介面
N->N /
3. 升級

在CD模式下,在商務邏輯變更需要升級合約的情況下,根據控制器合約與資料合約的升級關係來劃分,可以歸納為以下三種情況:

控制器合約 資料合約
升級 不升級
不升級 升級
升級 升級

在升級過程中,還需要考慮是全量升級還是灰階升級。如果是灰階升級,灰階策略是怎麼樣的。另外,在多鏈情境和單鏈情境、跨鏈情境,升級過程是否有不同。多鏈情境的灰階策略如何考慮。新舊版本資料能否共存。如果需要資料移轉,如何做到無縫遷移?

下面以最為常見的1->N 情境來介紹不同的升級情況。 3.1 控制器合約升級,資料合約不升級

如上圖所示,銀行業務控制器合約從V1升級到V2,而其他的合約和介面都是不需要更新的,假設V2版本相對V1版本只是升級withdraw這個介面。

此時,V2版本的銀行業務控制器合約需要做的事情是: 繼承V1版本的銀行業務控制器合約。 增加一個指向V1版本的鏈上合約地址的成員變數。 增加一個withdraw開關介面,允許外部賬戶通過普通交易來操作V2版本合約的啟停灰階策略。 重載withdraw介面。升級對應的介面邏輯。並且在商務邏輯真正開始執行之前,自訂實現灰階策略(譬如灰階特定使用者,或者一定比例使用者或者其他策略)。並且需要注意的是在開啟灰階開關的情況下,如果請求沒有命中灰階策略,則直接透傳參數調用V1版本的合約介面,V2版本的withdraw介面不做任何額外工作。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.