深入研究 Move - Facebook 的 Libra 區塊鏈程式語言

接下來,我們將詳細考慮 Move 語言的主要特徵,以及它與另一種已經流行的智能合約語言 Solidity(在以太坊平台上)的主要區別是什麼。 該材料基於對可用的在線 26 頁白皮書的研究。

介紹

Move是一種可執行字節碼語言,用於執行使用者交易和智慧合約。 請注意兩點:

  1. Move是一種可以直接在Move虛擬機上執行的字節碼語言,而Solidity(以太坊的智能合約語言)是一種高級語言,在EVM(以太坊虛擬機)上執行之前先編譯成字節碼。
  2. Move 不僅可以用於實現智能合約,還可以用於自定義交易(稍後會詳細介紹),而 Solidity 是一種僅限智能合約的語言。


翻譯由 INDEX Protocol 專案團隊進行。 我們已經翻譯了 描述 Libra 專案的大型材料,現在是時候更詳細地了解 Move 語言了。 與 Habrauser 聯合進行翻譯 酷秀

Move 的一個關鍵功能是能夠使用基於線性邏輯的語意定義自訂資源類型:資源永遠無法被複製或隱含刪除,只能移動。 從功能上來說,這與 Rust 語言的功能類似。 Rust 中的值一次只能指派給一個名稱。 將值指派給不同的名稱會使其在先前的名稱下無法使用。

深入研究 Move - Facebook 的 Libra 區塊鏈程式語言

例如,以下代碼片段將引發錯誤: 使用移動值“x”。 這是因為 Rust 中沒有垃圾收集。 當變量超出範圍時,它們引用的內存也會被釋放。 簡單地說,數據只能有一個“所有者”。 在這個例子中 x 是原始所有者,然後 y 成為新的所有者。 在這裡閱讀有關此行為的更多信息.

開放系統中數字資產的表示

實物資產有兩個難以數字化的特性:

  • 稀有 (稀缺,原本是稀缺的)。 必須控制系統中資產(排放)的數量。 必須禁止複制現有資產,創建新資產是一項特權操作。
  • 訪問控制... 系統參與者必須能夠使用訪問控制策略來保護資產。

這兩個特性對於物理資產來說是很自然的,如果我們想將它們視為資產,就必須為數字對象實現。 例如,一種稀有金屬自然存在短缺,只有您可以使用它(例如,將其握在手中)並且您可以出售或花費它。

為了說明我們是如何得出這兩個屬性的,讓我們從以下句子開始:

建議 #1:沒有稀缺性和訪問控制的最簡單規則

深入研究 Move - Facebook 的 Libra 區塊鏈程式語言

  • G [K]: = n 表示對可通過密鑰訪問的數字的更新 К 在區塊鏈的全局狀態下,具有新的意義 n.
  • 交易⟨Alice, 100⟩ 意味著將 Alice 的賬戶餘額設置為 100。

上述解決方案有幾個主要問題:

  • 愛麗絲可以通過簡單地發送無限數量的硬幣 交易⟨愛麗絲,100⟩。
  • Alice 發送給 Bob 的硬幣是無用的,因為 Bob 可以使用相同的技術向自己發送無限數量的硬幣。

建議#2:考慮赤字

深入研究 Move - Facebook 的 Libra 區塊鏈程式語言

現在我們正在監控情況,以便硬幣數量 Ka 至少是平等的 n 轉讓交易前。 但是,雖然這解決了稀缺性問題,但沒有關於誰可以發送 Alice 的幣的信息(目前,任何人都可以這樣做,主要是不要違反限制數量的規則)。

提案#3:結合稀缺性和訪問控制

深入研究 Move - Facebook 的 Libra 區塊鏈程式語言

我們用數字簽名機制解決了這個問題 驗證簽名 在檢查餘額之前,這意味著 Alice 使用她的私鑰來簽署交易並確認她是她的硬幣的所有者。

區塊鏈編程語言

現有的區塊鏈語言面臨以下問題(都在Move中解決了(注: 不幸的是,這篇文章的作者在他的比較中只對以太坊有吸引力,因此僅在這種情況下才值得考慮。 例如,以下大部分內容也在 EOS 中得到解決。)):

資產的間接代表。 資產使用整數進行編碼,但整數與資產不同。 事實上,沒有代表比特幣/以太幣/<任何硬幣>的類型或值! 這使得編寫使用資源的程式變得困難且容易出錯。 諸如將資產傳遞給流程或從流程傳遞資產或將資產儲存在結構中之類的模式需要語言的特殊支援。

赤字不可擴大... 語言只是一種稀缺資產。 此外,防止稀缺性的方法直接嵌入到語言本身的語義中。 開發者如果要創建自定義資產,必須自己仔細控制資源的各個方面。 這些正是以太坊智能合約的問題。

