Libra教程之:move语言的特点和例子
文章目錄
- move語言的特點
- 資源優(yōu)先
- 靈活性
- 安全性
- 可驗證性
- Move語句初探
- 點對點支付交易腳本
- Currency Module
move語言的特點
Libra的目標是打造一個全球話的金融和貨幣的平臺,從而賦能地球上的幾十億人。那么作為Libra的move語言就需要在安全性和可編程性上面提供大力的支持。
為了實現(xiàn)這樣的目標,move遵從如下四大設(shè)計原則:
資源優(yōu)先
在區(qū)塊鏈中我們需要通過程序來存取數(shù)字資產(chǎn),這個數(shù)字資產(chǎn)和普通程序中的變量(如booleans,integers,strings)有著明顯的區(qū)別。我們需要一個特別的方式來表示區(qū)塊鏈中的數(shù)字資產(chǎn)。
Move語言中的resource就是特別為數(shù)字資產(chǎn)定義的,它有這樣的特點:
resource是不能被拷貝和隱式銷毀的,它只能在不同的用戶之間移動。這個特性是在Move的類型定義中已經(jīng)聲明了的。除了這個特殊的限制,resource和其他普通的資源一樣,可以存儲在數(shù)據(jù)結(jié)構(gòu)中,可以作為參數(shù)傳給過程等。
資源優(yōu)先的概念為程序員寫出安全和有效的代碼提供了非常大的幫助。
Libra coin就是一種resource,因為它將和現(xiàn)實世界的貨幣相對應(yīng),所以它可以被創(chuàng)建,修改,或者銷毀。我們需要做的就是通過modules來控制好操作coin的權(quán)限。
move中的modules有點像以太坊中的智能合約,module聲明了resource類型和過程(業(yè)務(wù)邏輯:如何創(chuàng)建,移動,銷毀coin)。module中的定義的type和過程可以被其他的module進行調(diào)用。
靈活性
move的靈活性體現(xiàn)在可以通過transaction腳本來自由組合各種transaction來實現(xiàn)不同的功能,一個腳本可以調(diào)用多個transaction,
在move中modules/resources/procedures的關(guān)系有點像面向?qū)ο蟪绦蛘Z言中classes/objects/methods的關(guān)系。
安全性
move定義了資源的安全性,類型的安全性和內(nèi)存的安全性,任何違背這些安全性的操作都會被拒絕。
一般來說,有兩種方式來實現(xiàn)這個功能:1.在高級別的語言定義上,通過編譯器來檢查這些異常。 2. 在低級別的虛擬機匯編語言上檢查這些異常。
move是這兩種方式中間的一種方式:Move執(zhí)行的字節(jié)碼比匯編語言要高級一點,但是又比編程語言又低級一點。move的字節(jié)碼提交到鏈上后,會被字節(jié)碼驗證器校驗,然后經(jīng)由字節(jié)碼解釋器執(zhí)行。
可驗證性
最好的驗證方式就是將字節(jié)碼提交到鏈上進行真實的驗證,但這樣很明顯會加重鏈的負擔(dān),影響交易的速度,所以在move中我們盡可能多的在鏈上做輕量級的驗證,而在語言級別做線下的靜態(tài)驗證。
Move語句初探
本節(jié)我們會通過一個例子來詳細的講解Move語言的具體特性。本節(jié)的例子是使用move IR來編寫的,這是一個實驗性的版本,正式的move語言還在編寫中。
點對點支付交易腳本
public main(payee: address, amount: u64) { let coin: 0x0.Currency.Coin = 0x0.Currency.withdraw_from_sender(copy(amount)); 0x0.Currency.deposit(copy(payee), move(coin)); }上面是一段簡單的交易腳本,main方法有兩個輸入,一個是地址,一個是要支付的數(shù)目。
邏輯其實很簡單,從發(fā)送者的賬戶里面減去amount, 然后將它轉(zhuǎn)給接收者。
0x0是module的存儲地址,Currency是module的名字,0x0.Currency.Coin 代表的就是資源了。
在上面的章節(jié)中我們講到了,coin是resource,只能move不能copy,嘗試將move(coin)替換成copy(coin)會報錯。
其他的非resource的資源像是payee和amout可以被move也可以被copy.
如果我們添加這樣一行:
0x0.Currency.deposit(copy(some_other_payee), move(coin))
則coin將會被使用兩次,這在邏輯上是有問題的,在Move語言中,
move(coin)方法在使用一次過后會變得不可用,從而導(dǎo)致第二次move失敗,從而有效的保障了應(yīng)用邏輯。
coin只能也必須移動一次,如果把move(coin)刪除,同樣會的到一個錯誤。這樣做的目的是有效的避免程序員的疏忽導(dǎo)致的應(yīng)用邏輯錯誤。
Currency Module
上面我們定義了一個Currency的module。這里我們講一下Currency是怎么實現(xiàn)的。
Libra有兩種程序,一種是transaction腳本,一種是module,腳本會去調(diào)用module里面的過程來更新全局狀態(tài)。
transaction腳本是一種只能執(zhí)行一次的腳本,執(zhí)行完之后就不能再用了,而module是發(fā)布在全局狀態(tài)里面的長期存在的代碼。
全局狀態(tài)是一個賬戶地址到賬戶的映射,如下圖所示,0x0,0x1,0x2都是賬戶的地址。
每個地址里面可以包含任意個module和資源。例如0x0地址的賬戶包含了一個module:0x0.Currency和一個resource:0x0.Currency.Coin.
知道了賬戶的結(jié)構(gòu)之后,我們看下module是怎么定義資源的:
module Currency { resource Coin { value: u64 } // ... }上面的代碼定義了一個Coin的resource,它有一個value字段,類型是u64。
接下來我們看下存儲這個操作是怎么定義的:
public deposit(payee: address, to_deposit: Coin) { let to_deposit_value: u64 = Unpack<Coin>(move(to_deposit)); let coin_ref: &mut Coin = BorrowGlobal<Coin>(move(payee)); let coin_value_ref: &mut u64 = &mut move(coin_ref).value; let coin_value: u64 = *move(coin_value_ref); *move(coin_value_ref) = move(coin_value) + move(to_deposit_value); }這個過程主要做了這樣幾件事情:
Unpack<T> 是唯一的銷毀T的方式,unpack會銷毀T,然后返回T對應(yīng)的值。
BorrowGlobal<T> 接收一個地址作為參數(shù),然后返回一個指向該地址里的T實例的引用。
同樣的,我們看下withdraw_from_sender 是怎么實現(xiàn)的:
public withdraw_from_sender(amount: u64): Coin { let transaction_sender_address: address = GetTxnSenderAddress(); let coin_ref: &mut Coin = BorrowGlobal<Coin>(move(transaction_sender_address)); let coin_value_ref: &mut u64 = &mut move(coin_ref).value; let coin_value: u64 = *move(coin_value_ref); RejectUnless(copy(coin_value) >= copy(amount)); *move(coin_value_ref) = move(coin_value) - copy(amount); let new_coin: Coin = Pack<Coin>(move(amount)); return move(new_coin); }這個過程做了這樣3件事情:
其中Pack<T>是Unpack<T>的反向操作。用來創(chuàng)建T資源。
更多精彩內(nèi)容且看:
- 區(qū)塊鏈從入門到放棄系列教程-涵蓋密碼學(xué),超級賬本,以太坊,Libra,比特幣等持續(xù)更新
- Spring Boot 2.X系列教程:七天從無到有掌握Spring Boot-持續(xù)更新
- Spring 5.X系列教程:滿足你對Spring5的一切想象-持續(xù)更新
- java程序員從小工到專家成神之路(2020版)-持續(xù)更新中,附詳細文章教程
更多教程請參考 flydean的博客
總結(jié)
以上是生活随笔為你收集整理的Libra教程之:move语言的特点和例子的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: JDK14的新特性
- 下一篇: Scala教程之:面向对象的scala