We’re in the process of determining the initial Spacemesh roadmap for the next few years (as I wrote about the past two weeks). One of the most important parts of this is the VM design. It’s the first and most important major milestone on the roadmap post-genesis. For now Spacemesh is launching with an extremely barebones VM which only runs a limited number of hardcoded smart contracts including multisig and vesting vaults. In other words, users won’t be able to write or deploy their own smart contracts at genesis. It’s frustrating to launch without a full VM, since so much of what makes Ethereum and platforms like it interesting is the full-featured, Turing complete VM. It’s also the thing that initially drew me to Ethereum and it’s the part of Ethereum I was most excited to work on. But there’s at least one benefit to adding the VM later: it gives us more time to consider possible designs and get this right. And get it right we must, since this is one of the most important decisions we’ll make with respect to the design of the Spacemesh protocol.
Thing #1: EVM Who? 😕
Our original plan was to design a custom VM from scratch. We called this SVM for the Spacemesh virtual machine. We worked on it for a few years, and while we ultimately shelved the project entirely, it’s worth explaining and understanding why we originally decided to build our own VM. In many ways it’s the same ideas that motivated the creation of the Ewasm project that I worked on in Ethereum before joining Spacemesh.
In short, EVM is a strange VM. There are many things about it that I and other engineers would like to change. A number of suboptimal design choices were made at the time when it was designed. To be clear, at the time, better options like Wasm and RISC-V didn’t exist yet so the EVM designers were working ex nihilo. All things considered, it’s a pretty remarkable creation! But it has warts. These include the fact that all words are 256 bits (32 bytes) long, which cannot run natively on modern CPUs. As a result even simple arithmetic, e.g., adding 1+2, translates into multiple instructions via BigInt libraries. Storage units are similarly arranged in 256 bit slots so that storing a small value is very wasteful. And then there’s the inclusion of strange “opcodes” like KECCAK256, and arbitrary jumps which makes analysis hard.
In this respect EVM is warty in the way that Javascript is warty (as programmers like to say, what can you expect of a language created in ten days?). In fact, EVM and Javascript have more than a little bit in common. For one thing, Solidity (the primary language used to write programs that target EVM) and Javascript have similar syntax, which isn’t an accident: Solidity’s creators wanted it to feel familiar to Web2 developers. For another, in spite of their wartiness, both have rapidly emerged as global standards (we’ll come back to this in a moment).
On the face of it WebAssembly (a.k.a. Wasm) seems like a much better choice for a variety of reasons. For one thing, it’s extraordinarily well designed. It was created and is maintained by a committee of experts from companies such as Apple, Amazon, Google and Mozilla. It’s also very efficient, running at around 80% the speed of native code, much much faster than EVM. It’s natively portable across platforms and runtimes, and runs on the backend as well as it does in the browser. And it plugs directly into existing, popular toolchains including web/Javascript applications and the LLVM toolchain, which means that existing, mature tools including compilers, testing frameworks, static analyzers, profilers, debuggers, etc. should all work more or less out of the box. It also means that developers can write Wasm code in whatever language they’re already familiar with. Popular choices that target Wasm include C/C++, Rust, and Typescript.
If the goal is to give the programmer an ergonomic, comfortable experience with the languages and tools that they’re familiar with, and to avoid the hassles and pitfalls of Solidity and EVM, and to use the best, most mature tools available, then Wasm seems like the obvious choice.
Thing #2: Oh, That EVM 🙄
Why, then, did we decide to drop SVM? And while similar Wasm-based VMs have landed in other blockchain ecosystems including Polkadot, NEAR, and Cosmos, why was Ewasm also dropped from the Ethereum roadmap after years of effort?
There are complicated, idiosyncratic, situational reasons for each of these decisions. Ewasm was dropped from the Ethereum roadmap not on its merits (or lack thereof) but rather because the Ethereum roadmap changed, from one focused on execution to one where execution is largely outsourced to rollups. In this vision, rather than having a maximally functional base layer VM, the base layer VM should instead be simple and complex programmability should be pushed to higher layers inside rollups. Indeed, at least one popular rollup is using Wasm under the hood. And as for Spacemesh, we simply didn’t do a good job of integrating the work that was done on SVM into go-spacemesh early enough in the R&D process to include it in the genesis release. The project grew complicated enough without SVM, since we’re already innovating in the consensus mechanism, the proof system, the account structure, and other places.
However, there’s something bigger going on here. The projects I spoke to that chose a non-EVM-compatible route years ago told me that they mostly regretted that decision. And they’ve almost universally backtracked by introducing EVM compatibility at layer two, such as NEAR’s Aurora and Polkadot’s Moonbeam, one of the most popular parachains on Polkadot. The market has spoken: it turns out that developers and users alike really just want EVM compatibility.
To be clear, it wasn’t at all clear three or four years ago that EVM would win the blockchain VM war. There was (and still is) a great deal of momentum behind Wasm, in particular, as a better alternative for the reasons described above. A few years ago a number of tools began to emerge, such as transpilers and IR layers like Yul, that promised to make it possible to compile familiar Solidity code directly to Wasm so that developers could continue to run their existing code on a Wasm backend, and could continue to develop smart contracts using familiar languages and tools. But, fast forward a few years, and frankly none of those things ever really took off, while the developer experience around Solidity and EVM has gotten better and better. Old stalwarts like ethers.js and the OpenZeppelin library and new tools like hardhat and foundry have made writing, testing, deploying, and upgrading Solidity code to EVM faster, easier, safer, and more fun than ever.
I can’t tell you how many times I’ve had conversations over the years with brilliant developers and researchers who told me that they dislike EVM and are working on something better. None of them has ever actually written and deployed production Solidity code onto an EVM compatible chain, but they dislike EVM because of some obscure, technical reason (such as the 256 bit word size, as described above, or the fact that it allows reentrancy, despite the fact that this is trivially easy to prevent in code). What they fail to understand is the powerful network effects of Solidity, EVM, and the other Ethereum tooling. This extends far beyond the programming experience! Everyday users are familiar with wallets like Metamask and tools like WalletConnect. They by and large understand gas and mnemonics and the division between EOA and smart contracts and nonces and the other weird details that come along with the Ethereum ecosystem. Exchanges can trivially add support for ERC-20 tokens, and they can be easily tested and composed with other, existing DeFi money legos. Auditors know how to audit this code. These effects in total are extraordinarily powerful and you deviate from them at your peril. Changing even a small piece of this complex puzzle can cause untold downstream incompatibilities and issues. I’ve heard horror stories from developers who tried making a tiny tweak to Ethereum’s transaction format on their chain to, say, introduce an additional field or change the signature format slightly, and ended up regretting it and paying the price for years as it caused headaches up and down the stack for users and developers alike.
To bring things down to earth imagine, if you will, that you’re a car designer, and you come up with a better design for an automobile. It’ll look better, be safer and easier and more comfortable to drive, cost less, consume less energy, etc. It just requires changing the shape of the car slightly, making the wheels a little further apart. That might sound like a trivial change and well worth the cost! But it means the car won’t be compatible with lots of existing infrastructure. It won’t fit in parking lots or gas stations or car washes or auto body shops, or on ferries, or even on narrow roads. It might have trouble parking on the side of the road. It might cause issues in tunnels and on bridges. The examples go on and on. In practice there’s zero chance the change would work because the cost of upgrading the global infrastructure and retraining everyone else is simply too great, even for a small change. This is what happens when something becomes an entrenched, global standard.
EVM isn’t perfect. It’s warty and weird and suboptimal. But it’s won the VM war and it’s time to face that fact. Betting against EVM has historically always been a mistake, now more than ever.
Thing #3: Just Kidding 🤷♂️
What can I say, I’m bad at making up my mind! For the past couple of years I mostly felt the way I just described: that without a very strong reason to deviate, EVM is the obvious choice. We’ve been relitigating this question recently, both in light of the current state of Ethereum and the blockchain VM landscape and also in light of Spacemesh’s imminent launch and our hopes and desires for its future and I’d like to share where we’re at.
As mentioned above we decided to launch Spacemesh initially without a full-featured VM, but the VM is the first major upgrade we want to make post-genesis. A few months ago we hatched a tentative plan to develop an “enshrined rollup,” which we believe would give us the best of both worlds. Like a rollup it would run at layer two, be extremely scalable, and significantly reduce the burden on L1 miners so they don’t have to validate every transaction and every state transition. However, unlike a L2 rollup it would be decentralized from day one (because many L1 validators and miners would act as a network of distributed sequencers) and share accounts and keys with the base layer. This would make it very easy to interact with the L2 VM, to move assets and funds back and forth, etc. And while we’d start with a single, enshrined rollup, it has the added benefit that we could introduce alternative L2s in the future.
As we’ve dug deeper into this plan and begun to fill in some of the details, however, we’ve found a few outstanding issues. One is that it’s not totally clear how L2 transactions would pay L1 gas. (Unlike a traditional rollup, we envision a system where L2 transactions also live on L1 and pay gas to L1 miners for being mined into a block.) Another is that EVM compatibility will likely be tough since we’ve already made a few decisions at L1 that would be tricky to reconcile such as using Ed25519 for signatures and a different account structure and nonce type. Would we expect every L2 transaction to necessarily be tied to an L1 account, and further, would we require that every L2 transaction also provide two signatures, one for EVM at L2 and one for the Spacemesh base layer? These are just a couple of early examples of unsolved challenges with this design.
In trying to plot a path forward, I find myself brought back to the original and most important question: What do we want Spacemesh to be when it grows up? What sort of users and use cases do we want and expect it to serve? In particular, EVM compatibility makes a lot of sense if you’re targeting existing Ethereum users and Ethereum applications, things like DAOs and NFTs and DeFi. There are legitimate use cases and applications on Ethereum and I wouldn’t mind if any of them make their way to Spacemesh, but I also wouldn’t mind if the 99% of speculative garbage on Ethereum doesn’t make its way to Spacemesh. It’s not clear that we should encourage that behavior by making it as easy as possible to move existing applications over, including the crappy ones. Yes, Ethereum users and developers are used to a particular stack of technologies and tools, and yes, Ethereum is by far the most important smart contract platform today, but in the grand scheme of things the number of Ethereum users in the world today is tiny relative to the total number of developers, and the number of Ethereum applications and transactions, and the amount of time people spend using them, relative to all the applications in the world is so tiny it barely registers.
In other words, while we are doubtless standing on the shoulders of cypherpunk giants including Bitcoin and Ethereum, I think it’s also very important that Spacemesh be bold and confident enough to step out from Ethereum’s shadow and chart its own, unique course. At the end of the day it’s a question of novelty and confidence. If the only thing that differentiates you from Ethereum is, say, higher throughput, then hewing as close as possible to Ethereum and EVM makes a ton of sense. If on the other hand you think you have a superior, novel design (which we do) that will attract many novel users and use cases (which it will), then this argument is less salient. Charting our own course might slow us down a little at the beginning but it could pay huge dividends down the line—and Spacemesh is nothing if not a long-term project!
At the same time we must recognize that designing and building a safe, performant, Turing complete VM is very hard, much harder than it might sound (take it from someone who worked on exactly this for years). If we do choose to go this route—and many projects including Solana, Stacks, Tezos, Nervos, and the Move ecosystem projects have before us—it means taking on not only this challenge but also the challenge of educating potential users about new languages and tools. We may not have the resources to do that at this stage.
Anyway, as we finally approach launch, I’m feeling more excited and more confident about Spacemesh’s bright future, and I think we should seriously consider boldly charting our own course in the VM landscape, too. I hope to share more details soon about what that might look like. One thing is clear to me today: the people who matter the most are the end users, i.e., the people using applications built and running on Spacemesh, and they just want to use the best apps in the world. They don’t care at the end of the day whether the applications they’re using are running on EVM or Wasm or something else entirely, just as they don’t care whether the apps they use today run on Firebase or AWS or Oracle. That’s our north star. We should make it as easy as possible for the best developers in the world to build the best applications in the world that millions of people will enjoy using. If we get this even half right, Spacemesh will do just fine.