用戶發行他們的資產 ERC-20 代幣,使用整數來確定價值和總供應量。 每當創建新代幣時,智能合約代碼必須獨立驗證是否符合排放規則。 此外,在某些情況下,資產的間接列報會導致嚴重錯誤——重複、雙重支出甚至資產完全損失。

缺乏靈活的訪問控制... 當前使用的唯一訪問控制策略是使用非對稱加密的簽名方案。 與稀缺保護一樣,訪問控制策略深深嵌入語言的語義中。 但是如何擴展語言以允許程序員定義自己的訪問控制策略通常是一項非常棘手的任務。

在以太坊上也是如此,其中智慧合約不具備用於存取控制的本機加密支援。 開發人員必須手動設定存取控制,例如使用 onlyOwner 修飾符。

儘管我是以太坊的忠實粉絲,但我認為出於安全目的,資產屬性應該由該語言原生支援。 特別是,將以太幣轉移到智慧合約涉及動態調度,這引入了一種新的錯誤,稱為重入漏洞。 這裡的動態調度意味著程式碼的執行邏輯將在執行時間(動態)而不是編譯時(靜態)決定。

因此,在 Solidity 中,當合約 A 呼叫合約 B 中的函數時,合約 B 可能會運行合約 A 開發者不想要的程式碼,這可能會導致 再入漏洞 (在帳戶餘額實際扣除前,合約A意外充當合約B提款)。

Move 語言設計基礎知識

一階資源

在較高的層次上,Move 語言中模塊/資源/過程之間的交互與 OOP 語言中類/對象和方法之間的關係非常相似。
移動模塊類似於其他區塊鏈中的智能合約。 該模塊聲明了定義創建、銷毀和更新聲明資源的規則的資源類型和過程。 但所有這些都只是約定俗成(“行話”)在移動中。 稍後我們將說明這一點。

靈活性

Move 透過腳本編寫為 Libra 增加了靈活性。 Libra 中的每筆交易都包含一個腳本,它本質上是交易的核心流程。 該腳本可以執行一個指定的操作(例如,向指定的收件者清單付款),也可以重複使用其他資源 - 例如,透過呼叫指定一般邏輯的過程。 這就是 Move 事務腳本提供更大靈活性的原因。 腳本可以使用一次性行為和重複行為,而以太坊只能執行可重複腳本(在智能合約方法上呼叫一種方法)。 之所以稱為“可重用”,是因為智能合約的功能可以被多次執行。 (筆記: 這裡的要點非常微妙。 一方面,比特幣中也存在偽字節碼形式的交易腳本。 另一方面,據我了解,Move 實際上將這種語言擴展至成熟的智能合約語言的水平).

安全

Move可執行格式是字節碼,一方面,字節碼是比組譯語言高級的語言,但比原始碼低階。 使用字節碼驗證器在運行時(鏈上)檢查字節碼的資源、類型和記憶體安全性,然後由解釋器執行。 這種方式可以讓Move提供原始碼的安全性,但無需編譯過程,也無需在系統中加入編譯器。 讓 Move 成為一種字節碼語言是一個非常好的解決方案。 它不需要像 Solidity 那樣從原始碼編譯,也無需擔心編譯器基礎架構可能發生的故障或攻擊。

核查

我們的目標是盡可能簡單地執行檢查,因為所有這些都是在鏈上完成的(注意: 在線,在每筆交易的執行過程中,因此任何延遲都會導致整個網絡的速度變慢),但是,最初語言設計已準備好使用鏈下靜態驗證工具。 雖然這是更可取的,但目前驗證工具(作為單獨的工具包)的開發已被推遲到未來,並且現在僅支援運行時(鏈上)的動態驗證。

模塊化

移動模塊提供數據抽象和本地化資源的關鍵操作。 模塊提供的封裝與 Move 類型系統提供的保護相結合,確保模塊類型上設置的屬性不會被模塊外的代碼破壞。 這是一個經過深思熟慮的抽象設計,這意味著合約中的數據只能在合約範圍內更改,而不能在外部更改。

深入研究 Move - Facebook 的 Libra 區塊鏈程式語言

移動概覽

事務腳本示例表明,模塊外部的程序員的惡意或粗心行為不會危及模塊資源的安全性。 接下來,我們將查看如何使用模塊、資源和過程來對 Libra 區塊鏈進行編程的示例。

點對點支付

深入研究 Move - Facebook 的 Libra 區塊鏈程式語言

金額中指定的硬幣數量將從發送者的餘額轉移到接收者。
這裡有一些新內容(以紅色突出顯示):

  • 0x0: 存放模塊的賬號地址
  • 貨幣: 模塊名稱
  • 硬幣: 資源類型
  • 程序返回的幣值是一個類型為 0x0.Currency.Coin 的資源值
  • 移動 (): 值不能再次使用
  • 複製(): 值可以稍後使用

解析代碼:第一步,發送方調用一個名為 撤回發件人 來自存儲在的模塊 0x0.貨幣。 第二步,發送方將資金轉移給接收方,將幣資源值移入模組的儲值流程 0x0.貨幣.

