最新內容會更新在主站深刻淺出區塊鏈社區
原文連接:深刻理解Plasma(四)Plasma Cashgit
這一系列文章將圍繞以太坊的二層擴容框架 Plasma,介紹其基本運行原理,具體操做細節,安全性討論以及將來研究方向等。本篇文章主要介紹在 Plasma 框架下的項目 Plasma Cash。github
在上一篇文章中咱們已經理解了 Plasma 的最小實現 Plasma MVP 如何使用 UTXO 模型實現 Plasma 鏈下擴容的核心思想。但因爲 Plasma MVP 自己過於簡單,並不能用於實際的生產環境中。2018 年 3 月,在巴黎舉行的以太坊開發者大會上,Vitalik 發佈了 Plasma Cash 模型[1],能夠視爲對 Plasma MVP 的改進。Plasma Cash 與 Plasma MVP 的主要區別是每次存款操做都會產生一個惟一的 coin ID 對應轉移到側鏈上的資產,並使用一種稱爲稀疏梅克爾樹(Sparse Merkle Tree)的數據結構存儲交易歷史。由此帶來的好處是用戶不須要關注子鏈上的每一個動態,只須要關注跟本身的 token 有關的動態。在下文中將介紹具體細節。安全
Plasma Cash 中的每次存款操做都會對應產生一個 NFT(non-fungible token)[2]。NFT 能夠簡單理解爲「不可互換的 token」,即每一個 token 都是獨一無二的,由惟一的 ID 標記。以太坊官方爲 NFT 提供了 ERC721 標準[3],在以前火爆到阻塞以太坊的 CryptoKitties 就是由 ERC721 合約實現的。微信
在 Plasma Cash 中,當用戶向 Plasma 合約發送存款交易時,合約會生成一個與存款等值的 token,並給這個 token 分配一個惟一的 ID。若是一個用戶分別執行兩次存款操做,且每次存款都是 5 ETH,那麼他將獲得相等價值的兩個徹底不一樣的 token。和 Plasma MVP 同樣,每次存款操做都會使得 Plasma 合約產生一個只包含這個存款交易的區塊。數據結構
Plasma Cash 中的每一個 token 都被分配惟一的 ID,所以能夠按 ID 的順序存儲每一個 token 的交易歷史。Plasma Cash 的區塊按 token ID 的順序給每一個 token 分配了一個插槽(slot),每一個插槽會記錄這個 token 是否被交易的信息。例如在下圖(來源[4])的區塊中,包含 4 個 token,id 分別是 #1,#2,#3,#4。其中 #1,#2,#3 被標記爲沒有被花費,而 #4 由用戶 A 發送給用戶 B。框架
從上面這個例子中咱們能夠看到,每一個插槽記錄了其所對應的 token 在當前區塊中的交易狀態,全部存儲了某個 token 的交易狀態的區塊按時間順序連在一塊兒就構成了這個 token 的所有交易歷史。每當一個 token 被分配了一個 id,以後的全部交易狀態都會被保存在每一個區塊相同的插槽中,也不會被其它 token 取代。所以,用戶只須要關注每一個區塊中存儲屬於本身的 token 的狀態,徹底不用關心別的插槽存儲的內容。less
因爲 Plasma Cash 中的節點只追蹤屬於本身的 token 的交易歷史,所以當有交易發生時,token 的發送者要向接收者提供關於這個 token 全部的交易歷史(從存款交易開始)以便接收者驗證。從下圖(來源[4])的例子中能夠看到 4 個區塊中所記錄的 4 個 token 的交易歷史。學習
截止到區塊 #4,能夠看到token #1 和 token #3 始終沒有被交易。token #2 在區塊 #2 被 E 發送給了 F,在區塊 #4 被 F 發送給了 G,在其它區塊沒有發生交易,token #2 的最終全部權歸 G。token #4 在區塊 #1 被 A 發送給了 B,在區塊 #3 被 B 發送給了 C,在其它區塊沒有發生交易,token #4 的最終全部權歸 C。F 爲了向 G 證實 token #2 的合法性,須要向 G 提供 token #2 在前 4 個區塊中的全部交易歷史,也就是說不只須要包括區塊 #2 中 E => F 的交易證實、區塊 #4中 F => G 的交易證實,還要包括在區塊 #1 和 #3 中沒有被交易的證實。到這裏可能感受有點奇怪,爲何還要包括沒有被交易的證實?這是爲了防止雙花,由於 G 並不知道在區塊 #1 和 #3 中 token #2 是否被交易給了其它人。假如 F 在區塊 #3 中將 token #2 發送給了 H,而且對 G 隱瞞了這個交易,那麼發生在區塊 #4 中的 F => G 就是非法(雙花)的。所以,在 Plasma Cash 中,完整且合法的交易歷史是一個 token 被安全交易的前提。區塊鏈
在上文中咱們已經瞭解到一個交易的成功的前提是須要發送方提供關於一個 token 的完整交易歷史。完整的交易歷史既包括這個 token 在哪些區塊被交易的信息,也包括這個 token 在哪些區塊沒有被交易的信息。咱們都知道,在區塊鏈中,使用梅克爾樹(Merkle Tree,MT)構造梅克爾證實(Merkel Proof, MP)能夠在 O(logN)的時間複雜度驗證一個交易是否存在一個區塊中。但想要證實一個交易沒有存在一個區塊中,使用標準的梅克爾樹卻沒那麼容易。所以,Plasma Cash 中使用了一種稱爲稀疏梅克爾樹(Sparse Merkle Tree,SMT)的數據結構存儲交易數據,可以在O(logN)的時間複雜度驗證一個交易不存在。spa
SMT 實際上一點都不復雜,它的葉子節點是按數據集中的元素序號順序排列的。若是某個葉子節點對應的元素爲空,那麼該葉子節點將存儲一個特定的值(例如 0 的哈希值)。一個簡單的 SMT 示例以下圖(來源[5])所示。
擴展到 Plasma Cash 中,SMT 的葉子節點對應了區塊中給每一個 token 分配的插槽,按照每一個 token 的 ID 排序。每一個葉子節點存儲對應的 token 的交易信息,若是 token 在這個區塊中沒有被交易,則相應的葉子節點存儲的值爲 null。
以上圖爲例,若是須要證實交易 A 存在,就像在標準的 MT 中同樣,須要構造 MP:H(null) 和 H(H(null) + H(D))。若是須要證實 B 不存在,一樣很簡單,咱們已經知道 B 的位置是第二個葉子節點,若是 B 不存在,那麼該節點存儲的值應該爲 null。所以就像在標準的 MT 中證實存在的 MP 同樣,只不過須要加上 H(null) 做爲 MP 的一部分,即 MP:H(null)、H(A)和 H(H(null)+H(D))。
Plasma Cash 中的取款操做在流程上跟 Plasma MVP 大致相同,都要從提交取款申請開始,經歷爭議期以後才能完成。因爲 Plasma Cash 中採用的數據結構不一樣,在取款時須要提交的 token 全部權證實不一樣,所以當爭議發生時須要提交的爭議證實也不一樣。
在向 Plasma 合約提交關於某個 token 的取款申請時,須要提供關於這個 token 最近的兩次交易證實。例如,在上圖中,假如 G 想要取走 token #2 到主鏈,那麼他須要提交關於 F => G 以及 E => F 的 Merkle Proof。
取款者在提交了取款申請以後一樣須要支付必定的保證金,並等待一段時間的爭議期。在這期間若是有其它節點提交了有效的爭議證實,那麼取款者不但沒法完成取款操做,也會損失所有或部分的保證金。
目前 Plasma Cash 支持三種爭議證實,分別應對三種不一樣的攻擊場景(具體會在後文分析):
在這一節將討論已有的 3 種攻擊場景以及如何構造爭議分別應對這些攻擊[6]。在這裏假設 Plasma Cash 中存在不可信的 operator 接收全部的交易並構造區塊。
以下圖(來源[7])所示,假設攻擊者 Alice 向 Bob 發送了一個 token A,且 Bob 已經驗證了 A 的交易歷史沒有問題,交易在區塊 N+X 獲得確認。在這以後,Alice 當即提交取款申請,企圖將 token A 取回主鏈,並提交 A 在區塊 N 以及以前的交易證實。爲了應對這種狀況,Bob 必須及時發現 Alice 的取款行爲,而且在爭議期結束前提交在區塊 N+X 中 token A 被 Alice 發送給 Bob 的證實。這裏須要注意的是,若是 Bob 在區塊 N+Y 將 token A 發送給 Charlie 的交易是不能被當作爭議證實的,只有最接近被爭議的交易的下一個交易證實有效。
雙花攻擊須要 operator 配合,將含有已經被花費的 token 的交易打包入下一個區塊中。以下圖所示(來源[7]),攻擊者 Alice 和 Charlie 是同謀,Alice 向 Bob 發送一個 token A 在區塊 N+X 被確認,以後 Alice 又將 token A 發送給 Charlie,並在區塊 N+Y 被確認。這時在主鏈看來,Bob 和 Charlie 都是 token A 的合法擁有者。接下來,Charlie 當即提交取款申請,企圖取走 token A。Bob 爲了防止本身的 token 被盜,能夠在爭議期內提交在區塊 N+X 被確認的交易,代表本身在 Charlie 以前已經擁有了 token A。
這種攻擊須要聯合比較多的同謀者。以下圖所示,Alice 在區塊 N 擁有 token A。Bob 聯合 operator、Charlie 以及 Dylan 企圖盜走 Alice 的 token。首先,operator 僞造 Alice 將 token A 發送給 Bob 的交易,並在區塊 N+X 獲得確認,以後 Bob 將 token 發送給 Charlie,在區塊 N+Y 確認。一樣地,Charlie 接着將 token 發送給 Dylan,在區塊 N+Z 確認。這是,Dylan 提出取款申請,企圖取走 token A。Dylan 用於取款申請的兩個交易證實 Charlie => Dylan 和 Bob => Charlie 都是合法的,但 token A 的交易歷史中有一部分是僞造的。Alice 爲了證實本身是 token A 的最新合法擁有者,能夠提出爭議,要求 Dylan 提供 Alice => Bob 的交易證實,同時 Alice 須要提交一部分保證金(不然任何人均可以隨便提出爭議)。Dylan 必須在必定的時間內提供合法的交易證實,不然取款失效。
Talk is cheap, show me your code.
目前已經有許多機構和公司已經實現了 Plasma Cash,但實現的語言和細節有所不一樣:
本篇介紹了 Plasma 框架下的基於 NFT 的項目 Plasma Cash。Plasma Cash 給每一個新轉移的 token 分配一個惟一的 token ID,而且用稀疏梅克爾樹存儲交易,使得用戶能夠只關注跟本身的 token 有關的動態,而不須要關注其它 token。Plasma Cash 能夠被看做 Plasma 逐漸邁向成熟的一步,已經有不少公司使用 Plasma Cash 搭建本身的平臺和應用,例如 Loomnetwork 公司搭建了本身的 Plasma Cash 子鏈而且編寫了 SDK 支撐開發者在上面開發新的應用。然而 Plasma Cash 自己仍然存在較多的問題,例如 token 沒法被分隔合併、須要提交的證實過長等。在接下來的文章中還會繼續跟進 Plasma 最新的進展。
本文的做者是蓋蓋,他的微信公衆號: chainlab
深刻淺出區塊鏈 - 系統學習區塊鏈,打造最好的區塊鏈技術博客。