This is a summary of the technical paper describing the Move language features released by Facebook’s Libra blockchain.
With the well-known issues that current blockchain languages like Solidity pose to the ecosystem, a need for a new language which is safe and flexible has been imperative. Move programming language includes these as the main features for their implementation. As mentioned in the paper, any language that is managing digital assets, either creation, transfer or destruction, has to enforce two main properties:
- Scarcity — In terms of blockchain technology, this is nothing but, avoiding double-spending attacks and also the creation of assets be restricted.
- Access Control — Maintain ownership information and privileges on the digital assets according to the ownership.
Move imposes these properties by including a type system for all resources in the system. And resources are automatically enclosed with access control privileges.
Comparison to existing languages
There are some major differences with existing blockchain languages that make Move a viable language for future implementations.
- No type system enforced by default for digital assets. Ex: Bitcoin/Ether.
- A single scarce asset is represented in the whole language like Ether. Any custom assets like ERC20 tokens, need to be checked for safety properties specified by the programmer building the tokens.
- Access control policies are also embedded in the language semantics. No easy way to extend this to custom assets.
- Specifically with Bitcoin — Cannot define custom data types or procedures. Bitcoin script is not Turing complete.
Design goals considered
- First-class resources — In Move, any custom asset can be declared as a resource type, making it safe and access controlled by default. Similar to smart contracts in Ethereum, Move has modules, which are code blocks containing resources, other types and procedures. A strong level of data abstraction is enforced by way of these two main components. Resources are transparent within modules and are opaque to invocations external to the modules. An important characteristic of a resource is — a resource can never be copied or implicitly discarded, only moved between storage location. Below is an example module declaration:
- Flexibility — Each Libra transaction will include a transaction script. Transaction scripts are used to make calls and invoke procedures in a module. It is a single main procedure that can contain customizable transactions and arbitrary code. A single script can invoke multiple procedures. Until now, the design goals make Move look very similar to object-oriented programming languages. This can be attributed to an identical relationship between modules/resources/procedures -> classes/objects/methods.
- Safety — To enforce safety in this language three main components have to be investigated — types, resources and memory. In general two approaches seemed to be common, either compile-time checking or runtime checking at the assembly level. With Move, a new approach has evolved which is a median between the above two approaches, i.e., typed bytecode which is at a higher level than assembly and lower-level than source language. A Bytecode Verifier, checks for safety properties on-chain before the modules are published. Once verified, Bytecode Interpreter executes the code. This is very similar to the process used with JVM (Java Virtual Machine) and CLR (Common Language Runtime).
- Verifiability — Even though Move enables on-chain verification of all the safety properties. This is not ideal for a highly utilized blockchain. Hence, off-chain static verification tools are also supported by Move which will reduce the complexity of on-chain verification. Under this assumption, there are three design decisions considered: No dynamic dispatch (avoid complex call graph construction and call site can be statically determined), Limited mutability (Usage of reference types similar to C++, which allows at most one mutable reference at a point), Modularity (modules can be isolated for functional verification).
Move is a stack-based language. It works similar to all the stack-based languages by pushing and popping as operations are performed. According to the execution model, each account (256-bit address) can have zero or more modules and one or more resource types. Accounts can have at most one resource of a particular type. If needed custom resource type containing multiple resource instances of the same type could be created.
Any variable declared as a resource will be associated with some built-in restrictions. Resources can only be moved and cannot be copied. They can only be created or destroyed within the modules that they are declared in. Once a resource is used up, it becomes available for second use later — this is a major factor to avoid double spending. Resources must be moved exactly once — this helps any dangling resources that have been forgotten by a developer to be recognized during verification.
Modules have some restrictions in place as well. Not to be left out !! Any module can operate on the resources that are referenced within. They can only write or reference values from other modules but, cannot create or destroy the resources. Specifically, they can only perform “move” operation on the other modules resources.
The language also comes with a lot of built-in functions that would allow to get a reference to the values of resources or destroy resources. Built-in’s can only be used on the resources declared in the current module. Hence, if a developer forgets to declare a procedure to reference the value of a resource using built-in then, that resource will be unavailable to view or change.
Components of Move language
Here, I would like to mention the components of the language.
- Types — Supports primitive types like boolean, address (256-bit), unsigned integer (64-bit) and fixed size byte arrays.
- Struct — Two types: kind(resource) and unrestricted(general structures).
- Procedures — Methods that can be public or internal. By default, module dependency is acyclic, which avoids the re-entrancy attacks.
- Bytecode Verifier — The critical component which checks for safety properties before modules get published. All Move programs have to pass through the verifier before getting deployed on the network. There are multiple phases in the process of verification: control graph construction, stack balance checking (ensuring the size of the stack is not modified after all the operations), type checking, kind or resource checking, reference checking and linking with the global state (checking declarations match their usage).
- Bytecode Interpreter — After verification is done, the programs are passed through an interpreter for execution. This flow is very similar to JVM and CLR as mentioned before and traditional programmers can relate to this process. Execution of programs is metered similar to Ethereum using “gas” parameter. This will warrant any infinite loop executions.
- Move Virtual Machine — The process of VM is similar to any other blockchain. This has been covered in detail as in another technical paper as mentioned. But to sum it up, blocks contain multiple transactions and each transaction is executed to create a transaction effect. The transaction effect is used to generate an updated global state. This creates a separation between effects and state transitions.
The language, in general, is designed to support parallel execution.
Multiple future works have been mentioned in the paper. Here are the highlights:
- Using Move to implement accounts, Libra coin, Libra reserve management, Validation management, transaction fee management, cold wallets, etc.,
- Additional object-oriented programming language features like polymorphism, collections and events, etc.,
- A source language for Move.
- Logical specification for the language and automated formal verification tools.
- Third party module publishing support other than Libra users (this would pave way for extensive use cases).
There are a lot of questions still left out for me even after reading the paper. For example, I am not sure yet how the modules are acyclic or how storing global storage as a tree helps better than storing like a graph. I am going to keep a lookout for the next version of the paper.
Overall, looking at the current specification of Move, I feel blockchain is no more in a nascent stage. It’s at the stage of young adolescents. Also, I do understand how much Libra has learnt from the experience of current blockchains. Their proposal is very futuristic and I do hope with the right use case they Libra coin might be a regular utility currency in no time.