有趣的DApp 設計模式:First-class Asset

本篇文章的作者是Jan,文章闡述了Cell 模型中支持的一種非常有趣的DApp 設計模式:First-class Asset,它讓加密資產變成區塊鏈中的「一等公民」。
二級標題
二級標題
狀態模型的快速入門
在Cell 模型之前,各種區塊鏈使用的狀態模型基本上就是兩種:UTXO 模型和Account 模型。
正文

正文

First-class Coin
UTXO 模型和Account 模型代表了構建賬本狀態的兩種思路。賬本是所有者與資產之間關係的集合。 UTXO 模型以資產為基礎建模,先構建出「硬幣」的概念,再給硬幣賦予所有者的屬性;Account 模型以所有者為基礎建模,先構建出「賬戶」的概念,再給賬戶賦予餘額的屬性。以哪種方式作為基礎模型決定了系統中的操作的基本對像是資產還是賬戶(所有者)。
所以我們說,硬幣(Coin)是UTXO 模型中的First-class Citizen,每一個UTXO 都是一個具有獨立標識符的對象(Transaction ID + Output Index),Coin 是用戶直接操作的對象(用戶在構造的交易中包含UTXO),賬戶是基於Coin 建立的上層概念(只存在於錢包中)。因此UTXO 是First-class Coin。

在Account 模型中,賬戶是First-class Citizen,聚合在賬戶餘額中的硬幣沒有獨立的標識符。賬戶是用戶直接操作的對象,資產的轉移是由賬戶作為用戶的代理實現的,這一點在接受方是合約賬戶時體現的最為明顯。在這樣的模型下,用戶定義加密資產(例如ERC 20)更像是通過第三方記賬的方式,而非點對點的方式轉移,這個差異會將第三方(這裡的第三方指的是託管加密資產的智能合約)引入資產轉移流程,增加智能合約的設計複雜度(我們可以把智能合約看作在資產轉移時會自動執行的邏輯)。為了降低這種複雜度,Account 模型中的交易需要加入特殊的邏輯(Value 字段),但是這樣的特殊邏輯只有助於原生資產,同時造成對原生資產和用戶自定義資產的不同代碼路徑。
對於這些問題,Kelvin Fitcher 寫過一篇Looking at ownership in the EVM進行了很好的分析,在此不再贅述。

有了這些背景,我們應該更容易理解CKB 的這一設計理念了:
二級標題
二級標題
First-class State
如何實現First-class Assets 呢?
無論用何種方式,我們都需要記錄所有者和資產之間的關係。這些關係記錄,本質上是經過共識的狀態。要有First-class Assets, 必須先有First-class State,而這正是Cell 模型的出發點。
Nervos CKB 的名字來自於Common Knowledge Base(共同知識庫)的縮寫。我們之所以把Nervos 網絡中的區塊鏈稱為「共同知識庫」,是因為它的責任是持續不斷的對網絡的共同狀態形成全球共識,換句話說,CKB 是一個由全球共識維護的狀態庫。一個狀態庫的基本模型,很自然的是將整個狀態劃分為更小的狀態單元組織起來。這些更小的狀態單元,就是Cell。
由於Cell 是一種狀態單元,有獨立的標識符(Transaction ID + Cell Output Index),可以被直接引用,作為參數傳遞給腳本,它是CKB 中的「一等公民」,也就是說狀態是CKB中的「一等公民」。 Cell 不僅僅是一種First-class State,而且是最簡單的一種First-class State:一個Cell 中只有Capacity,Data,Lock 以及Contract(可選,Contract 可以是一段代碼或者指向一個Code Cell 的Reference )四個字段。
如下圖所示,Cell 的所有者可以直接更新Cell 中保存的狀態,不需要經過任何中間方,而在Account 模型中用戶只能通過合約代碼(賬戶中的Code)來操作賬戶內的狀態,狀態實際上是託管在合約手中的。

