# Move语言和MoveVM虚拟机
## 1. Move语言
### 1.1 What is Move
Move语言是Libra项目推出的智能合约语言，由rust编写而成，和传统的智能合约语言类似，Move语言主要用来编写Libra交易的执行逻辑
### 1.2 Why Move
Libra旨在建立一个简单的全球货币和金融基础设施，基于此，Move语言和其他智能合约对资产的描述和处理有很大不同。

现实世界中的资产数字化过程中面临着两方面的困难——`稀缺性`和`权限控制`。而现有的平台，如以太坊、比特币等也同样面临着几个问题：

* 资产的不正规表示（Indirect representation of assets）
* 自定义资产稀缺性描述，在区块链编程语言中得不到良好的支持（Scarcity is not extensible）
* 权限控制功能深植于语言之中，难以自定义（Access control is not flexible）


比如Solidity中发布Token，其中的Balance多数是用Integer表示，表意性太差；其次，由于Token自己颁发，几乎所有的内容都需要自己在合约中写出来，由合约所有者维护的，包括其本质的问题：稀缺性和权限控制。一旦出现问题，那么对于这个 Token 而言将是灾难性的。

区块链本身操作的是资产（Asset），所有的资产应该是一类共有的逻辑，应该作为一种基本的资源向开发者提供而不是作为一种可供选择的资源。

因此我们认为在区块链的世界中，基础的资产类型应当是开发者认为的底层，而不是业务逻辑。支撑区块链平台的语言要比以前的编程语言在基础上多了一层对于基础类型的封装 — `对资产类型的保护`。

这也是Move的设计目标：
* 资产是一等公民（First-class assets）
* 灵活性（Flexibility）
* 安全性（Safety）
* 可验证性（Verifiability）

从语义上将资产（Asset）作为其支持的一部分，而不是由用户自定义其基础（稀缺性、权限控制）的实现逻辑。用户只需要自定义自己需要实现的部分即可，如：转账逻辑、退款逻辑等等

### 1.3 特点
#### 1.3.1 两大类型
Move把所有的变量或者实例分成两种：
* Unrestricted Value: 诸如u64或钱包地址等等的变量信息，可以被正常的复制和转移
* Resource: 即之前所说的资产(Assert),不能被复制，只能被转移，并且只能被转移一次，且不能被隐式丢弃

#### 1.3.2 两个程序模型
Move把代码分成两类：
* Module：类似智能合约，可以定义内容的转移，销毁，发布等业务逻辑
* Transaction script：交易指令

比如，Alice 向 Bob 转 100 Libra，这个操作就是 Transaction script，而 100 Libra 和转移过程中要经历怎样的逻辑则是 Modules 的职责了

Transaction script 具有 all or nothing 的特性，即要么都成功，要么都失败，不会存在一种中间状态

#### 1.3.3 两个基本模块
libra内置了move脚本的很多基础模块，比如地址，hash，签名等，其中有两个重要的基本模块：
* LibraAccount 账户基本模块
* LibraCoin coin基本模块

### 1.4 语法
```
1. 基本操作
move：资源或变量的转移
copy：变量的复制

2. 类型
 // kind
 R resource
 V value

 // 基本类型   
 Address,   
 U64, 
 Bool,   
 ByteArray,   
 String,

 // 引用
 &t     类型t不可改变的引用
 &mut t 类型t可变的引用
	
3. 内建函数
 "create_account"
 "release"
 "freeze"  //'&mut t -> &t' coerce a mutable reference to an immutable reference
 "get_txn_gas_unit_price" 
 "get_txn_max_gas_units" 
 "get_txn_public_key" 
 "get_txn_sender" 
 "get_txn_sequence_number"
 "get_gas_remaining"     
 "get_height" 
 "emit_event" 
	
4. &引用
 &x x的不可变引用
 &e.f 结构体e的成员f的引用
    balance_value = LibraCoin.value(&move(account).balance);
    且account需要是&类型“account: &R#Self.T”
 *e  解引用

5. module操作
 //也是资源操作，仅在定义了资源t的module中使用
 move_to_sender<n>(e) 将类型为n的资源e发布到发送方地址
 move_from<n>(e)      移除地址e下的资源n
 borrow_global<n>(e)  生成一个不可更改的引用，指向地址e下的资源n
 exists<n>(e)         地址e下后是否存在资源n
```

