1. 程式人生 > >Plasma Cash完全解析

Plasma Cash完全解析

上一篇分析了Plasma MVP的原理和實現,這一篇介紹一下Plasma的另外一個實現版本:Plasma Cash。

1.和MVP的區別

Plasma Cash和MVP最大的不同在於使用稀疏Merkle樹代替了標準Merkle樹。我們都知道,Merkle樹的好處在於可以利用很少的資料來證明某筆交易“存在”於某個區塊中,那麼稀疏Merkle樹有什麼好處呢?除了可以證明某筆交易“存在”於某個區塊中以外,它還可以證明某筆交易“不存在”於某個區塊中!

怎麼做到的呢?其實也很簡單:計算區塊Merkle根時使用一個固定高度(257層)的Merkle樹,每個uid對應一個葉子節點(忽略雜湊碰撞概率)。如果該區塊中包含某個uid的交易,則在對應的葉子節點處放置該交易,其他葉子節點都為0。這樣一來,如果我們需要證明區塊中不存在針對某個uid的交易,只需要提供0的雜湊值和對應的merkle proof就可以了!
在這裡插入圖片描述

2.充值

Plasma Cash是用來儲存和轉移非同質(non-fungible)代幣的。所謂非同質代幣,是指這些代幣不可分割、不可互相替代。這一點在遊戲領域比較容易理解:某個代幣可能代表一把劍,另一個代幣可能代表一個盾牌,這兩個裝備的價值是不同的,另外你也不可能把劍或者盾牌拆成一小塊一小塊地賣給別人。舉個具體的例子:你充值10ETH,會生成一個代幣,然後你再充值100ETH,又會生成另外一個代幣。這兩個代幣的價值顯然是不相同的,無法互相替代,同時你跟別人交易時只能更改代幣的所有權,不能把它們分割成一小份一小份地花掉。以Omisego的實現為例,主鏈上會生成兩個funds物件,併為它們各自分配一個uid,最後傳送Deposit事件:

uint uid = uint256(keccak256(currency, msg.sender, depositCount));
wallet[uid] = funds({
    hasValue: true,
    isConfirmed: false,
    amount: amount,
    depositor: msg.sender
});
depositCount += 1;
emit Deposit(msg.sender, amount, uid);

operator監聽到這個Deposit事件,在側鏈上為這個uid生成一筆deposit交易,之後就可以在側鏈上自由交易這個新資產了。

3.交易

之前提到過,資產是不可分割的,交易只能轉讓所有權。

在Omisego的實現中,每筆交易中包含下面幾個欄位:

  • uid:資產唯一標識
  • amount:和uid關聯的充值金額(用於驗證)
  • new_owner:資產的新主人
  • sig:交易簽名
  • prev_block:上一筆交易所在的區塊高度
  • spent:新主人是否又把資產花出去了

重點在於後面兩個引數的驗證:首先在prev_block中查詢該uid對應的交易,如果有並且spent為false,則說明當前這筆交易是有效的,並且把prev_block中的那筆交易的spent設定為true。
在這裡插入圖片描述

4.退出 & 挑戰

使用者想從側鏈上退出時,需要提供要退出的交易和它上一筆交易的merkle proof用於驗證,我們看一下startExit()的函式原型:

    function startExit(
        bytes prevTx,
        bytes prevTxProof,
        uint prevTxBlkNum,
        bytes tx,
        bytes txProof,
        uint txBlkNum
    )

也就是說,要證明有人把錢轉給了你,還要證明一下他的錢是從哪裡來的。

如果使用者發現了一筆非法退出請求,則需要對其發起挑戰。我們把要退出的交易稱為child,它的上一筆交易稱為parent,則可以分為3種情況:

1.child交易的後面有人把錢花掉了

如下圖所示,說明C對uid 100進行了雙花,挑戰立即成功:
在這裡插入圖片描述

2.parent和child交易之間還有關於這筆資產的交易

如下圖所示,說明parent並非child的上一筆交易,挑戰立即成功(B有可能對uid 100進行了雙花):
在這裡插入圖片描述

3.parent之前有疑似雙花的交易

如下圖所示,A有可能對uid 100進行了雙花。此時挑戰不會立即成功,但會加入挑戰列表。被挑戰的人必須響應該次挑戰,證明在這兩筆衝突的交易之間,uid 100又被重新轉給了A(紫色交易),否則無法完成提現:
在這裡插入圖片描述

5.優點和缺點

Plasma Cash具有非常高的可擴充套件性,由於使用了稀疏Merkle樹,使用者只需要關心他們自己的代幣的流向。

當然,缺點也是很明顯的,它只能支援非同質代幣的交易,適用範圍非常侷限。後面會有一個叫Plasma Debit的專案來解決這一問題。另外,有人詬病驗證代幣所有權時需要比較大的資料量的問題,有一個叫做Plasma XT的專案正在試圖使用checkpoint的手段消除這一缺陷的影響。

參考:

https://github.com/omisego/plasma-cash

https://medium.com/@kelvinfichter/whats-a-sparse-merkle-tree-acda70aeb837

https://www.learnplasma.org/en/learn/cash.html

更多文章歡迎關注“鑫鑫點燈”專欄:https://blog.csdn.net/turkeycock
或關注飛久微信公眾號:
在這裡插入圖片描述