從比特幣、以太坊、libra的不一樣特色認識move語言

關於比特幣、以太坊、libra,咱們知道他們是不一樣的區塊鏈應用,那麼他們的根本差異在哪裏呢。
其實,單從白皮書的標題,就能夠大概看出三個項目在設計目標上的差別。程序員

  • 比特幣的目標是 —— 可編程貨幣(Programmable Money),因此白皮書標題是 「Bitcoin: A peer-to-peer electronic cash system」。
  • 以太坊的目標是 —— 可編程的去中心化應用(Programmable dApps),在貨幣的基礎上,擴展到更通用的領域。因此白皮書標題是:「Ethereum: a next generation smart contract and decentralized application platform」,黃皮書標題是:「Ethereum: A secure decentralized generalized transaction ledger」。
  • Libra 的設計目標剛好介於兩者中間 —— 可編程資源(Programmable Resources),或者叫可編程資產。

那麼,「可編程貨幣」、「可編程應用」、「可編程資源」,這三者到底有什麼不一樣呢?
既然都是 「可編程 XX」 句式,他們的主要區別就在於兩點:
對什麼編程;
如何編程。
對什麼編程?編程

對什麼編程,是指系統所描述或者抽象的,究竟是現實世界中的什麼東西。安全

比特幣對 「貨幣」 編程

比特幣系統抽象的是 「貨幣」,或者說是 「帳本」 的概念。貨幣能夠用一個數字來描述,也就是某一個帳戶的 「餘額」。用戶能夠經過 「交易」,把一部分錢轉給別人。當比特幣網絡接收到一筆交易的時候,每一個節點都會檢查交易是否合法,好比你花的是否是本身的錢,有沒有足夠的餘額(比特幣不容許透支)。當這些檢查都成功後,節點會作一個簡單的加減計算:在你的帳戶中扣減轉帳的數額,並在對方帳戶中加上一樣的數量。所以,比特幣惟一的功能就是記帳,保證在帳戶彼此轉帳的過程當中,貨幣的總量不會莫名其妙的增長或減小(不考慮挖礦獎勵和黑洞地址等特例)。網絡

以太坊對 「應用」 編程

以太坊系統抽象的是 「應用」,應用的種類一應俱全,好比遊戲、借貸系統、電商系統、交易所等,這些都是應用。理論上講,任何傳統的計算機程序均可以移植到以太坊上。所以,以太坊中記錄的是各類應用的內部數據(即 「合約狀態」),好比一個電商系統的庫存、訂單、結算信息等。這些信息沒法用一個簡單的數字來描述,必須容許用戶定義很是複雜的數據結構,而且容許用戶經過代碼(智能合約),來對這些數據進行任意所需的操做。固然,這些應用也包含了 「貨幣帳本」。事實上,目前在以太坊上應用最普遍的正是此類應用(稱爲 「ERC20 智能合約」)。因爲以太坊把這類應用看做是平臺所能支持的多種應用中的一種,與其餘類型的應用相比,並無什麼特別之處,因此也就沒有針對此類應用提供更多的安全保護,只提供了相似 ERC20 這樣的接口規範。一個在以太坊上新發行的 「貨幣」,其轉帳邏輯的正確性徹底由開發者負責。
在這裏插入圖片描述
在以太坊的存儲結構中,ERC20代幣 的帳本是 「二級對象」,和 ETH 原生代幣餘額存儲在不一樣的地方。例如上圖所示,0x0,0x1 和 0x2 是三個以太坊地址,其中,0x0 和 0x2 是普通帳戶地址(External accounts),而 0x1 是一個合約地址(Contract accounts)。咱們能夠看到,每一個帳戶都存儲了一個 ETH 的餘額,這個數據是頂級對象 (First-Class Object)。在合約地址 0x1 中,還存儲了一個智能合約代碼 MyCoin,它是一個 ERC20 代幣應用。而 MyCoin 這個代幣的整個帳本,都存儲在 0x1 的空間中,怎麼修改都由 0x1 中的合約代碼說了算。數據結構