值得指出的是,有了Cell,CKB 實際上就獲得了一種有狀態的編程模型。一種普遍的觀點是,以太坊編程模型的表達能力來自圖靈完備的虛擬機,實際上通過賬戶使得智能合約能夠保存計算狀態是一個大過EVM的優點(圖靈不完備的語言也有很強大的表達能力:https://en.wikipedia.org/wiki/Total_functional_programming)。
CKB 通過Cell 和CKB-VM(Simple Yet Powerful! 這得另外寫一篇文章了)的組合實現了一種新的有狀態的智能合約編程模型。這個編程模型更加適合Layer 2,因為通過分析Layer 2 協議的共同模式我們可以看到,協議層之間的交互對象應該是狀態對象(State Transaction)而不是事件對象(Event Transaction),Layer 1 應該是一個狀態層而不是計算層。
CKB 編程模型的另一個特點是,不區分數據(狀態)和代碼。這句話的意思是,與Account 模型不同,合約的狀態和代碼都可以儲存在Cell 的Data 字段中,保存代碼的Cell 可以被其它Cell 引用(因為它們是First-class State!),合約的狀態和代碼不需要綁定在一起,存放在一個地方。開發者可以通過一條簡單的指令把代碼Cell 或者數據Cell 的內容載入運行時內存,然後根據需要自行將其解釋為代碼執行或者數據來讀寫。

有了這些底層支持,我們就可以將一個合約的代碼和狀態分開保存在不同的地方:Code Cell 的Code(Data)字段存放代碼,而State Cell 的State(Data)的字段則保存狀態;在State Cell 中通過Contract ref 引用Code Cell 來建立對自身保存的State 的業務邏輯約束,通過Lock ref 引用另外一個Code Cell 來表達State Cell 的所有權。每一個State Cell 可以屬於不同的用戶,因此在Cell 模型下獨立的用戶狀態是非常容易實現的模式(在Account 模型下,合約狀態往往由多個用戶狀態混合構成,例如在一個ERC 20 合約中, Alice 和Bob 的Token 餘額都記錄在同一個合約的內部狀態裡面)。
二級標題
二級標題
First-class Asset
CKB 中的用戶定義資產(User Defined Asset)可以這樣來構造:
設計資產定義合約(Asset Definition),規定資產的主要約束(例如總數量,發行者,交易前後數量不變等);
保存合約代碼到Asset Definition Cell 中;
在滿足發行權限的情況下,發行者發行資產,並將資產狀態保存在另外的State Cell中。 State Cell 的Contract 字段引用保存了資產定義的Code Cell,保證State Cell 的變化受到資產定義的約束;
Asset Cell 的持有者可以通過更新Lock 來改變Asset Cell 的所有者。

可以看到,在這樣的設計中,用戶定義的資產是作為獨立對象存在於系統中的,每一份資產都是一個Cell,每一份資產都擁有自己的標識符。我們完全可以認為Asset Cell 是UTXO 的通用化版本。這樣的First-class Asset 有如下優點:
Asset Cell 可以被引用,可以直接作為其它合約的參數傳入。只要引用Asset Cell 的Input 有正確的用戶授權,合約就可以正常的使用用戶的Asset Cell;
資產定義與資產狀態分離。 Asset Definition Cell 的所有者是資產的發行者,而Asset Cell 是屬於每個用戶的。 Asset Cell 的授權邏輯和業務邏輯分離,所有權完全由自己的Lock 決定,與Asset Definition 的邏輯無關,這意味著First-class Asset 不是託管在資產發行者、開發者或是資產定義合約的手中,而是真正完全屬於用戶的;
用戶的資產相互隔離,用戶資產狀態獨立。 CKB 的經濟模型關注狀態存儲激勵問題:用戶在區塊鏈上保存狀態不僅需要支付寫入費用,而且應該承擔與存儲時間成正比的存儲成本。如果用戶的資產狀態混合在一個地方保存(例如ERC 20),這些狀態的存儲成本有誰來支付將是一個問題。 (CKB Economics Paper 正在努力寫作中…);
二級標題
二級標題
Summary
Cell 模型是一個高度抽象的模型,事實上,你不僅可以在Cell 上實現First-class Asset,也可以在Cell 上模擬Account。通過這篇文章的介紹我們可以看出,Cell 模型是一個不同於UTXO 模型和Account 模型的新設計。除了狀態模型的不同,CKB 還將計算(也就是狀態生成)轉移到了鏈外,在鏈上只需要對狀態進行驗證的邏輯。獨特的狀態模型和計算驗證分離這兩點決定了CKB 的編程模型上必然會出現新的DApp 範式和設計模式。
從CKB 白皮書完成到現在將近一年的時間中,我們看到越來越多的人開始關注和討論First-class State 和First-class Asset 這兩種新的思路(雖然大家用的名詞各自都不一樣),這些進展讓我們非常興奮。如果你有興趣對First-class State 和First-class Asset 進行更多的探討,或是在CKB的編程模型上有什麼有趣的想法,歡迎聯繫我們討論 ~
CKB 的代碼已經完全開源,這篇文章介紹的內容在代碼中都已經實現。歡迎給我們的代碼提出各種意見:
https://github.com/nervosnetwork/ckb-demo-ruby-sdk (CKB 上用Ruby 腳本編程的示例,理解CKB 上編程模型的最佳入口)
https://github.com/nervosnetwork/ckb
https://github.com/nervosnetwork/ckb-vm
感謝Ian Yang,Xuejie Xiao,Kevin Wang 在CKB 和Cell 模型設計中提供的幫助 ~


