Move from the EVM

One of the big themes that I think we’re starting to see shake up for 2024 is the rise of Move as both a VM and a language. This is especially as Solana seeks to adopt Move, and their next step up in programmability (Runtime v2 – great talk here from Breakpoint) is a step towards this future. The other big catalyst is the growth of Sui (which recently hit $200m in TVL), Aptos, and chains that bring a Move VM to other ecosystems (Movement Labs, Lumio by Pontem).

Move was developed by Libra/FB to be their programming language for their payments focused blockchain. However, with things not petering out as they hoped – many jumped ship and started their own startups, including Mysten Labs (Sui), Aptos Labs (Aptos) and others. It has a Rust like syntax, but it’s simpler – and as a result it’s much easier to pick up from Solidity than Rust for the first time.

Why Move? Why another language for devs to learn?

Move is the only other major smart contract programming language outside of the EVM (Solidity, Vyper, etc). This is important because one of the issues with working from an existing programming language like Rust or Javascript – you have to add more boilerplate or add in libraries in order for it to be suited for a blockchain context.

Even though many developers know these languages, the actual usability decreases when you have something that isn’t purpose built for it. While there can be work done that smoothes it out (e.g. packages like Anchor for Solana), I hold the strong belief that a smart contract specific language is important for composability where we deal with more complex interactions.

  1. Global Types System

One of the painpoints with the EVM is that there are no native types. That means if you’re trying to interface from another protocol from your contract, but you don’t have their interface, you’re plain out of luck. One thing you can do is go to Etherscan, copy the interface and then interface with it.

With Move, contracts are called ‘Packages’ – borrowing from Rust terminology here, and when you ‘publish’ (aka deploy) you push up not only the bytecode, but also the metadata associated with the contracts.

As a result, you can specify dependencies as addresses, and pull the information about for use in your program – the following, from the Kuna Labs repo is a good example:

  1. Native Upgradability

One of the great painpoints with the EVM is the lack of upgradability. This has resulted in hacky patterns like transparent proxies, UUPS, etc.

Just like Solana, you can directly upgrade the contract if you have the upgrade key. There are some limitations of course – the public facing API can’t be changed, only new functions can be appended, structs can’t be directly modified.

As usual – the code can be made immutable as well, but by default contracts are upgradable.

  1. Inline Tests

This is probably the aspect that I wish came into Solidity the most, but you can add inline tests to Move. Just as a quick refresher, for more complex systems, in order to test specific components, we’ll often write out mocks or lens contracts to help determine the state of a particular contract. However, inlining these tests allows for more seamless test driven development (TDD).

Here are some tests that are part of the Kai Finance vaults:

  1. Global Storage

One of the key things is the global storage, where instead of using a mapping, user data is stored in an address. This is in part what allows for such good performance, since only the data that you need to access is called (e.g. your token balance), instead of needing to load the entire program data into memory.

These are resources, and have a key or a store ability. The key refers to the fact that is can be stored in this global storage, and the store refers to the fact that it can hold data.

This is why you might see a bunch of addresses that are being invoked when you look at the transaction graph on an explorer – these are references to the global storage.

  1. (Sui specific) Objects

Sui goes one step further with the concept of global storage and introduces the idea of objects. With objects, these have native transferability if it has a store ability.

If I were making an Ownable module, I’d create an object with key, store and transfer the object to my address. To get authentication, I would just add it as a field in a function, since no one else has access to this OwnerCap object – no need to authenticate within the function.

function setFees(_: &OwnerCap, newFee: u64)


Hopefully this post goes a bit further in demystifying Move and some of the ideas explored here. While there are areas that are clunky (e.g. the VScode extension is really bad), Move is surprisingly developed out with robust docs, good design, and a helpful community.

For some good resources:

Move Book

Aptos Move Tutorial

Sui Move Intro

Collect this post to permanently own it.
William logo
Subscribe to William and never miss a post.
  • Loading comments...