以下是檢查將拒絕的程式碼錯誤的三個範例:
通過更改調用來複製資金 移動(硬幣)複製(硬幣)。 資源只能移動。 嘗試複製一定數量的資源(例如,透過調用 複製(硬幣) 在上面的示例中)將在檢查字節碼時導致錯誤。

通過指定重新使用資金 移動(硬幣) 兩次 。 新增一行 0x0.Currency.deposit(複製(some_other_payee),移動(硬幣)) 例如,上面將允許發送者「花費」硬幣兩次 - 第一次是與收款人,第二次是與收款人 其他收款人。 這是一種不良行為,對於有形資產來說是不可能發生的。 幸運的是,Move 會拒絕這個計畫。

因拒絕而造成資金損失 移動(硬幣)。 如果您不移動資源(例如,刪除包含 移動(硬幣)),會拋出字節碼驗證錯誤。 這可以保護 Move 程式設計師免受意外或惡意的資金損失。

貨幣模組

深入研究 Move - Facebook 的 Libra 區塊鏈程式語言

每個帳戶可以包含0個或多個模組(顯示為矩形)和一個或多個資源值(顯示為圓柱體)。 例如,帳戶位於 0x0 包含模組 0x0.貨幣 以及資源類型的值 0x0.貨幣.硬幣。 帳戶地址 0x1 有兩個資源和一個模組; 帳戶地址 0x2 有兩個模組和一個資源值。

一些時刻:

  • 事務腳本是原子性的-要嘛完全執行,要嘛根本不執行。
  • 模組是一段長期存在的程式碼,可以全域存取。
  • 全域狀態被建構為哈希表,其中鍵是帳戶位址
  • 帳戶只能包含一個給定類型的資源值,且不能包含多個具有給定名稱的模組(帳戶位於 0x0 不能包含額外的資源 0x0.貨幣.硬幣 或另一個名為 貨幣)
  • 聲明的模組的位址是類型的一部分(0x0.貨幣.硬幣 и 0x1.貨幣.硬幣 是不同的類型,不能互換使用)
  • 程式設計師可以透過定義其自訂資源在一個帳戶中儲存此類資源的多個實例 - (資源 TwoCoins {c1:0x0.Currency.Coin,c2:0x0.Currency.Coin})
  • 您可以透過名稱引用資源而不會發生衝突,例如,您可以使用以下方式引用兩個資源 兩幣.c1 и 兩幣.c2.

幣種資源公告

深入研究 Move - Facebook 的 Libra 區塊鏈程式語言
模組命名為 貨幣 和一個名為的資源類型 硬幣

一些時刻:

  • 硬幣 是一個具有一個類型字段的結構 u64 (64 位元無符號整數)
  • 僅模組程式 貨幣 可以建立或銷毀類型的值 硬幣.
  • 其他模組和腳本只能透過模組提供的公共過程寫入或引用值欄位。

出售存款

深入研究 Move - Facebook 的 Libra 區塊鏈程式語言

此過程接受資源 硬幣 作為輸入並將其與資源結合 硬幣儲存在收件者的帳戶中:

  1. 銷毀輸入資源Coin並記錄其價值。
  2. 接收儲存在接收者帳戶中的唯一硬幣資源的連結。
  3. 透過呼叫過程時參數中傳遞的值來更改硬幣數量的值。

一些時刻:

  • 拆包,借用全球 - 內建程式
  • 打開包裝 這是刪除 T 類型資源的唯一方法。該過程將資源作為輸入,銷毀它,並傳回與資源欄位關聯的值。
  • 借全球 接受一個地址作為輸入並返回對該地址發布(擁有)的 T 的唯一實例的引用
  • 硬幣 這是資源的連結 硬幣

實施withdraw_from_sender

深入研究 Move - Facebook 的 Libra 區塊鏈程式語言

這個程式:

  1. 獲取獨特資源的鏈接 硬幣,連結到寄件者的帳戶
  2. 降低資源的價值 硬幣 透過連結支付指定金額
  3. 建立並返回新資源 硬幣 更新後的餘額。

一些時刻:

  • 押金 任何人都可能造成,但是 撤回發件人 只能存取呼叫帳戶的硬幣
  • 取得Txn發送者地址 如同 訊息發送者 堅固性
  • 拒絕除非 如同 要求 在堅固性中。 如果此檢查失敗,交易將停止並回滾所有變更。
  • 它也是一個創建 T 類型新資源的內建過程。
  • 打開包裝, 只能在描述資源的模組內部調用 T

結論

我們研究了 Move 語言的主要特徵,將其與以太坊進行了比較,並熟悉了腳本的基本語法。 最後,我強烈建議您查看 原始白皮書。 它包含許多有關程式語言設計原理的詳細信息,以及許多有用的連結。

來源: www.habr.com

添加評論