摘要
我在上一篇文章《無鏈之鏈:Corda帶來的新視角》當(dāng)中,留下了一個最主要的問題(也許是兩個):Corda需要共識機制嗎讳癌?如果需要未状,這個共識機制應(yīng)該是什么樣子的?這個問題我相信很多人都會關(guān)心:一方面notary這種近乎信任中介的模式析桥,為什么還需要共識機制呢?另一方面R3又一直宣稱Corda也是有共識機制的艰垂,這不能不讓人產(chǎn)生困惑泡仗。前一段聽到R3的企業(yè)產(chǎn)品部門負(fù)責(zé)人Mike Ward簡介Corda的時候,受到相關(guān)概念的啟發(fā)猜憎,又重新開始考慮這個問題娩怎,并且有了一些新的想法。
本文首先詳細(xì)介紹一下基于notary的交易驗證機制胰柑,而后解釋一下STXO的概念以及其對系統(tǒng)實現(xiàn)的影響截亦,最后再針對Corda到底需不需要共識機制進(jìn)行分析,并給出筆者建議的一種共識機制實現(xiàn)方式的建議柬讨。
1. Notary模式回顧與分析
本節(jié)實際上是針對Corda的notary機制進(jìn)行詳細(xì)講解崩瓤,畢竟“無鏈之鏈”這篇綜述性的文章,并不能全面描述notary運行機制踩官∪赐埃考慮到notary是Corda至關(guān)重要的特點之一,同時也為了后面進(jìn)一步討論共識機制蔗牡,對notary模式的關(guān)鍵要點和流程進(jìn)行詳細(xì)介紹還是有必要的颖系。
Notary的基本運行方式
Corda基于notary進(jìn)行交易確認(rèn)的模式,可以簡單地這樣理解:一個notary記錄了通過他確認(rèn)的所有交易的輸入辩越、輸出狀態(tài)嘁扼,新來一個交易的時候,只需要對所有(成功的)歷史交易的輸入項進(jìn)行一個直接的查詢黔攒,就能知道新交易的所有輸入項中任何一個是否以前被使用過趁啸。只要所有輸入項都沒有被使用過,也就是不會發(fā)生雙花亏钩,整個交易(在輸入項這個維度上)就是合法的莲绰。
另一方面,Notary機制的要點之一姑丑,就是允許系統(tǒng)中存在多個這樣的角色蛤签,從而能夠讓相互之間不做交易的人使用不同的notary作為公證人。例如:Alice和Bob做交易栅哀,使用notary N1震肮,Carol和Dave做交易称龙,使用notary N2。這樣的設(shè)計才使得notary這個概念有意義戳晌,如果整個Corda網(wǎng)絡(luò)都必須采用同一個notary的話鲫尊,幾乎就退化成為了一個星形結(jié)構(gòu)(哪怕notary本身是一個大型的分布式網(wǎng)絡(luò),邏輯上仍然是一個整體)沦偎,中心化網(wǎng)絡(luò)的一切弊病都會回來了疫向,也就沒必要發(fā)明notary這個“新詞“了。
Corda的發(fā)明者們提出:通過上面這兩個機制豪嚎,Corda實現(xiàn)了隱私局部化搔驼、高性能、高可靠性等關(guān)鍵特性侈询。因此可以說這兩點是Corda的notary機制的核心特性舌涨,缺一不可。
多個Notary的問題
首先設(shè)想一個場景:Alice從Bob那里獲得了10元錢扔字,要通過一個交易把這十元錢的資產(chǎn)轉(zhuǎn)移給Dave的時候囊嘉,這個交易應(yīng)該通過哪個notary來確認(rèn)呢?如果Corda對于notary確認(rèn)交易的機制沒有其他規(guī)定的話革为,N1扭粱、N2都能對這個交易做確認(rèn):根據(jù)我們前面對notary機制的簡單解釋,如果這筆資產(chǎn)沒有在之前轉(zhuǎn)移給別人震檩,那么N1焊刹、N2當(dāng)然都不可能在自身的數(shù)據(jù)庫中查到使用過的記錄,因此都會認(rèn)為這個10元錢的資產(chǎn)狀態(tài)是有效的恳蹲。真的這么簡單嗎虐块,怎么隱約感覺會有點什么問題呢?
我們來考慮第二個場景:Alice想要實現(xiàn)“雙花”攻擊嘉蕾,也就是把這筆資產(chǎn)同時轉(zhuǎn)給Carol贺奠、Dave,他會怎么做错忱?此時如果他選擇N1來做這兩筆交易確認(rèn)的話儡率,N1作為驗證者,無論是采用任何同步以清、串行等機制儿普,一定會實現(xiàn)根據(jù)歷史狀態(tài)查出這個資產(chǎn)已經(jīng)轉(zhuǎn)移過一次的信息,從而拒絕這兩筆交易中還未成功的那個掷倔,這是notary模式的應(yīng)有之義眉孩。因此,對Alice而言,很顯然應(yīng)該選擇將這兩筆交易分別發(fā)送給N1浪汪、N2進(jìn)行確認(rèn)巴柿,期望有可能進(jìn)行攻擊∷涝猓可以想見广恢,如果系統(tǒng)沒有特殊機制應(yīng)對這種情況,而是任由N1呀潭、N2通過簡單的歷史狀態(tài)查詢方式來對這筆資產(chǎn)的有效性進(jìn)行驗證钉迷,由于查不到被使用過的記錄,一定都認(rèn)為它是有效的钠署,結(jié)果就發(fā)生了“雙花”篷牌。因此,系統(tǒng)必須設(shè)計一套機制來保證這兩個交易至少有一個不能成功踏幻。什么樣的機制呢?我們先來看看Corda關(guān)于notary進(jìn)行狀態(tài)確認(rèn)的原則:
- 狀態(tài)必須是基于notary的戳杀,也就是每個狀態(tài)會有一個notary“字段”该面,表明這個狀態(tài)當(dāng)前“基于”哪個notary
- 一個合法交易的所有輸入必須基于同一個notary
先來看第一條:由于每個狀態(tài)都有一個notary屬性,因此一個notary是能夠判斷這個狀態(tài)是不是“屬于”自己的信卡。有了這個信息隔缀,上面問題中所說的交易對于N1、N2來說就不是完全等同的傍菇,如果我們能夠根據(jù)這個信息設(shè)定一個機制來防止雙花猾瘸,就能解決這個問題了。很顯然丢习,我們只能要求那個發(fā)現(xiàn)待驗證交易的一個輸入項對應(yīng)的notary不是自己的時候做出反應(yīng)(在這個例子中是N2)牵触,他可以有兩個選擇:一是驗證失敗,本質(zhì)上就是拒絕驗證那些包含notary屬性不等于自己的狀態(tài)的交易咐低,因為這筆資產(chǎn)的狀態(tài)對應(yīng)的notary一定是N1揽思。另一選擇是他可以在驗證這個交易的時候根據(jù)該狀態(tài)的notary屬性向“原”notary(也就是N1)來發(fā)出請求,針對這個狀態(tài)進(jìn)行驗證见擦。這兩個方案看起來應(yīng)該都能滿足防雙花的需求钉汗,但稍微想一下就知道,方案二需要引入很復(fù)雜的機制才能實現(xiàn)鲤屡,這個留給讀者自行驗證损痰。毫無疑問,Corda選擇了前一個方案酒来,就是直接拒絕卢未。
Notary變更
上面的方案解決了一個問題,就是跨notary的“雙花”堰汉,但是故事并沒有結(jié)束尝丐。我們考慮第三個場景:Alice從Bob和Carol那里分別收到10塊錢显拜,其中與Bob的交易是N1確認(rèn)的,與Carol的交易是N2確認(rèn)的爹袁。他要把這20塊錢給Dave远荠,需要怎么做呢?我們先說合理的做法:他應(yīng)該發(fā)起一筆與Dave的交易失息,以兩個10塊錢的資產(chǎn)作為輸入譬淳,形成一個20塊錢的輸出,這也是UTXO模型的標(biāo)準(zhǔn)做法盹兢。但是根據(jù)上面的討論邻梆,我們會發(fā)現(xiàn)一個問題:這筆交易無論是發(fā)給N1確認(rèn)還是N2確認(rèn),都應(yīng)該會遭到拒絕——這也就是上述關(guān)于狀態(tài)驗證的兩個原則中的第二條所規(guī)定的含義——如果不拒絕绎秒,就無法杜絕Alice把其中一個十塊錢通過另一個notary進(jìn)行雙花的風(fēng)險浦妄。
當(dāng)然,我們可以有另一種做法见芹,就是要求Alice創(chuàng)建兩個交易剂娄,每個交易只有一個輸入項,然后分別交給當(dāng)初生成他們的交易所對應(yīng)的notary來確認(rèn)玄呛。這樣做是沒問題的阅懦,但是如果系統(tǒng)只允許這一種方案,就意味著Corda系統(tǒng)中的UTXO永遠(yuǎn)不能“合并”徘铝,本質(zhì)上Corda系統(tǒng)會被notary劃分成一個個永遠(yuǎn)無法互相通訊的子網(wǎng)耳胎,每個子網(wǎng)中都有所有那些需要互相交易的參與方。大家可以腦補一下這種景象惕它,notary+UTXO模型的“弊端”被“平方級”放大怕午,應(yīng)該屬于系統(tǒng)設(shè)計不良的范疇。
因此淹魄,只剩下一種可能性了:Corda必須提供一個可以把一筆資產(chǎn)/一個狀態(tài)/一個UTXO在不同notary之間轉(zhuǎn)移的手段诗轻。讀過“無鏈之鏈”這篇綜述文章的讀者應(yīng)該還記得,Corda專門設(shè)計了一種交易類型——notary變更交易揭北,用于將一個狀態(tài)在兩個notary之間轉(zhuǎn)移扳炬。同時,Corda也內(nèi)置了一個“Notary變更流程”的實現(xiàn)——NotaryChangeFlow搔体,這個flow接收兩個參數(shù):originalState, newNotary恨樟,主要完成以下工作:
- 創(chuàng)建一個交易(類型顯然是notary變更交易),以變更前的狀態(tài)作為輸入疚俱,產(chǎn)生一個變更后的新狀態(tài)作為輸出
- 獲得這個狀態(tài)的所有可能消費者的簽名(其實就是這個狀態(tài)的擁有者劝术,目前我還沒看到Corda當(dāng)中支持一個狀態(tài)有多個擁有者的設(shè)計,嚴(yán)格說這也不符合UTXO模型。不過不排除考慮可撤銷的狀態(tài)算是有兩個可能消費者的情況养晋?總之這是筆者的理解)
- 從狀態(tài)的原notary那里獲取簽名
- 完成該交易并將結(jié)果發(fā)送給參與方(也就是上面所說的所有可能消費者/擁有者)衬吆,這樣原舊狀態(tài)的擁有者就擁有新狀態(tài)了
簡單地說,一個狀態(tài)進(jìn)行notary變更绳泉,就是狀態(tài)的擁有者通過該狀態(tài)的當(dāng)前notary跟自己做了一個交易逊抡,這個交易的輸出狀態(tài)與輸入狀態(tài)之間只有一個變化,就是notary從舊的變成了新的零酪。這樣做顯然有一個好處冒嫡,就是舊的狀態(tài)也符合系統(tǒng)的規(guī)則:在交易完成之后就無效了,從而至少在舊notary的覆蓋范圍內(nèi)防止通過notary變更實現(xiàn)雙花四苇。
有了這套機制孝凌,我們先回過頭來看第二個場景——因為我們要保證這個新機制不能產(chǎn)生新的雙花攻擊的機會:Alice想要把一筆(已經(jīng)轉(zhuǎn)移給Dave的)資產(chǎn)轉(zhuǎn)移給Carol,如果他使用N1來驗證:此時N1會因為該資產(chǎn)已經(jīng)轉(zhuǎn)移而拒絕月腋;如果他使用N2來驗證蟀架,要么因為notary不同而被拒絕,要么必須首先進(jìn)行notary變更榆骚。而根據(jù)notary變更流程片拍,他同樣要跟N1做一個交易把資產(chǎn)的notary變成N2,N1仍然能知道這個狀態(tài)已經(jīng)在此之前交易過了寨躁,所以會拒絕這個變更交易,從而仍然能夠防止雙花牙勘。
現(xiàn)在來看第三個場景:Alice只要執(zhí)行若一次notary變更交易职恳,無論是把從Bob那里收到的10塊錢變更到N2上,還是把從Carol那里收到的10塊錢變更到N1上方面,就可以在對應(yīng)的notary上驗證這個新構(gòu)造的放钦、有兩個輸入和一個輸出的交易,從而實現(xiàn)轉(zhuǎn)賬恭金。同時操禀,后續(xù)無論通過什么方式進(jìn)行雙花攻擊,也都能被拒絕横腿,讀者可以自行驗證颓屑。
小結(jié)
簡單地說,Corda基于notary進(jìn)行交易確認(rèn)方式耿焊,在系統(tǒng)只有一個notary的情況下揪惦,通過對歷史交易記錄進(jìn)行查詢的方式就可以實現(xiàn)。一旦系統(tǒng)中有多個notary罗侯,并且出現(xiàn)“跨”notary的交易活動器腋,防止雙花的的職責(zé)當(dāng)然就涉及多個notary之間的“協(xié)同”。Corda結(jié)合交易場景,采用了一個比較標(biāo)準(zhǔn)的方式纫塌,就是不在交易過程中讓多個notary互動诊县,而是在交易之前必須把交易所需要的所有輸入狀態(tài)指定到驗證該交易的notary上,避免一個狀態(tài)可以在兩個notary上進(jìn)行驗證的情況措左,從而實現(xiàn)了防止雙花依痊。為此,Corda不僅設(shè)置了一種notary變更的交易類型媳荒,還內(nèi)置了變更流程抗悍,使得這些功能成為系統(tǒng)框架的一部分。