不管是有意仍是無心,ERC20代幣 很是容易出現安全漏洞。也就是說,在以太坊系統中,原生代幣 ETH 和用戶發行的代幣並不享有一樣的安全級別。app

Libra 對 「資產」 編程

那麼,可否不那麼走極端,試圖去抽象一些比簡單數字更復雜的資產類型,而又不追求一應俱全的 「通用性」 呢?這正是 Libra 的出發點。Libra 能夠定義相似一籃子貨幣、金融衍生品等比貨幣更復雜的資產類型,以及如何對他們進行操做,這種資產被稱爲 「資源」。Move 經過限制對資源的操做來防止不恰當的修改,從而提升資產的安全性。不管資源的操做邏輯如何,都必須知足兩個約束條件:electron

  • 稀缺性。即資產總量必須受控,不容許用戶隨意複製資源。通俗的說,就是容許銀行印鈔,但不容許用戶用複印機來 「製造」 新錢;
  • 權限控制。簡單的說就是資源的操做必須知足某種預先定義的規則。例如,張三隻能花本身的錢,而不容許花李四的錢。
    在這裏插入圖片描述
    上圖是 Move 的世界狀態,與以太坊不一樣,它把全部資產都看成是 「一等公民」(First-Class Resources),不管是 Libra 的原生代幣,仍是用戶本身發行的資產。任何一個 「幣種」 的餘額,都存儲在用戶地址對應的空間中,對其進行操做受到嚴格的限制。這種被稱爲資源(resource)的對象,在交易中只能被移動,並且只能移動一次,既不能被複制,也不能被消毀。甚至嚴格到在代碼中賦值給一個局部變量,然後面沒有使用它也不容許。

這種資產的存儲方式並不是 Libra 首創,在此前的一些公鏈中已有應用,例如在 Vite 公鏈中,用戶發行的幣種餘額也是頂級對象。不過 Move 能夠支持更爲複雜的資產類型,並對其提供額外的保護,這是 Libra 的主要貢獻。編程語言

編者組: Vite 是本文做者建立的項目。區塊鏈

如何編程?

咱們再來看看三個項目如何經過編程來實現豐富的擴展性。ui

比特幣腳本

在比特幣中,定義了一種 「比特幣腳本」,用來描述花一筆錢的規則。比特幣是基於 UTXO 模型的,只有知足了預先定義的腳本規則,才能花費一筆 UTXO。經過比特幣腳本,能夠實現 「多重簽名」 之類的複雜邏輯。比特幣腳本是一種很是簡單的基於棧的字節碼,不支持循環之類的複雜結構,也不是圖靈完備的。雖然利用它能夠在比特幣網絡上發行新的貨幣(Colored Coins),但它的描述能力很是有限,對開發者也不友好,沒法應用到更復雜的場景中。

以太坊的 Solidity 語言

在以太坊中,定義了一種 Solidity 的編程語言,能夠用來開發 「智能合約」。智能合約代碼能夠編譯成一種基於棧的字節碼 ——EVM Code,在以太坊虛擬機 EVM 中執行。Solidity 是一種高級語言,參考了 C++、Python 和 Javascript 的語法,是一種靜態類型、圖靈完備的語言,支持繼承,容許用戶自定義複雜的類型。Solidity 更像是一種通用的編程語言,理論上能夠用來開發任何類型的程序,它沒有針對貨幣或者資產類型的數據,在語法和語義上作任何限制和保護。好比用它來開發一個新的代幣合約,代幣的餘額一般聲明爲 uint 類型,若是編碼時對餘額增減邏輯的處理不夠當心,就會使餘額變量發生溢出,形成超額鑄幣、隨意增發、下溢增持等嚴重錯誤, 如: BEC 智能合約的漏洞。

Libra 的 Move 語言

再來看 Libra,它定義了一種新的編程語言 Move,這種語言主要面向資產類數據,基於 Libra 所設定的 「頂級資源」 結構,主要設計目標是靈活性、安全性和可驗證性。目前,Move 高級語言的語法設計尚未完成,白皮書只給出了 Move 的中間語言(Move IR)和 Move 字節碼定義。所以咱們沒法評估最終 Move 語言對開發者是否友好,但從 Move IR 的設計中,能夠感覺到它在安全性和可驗證性方面的特色。