### 1.5 示例
[eToken.mvir](resource/eToken.mvir)

### 1.6 现状
>In the longer term, Move must be capable of encoding the rich variety of assets and corresponding business logic that make up a financial infrastructure.
– Move: A Language With Programmable Resources

当前版本的move语言还不成熟，支持的功能相对比较简单，包括语法和测试都还有改进的地方

## 2. Move虚拟机
### 2.1 交易生命周期
![transaction flow](resource/transaction flow.jpg)

MoveVM不仅完成Move脚本的解析执行，还支持交易的验证

### 2.2 language目录结构
```
├── README.md          # This README
├── benchmarks         # Benchmarks for the Move language VM and surrounding code
├── bytecode_verifier  # The bytecode verifier
├── e2e_tests          # Infrastructure and tests for the end-to-end flow
├── functional_tests   # Testing framework for the Move language
├── compiler           # The IR to Move bytecode compiler
├── stdlib             # Core Move modules and transaction scripts
├── test.sh            # Script for running all the language tests
└── vm
    ├── cost_synthesis # Cost synthesis for bytecode instructions
    ├── src            # Bytecode language definitions, serializer, and deserializer
    ├── tests          # VM tests
    ├── vm_genesis     # The genesis state creation, and blockchain genesis writeset
    └── vm_runtime     # The bytecode interpreter
```

### 2.3 compiler工具
compiler将move语言脚本编译成字节码，同时对脚本语法做简单的校验。高级的语义检查由bytecode verifier完成。
```
CompiledProgram: {
Modules: [
CompiledModule: {
Module Handles: [
    0x0.Capability,]
Struct Handles: [
    resource Owner@0x0.Capability,
    resource T@0x0.Capability,]
Function Handles: [
    0x0.Capability.publish(): (),
    0x0.Capability.grant_owner_capability(): (),
    0x0.Capability.grant_minter_capability(Address, &resource Owner@0x0.Capability): (),
    0x0.Capability.grant_blacklisted_capability(Address, &resource Owner@0x0.Capability): (),
    0x0.Capability.borrow_owner_capability(): (&resource Owner@0x0.Capability),
    0x0.Capability.borrow_capability(): (&resource T@0x0.Capability),
    0x0.Capability.is_minter(&resource T@0x0.Capability): (Bool),
    0x0.Capability.is_not_blacklisted(&resource T@0x0.Capability): (Bool),
    0x0.Capability.require_minter(&resource T@0x0.Capability): (),
    0x0.Capability.require_not_blacklisted(&resource T@0x0.Capability): (),]
Struct Definitions: [
    {resource Owner@0x0.Capability},
    {resource T@0x0.Capability
        resource T@0x0.Capability.blacklisted: Bool
        resource T@0x0.Capability.minter: Bool},]
Field Definitions: [
    resource T@0x0.Capability.blacklisted: Bool,
    resource T@0x0.Capability.minter: Bool,]
Function Definitions: [
    public 0x0.Capability.publish(): ()
        locals(1): Address,
        GetTxnSenderAddress
		...
```
跟Move脚本的结构类似，每个Move脚本都会编译成CompiledProgram结构，CompiledProgram主要包含CompiledModule和CompiledScript

### 2.4 测试框架
libra在functional_tests目录中提供了简单的move语言脚本测试框架，开发者可在目录下编写自己的脚本，使用框架编译测试。
测试框架使用的mork执行器在本地执行，不会连接测试网络