Move 語言的設計

下面咱們來簡單介紹一下 Move 的語法。Move 的基本封裝單元是 「模塊」(Module),模塊有點相似於以太坊中的 「智能合約」,或者面嚮對象語言中的 「類」。模塊中能夠定義 「資源」(Resource)和 「過程」(Procedure),相似於類中的 「成員」(Member) 和 「方法」(Method)。

全部部署在 Libra 上的模塊都是全局的,經過相似於 Java 中的包名 + 類名的方式來引用,例如 0x001.MyModule,0x001 是一個 Libra 地址,MyModule 是一個模塊名。模塊中的過程有 public 和 private 兩種可見性,公有過程能夠被其餘模塊調用,私有過程只能被同模塊的過程調用。而模塊中的資源都是私有的,只有經過公有過程才能被其餘模塊訪問。並且,外部模塊或者過程對本模塊資源的修改受到嚴格的限制,惟一容許的操做就是 「移動」(Move),不能隨意對資源賦值。例如,Move 中是不容許出現一個相似於 MyCoin.setBalance() 這樣的接口,讓其餘用戶有機會隨意修改某個幣種餘額的。

除了受限的資源類型,Move 模塊中也容許定義非受限的成員,被稱爲非受限類型(Unrestricted Type),包括原生類型(boolean、uint6四、address、bytes)和非資源類的結構體(struct)。這些非受限類型就沒有那麼嚴格的訪問限制,能夠用來描述與資產無關的其餘應用類數據。從這個角度來講,Move 語言理論上應該具備和 Solidity 一樣的描述能力,但因爲實際的去中心化應用中,總會涉及到資產類的數據,而任何引用了資源類型的結構體也都是受限的,可以真正脫離 Move 語言嚴格限制的機會並很少。因此在實際使用 Move 語言開發的時候,程序員必定會有一種戴着鐐銬跳舞的感受,代碼出現編譯時和運行時失敗的可能也更大。

通俗的說,用 Move 寫代碼不會讓你感受 「很爽」,這就是安全性和可驗證性的代價。想一想你用 C 語言本身控制內存的分配和釋放時,雖然有一種 「我是上帝」 的感受,但也會時刻憂慮緩衝區溢出、內存泄露等潛在風險;而用 Java 語言開發,雖然你再也不可以隨心所欲的控制內存,但也不用擔憂這些內存安全性問題了。自由仍是安全,每每是不兼得的。

在一個 Libra 的交易(Transaction)中,也能夠嵌入一段 Move 代碼,被稱爲交易腳本(Transaction Script)。這段代碼不屬於任何模塊,是一次性執行的,不能再被其餘代碼調用。腳本中能夠包含多個過程,經過 main 過程做爲入口來執行,在其中也能夠調用其餘模塊中的過程。這個設計有點相似比特幣,而和以太坊徹底不一樣。在以太坊中,一個交易自己是不能包含一段可執行代碼的,只能部署新合約或者調用一個已部署的合約。我不太喜歡 Libra 的這個設計,因爲任何 Move 代碼都必須通過字節碼驗證器(Bytecode Verifier)的嚴格檢查才能發佈到鏈上,這種一次性代碼的邊際成本遠遠高於可複用的模塊,會拖慢交易被確認的速度,下降系統的吞吐量。交易腳本並非必須的,大部分現實場景均可以經過模塊來覆蓋,並且,它的存在還增長了 Libra 錢包的開發和使用難度,有機會的話我會向 Libra 的開發團隊提議取消這一設計。

本文內容首發於深刻淺出區塊鏈技術博客,點擊解讀 Libra Move:一種可編程資源語言看一下白皮書中的示例代碼片斷,直觀感覺Move 語言,進一步瞭解move虛擬機等。

深刻淺出區塊鏈技術博客,帶你瞭解move語言,走進libra的世界。

相關文章
相關標籤/搜索
本站公眾號
   歡迎關注本站公眾號,獲取更多信息