Gavin's Web3 Utopia: The Evolution of Polkadot Smart Contracts and Virtual Machines

CN
2 days ago

Gavin's vision is to build a brand new decentralized internet world.

Author: Guozi

Polkadot, an old blockchain project, is known to those in the Web3 industry, even if they haven't used their products.

Recently, Polkadot has been in the news frequently, with the new JAM architecture being eye-catching. The founder's demonstration of the DOOM game has shown us a new landscape for Polkadot, which has generated significant research interest in me. Polkadot is quite large, with major components like the Polkadot chain, the Substrate development framework, and relay/parachains, etc. Due to space and attention constraints, I will focus on the execution layer, specifically the virtual machine, to provide an overview of its development history, current status, and related information.

Prologue

When Ethereum was first established, Gavin Wood joined the Ethereum project development out of interest. At that time, Ethereum was just a preliminary framework, and Gavin's involvement allowed Ethereum to take shape on a technical level. Let's take a look at his contributions to Ethereum:

(1) Completed Ethereum's PoC-1 (Proof of Concept-1); (2) Almost single-handedly completed the earliest C++ version client of Ethereum; (3) Wrote the Ethereum technical specification Yellow Book; (4) Invented the high-level language Solidity for smart contract development.

For those interested in this history, you can read "Point to Everything: Ethereum and the Future of Digital Finance," and Gavin Wood's legendary story can also be easily found online, so I won't elaborate further here.

Let's focus on Solidity and EVM. First, let's look at a simple Solidity counter example code:

pragma solidity ^0.8.3;      
contract Counter {      
    uint public count;      
    function get() public view returns (uint) {        
        return count;      
    }      
    function inc() public {        
        count += 1;      
    }      
    function dec() public {        
        count -= 1;      
    }  
}

This example declares a state variable count, which you can think of as a single slot in a database. You can query and change it through the code managing the database. In this example, the contract defines functions inc, dec, and get that can be used to modify or retrieve the variable's value.

After being compiled by the Solidity compiler solc, a segment of bytecode can be obtained (see below). After being deployed to the node via JSON-RPC, the execution layer will first reach a consensus, and upon confirmation, it will be executed by the EVM.

6080604052348015600e575f80fd5b506101d98061001c5f395ff3fe608060405234801561000f575f80fd5b506004361061004a575f3560e01c806306661abd1461004e578063371303c01461006c5780636d4ce63c14610076578563b3bcfa8214610094575b5f80fd5b61005661009e565b60405161006391906100f7565b60405180910390f35b6100746100a3565b005b61007e6100bd565b60405161008b91906100f7565b60405180910390f35b61009c6100c5565b005b5f5481565b60015f808282546100b4919061013d565b92505081905550565b5f8054905090565b60015f808282546100d69190610170565b92505081905550565b5f819050919050565b6100f1816100df565b82525050565b5f60208201905061010a5f8301846100e8565b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f610147826100df565b9150610152836100df565b925082820190508082111561016a57610169610110565b5b92915050565b5f61017a826100df565b9150610185836100df565b925082820390508181111561019d5761019c610110565b5b9291505056fea26469706673582212207b7edaa91dc37b9d0c1ea9627c0d65eb34996a5e3791fb8c6a42ddf0571ca98164736f6c634300081a0033

Let's see what it looks like in assembly instructions:

PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH1 0xE JUMPI PUSH0 DUP1 REVERT JUMPDEST POP PUSH2 0x1D9 DUP1 PUSH2 0x1C PUSH0 CODECOPY PUSH0 RETURN INVALID PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH2 0xF JUMPI PUSH0 DUP1 REVERT JUMPDEST POP PUSH1 0x4 CALLDATASIZE LT PUSH2 0x4A JUMPI PUSH0 CALLDATALOAD PUSH1 0xE0 SHR DUP1 PUSH4 0x6661ABD EQ PUSH2 0x4E JUMPI DUP1 PUSH4 0x371303C0 EQ PUSH2 0x6C JUMPI DUP1 PUSH4 0x6D4CE63C EQ PUSH2 0x76 JUMPI DUP1 PUSH4 0xB3BCFA82 EQ PUSH2 0x94 JUMPI JUMPDEST PUSH0 DUP1 REVERT JUMPDEST PUSH2 0x56 PUSH2 0x9E JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x63 SWAP2 SWAP1 PUSH2 0xF7 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST PUSH2 0x74 PUSH2 0xA3 JUMP JUMPDEST STOP JUMPDEST PUSH2 0x7E PUSH2 0xBD JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x8B SWAP2 SWAP1 PUSH2 0xF7 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST PUSH2 0x9C PUSH2 0xC5 JUMP JUMPDEST STOP JUMPDEST PUSH0 SLOAD DUP2 JUMP JUMPDEST PUSH1 0x1 PUSH0 DUP1 DUP3 DUP3 SLOAD PUSH2 0xB4 SWAP2 SWAP1 PUSH2 0x13D JUMP JUMPDEST SWAP3 POP POP DUP2 SWAP1 SSTORE POP JUMP JUMPDEST PUSH0 DUP1 SLOAD SWAP1 POP SWAP1 JUMP JUMPDEST PUSH1 0x1 PUSH0 DUP1 DUP3 DUP3 SLOAD PUSH2 0xD6 SWAP2 SWAP1 PUSH2 0x170 JUMP JUMPDEST SWAP3 POP POP DUP2 SWAP1 SSTORE POP JUMP JUMPDEST PUSH0 DUP2 SWAP1 POP SWAP2 SWAP1 POP JUMP JUMPDEST PUSH2 0xF1 DUP2 PUSH2 0xDF JUMP JUMPDEST DUP3 MSTORE POP POP JUMP JUMPDEST PUSH0 PUSH1 0x20 DUP3 ADD SWAP1 POP PUSH2 0x10A PUSH0 DUP4 ADD DUP5 PUSH2 0xE8 JUMP JUMPDEST SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH32 0x4E487B7100000000000000000000000000000000000000000000000000000000 PUSH0 MSTORE PUSH1 0x11 PUSH1 0x4 MSTORE PUSH1 0x24 PUSH0 REVERT JUMPDEST PUSH0 PUSH2 0x147 DUP3 PUSH2 0xDF JUMP JUMPDEST SWAP2 POP PUSH2 0x152 DUP4 PUSH2 0xDF JUMP JUMPDEST SWAP3 POP DUP3 DUP3 ADD SWAP1 POP DUP1 DUP3 GT ISZERO PUSH2 0x16A JUMPI PUSH2 0x169 PUSH2 0x110 JUMP JUMPDEST JUMPDEST SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH0 PUSH2 0x17A DUP3 PUSH2 0xDF JUMP JUMPDEST SWAP2 POP PUSH2 0x185 DUP4 PUSH2 0xDF JUMP JUMPDEST SWAP3 POP DUP3 DUP3 SUB SWAP1 POP DUP2 DUP2 GT ISZERO PUSH2 0x19D JUMPI PUSH2 0x19C PUSH2 0x110 JUMP JUMPDEST JUMPDEST SWAP3 SWAP2 POP POP JUMP INVALID LOG2 PUSH5 0x6970667358 0x22 SLT KECCAK256 PUSH28 0x7EDAA91DC37B9D0C1EA9627C0D65EB34996A5E3791FB8C6A42DDF057 SHR 0xA9 DUP2 PUSH5 0x736F6C6343 STOP ADDMOD BYTE STOP CALLER

From the perspective of compilation principles, its execution flow is: `Solidity source code -> Lexical analyzer -> Syntax analyzer -> Compilation -> Bytecode -> Virtual machine -> Interpretation execution`

Yes, it is just a new programming language in the computer industry, but at that time, it was indeed a remarkable achievement. Two years after joining the Ethereum development project, Ethereum was launched as scheduled. **If Vitalik Buterin created the form of Ethereum, then Gavin gave Ethereum its soul.** Bitcoin is an electronic payment system, while Ethereum made blockchain **programmable**, proclaiming itself as the "world computer," and everything changed.

Web 3.0
-------

While serving as a co-founder and CTO of Ethereum, Gavin published an article on April 17, 2014, on the blog **"Insights into a Modern World"**: DApps: What Web 3.0 Looks Like\[1\], comprehensively explaining what he envisioned the Web 3.0 era should look like and the four components that constitute Web 3.0. The concept of Web 3.0 is widely recognized and influential, and Gavin not only has strong technical skills but also possesses a forward-looking vision. For the history and debates surrounding Web 3.0, you can refer to the Wikipedia entry on Web3\[2\]. American entrepreneur and venture capitalist Nova Spivack\[3\] suggested extending the definition of Web 3.0 to reflect the current major technological trends moving towards a new stage of maturity, excerpted as follows:

• **Ubiquitous Connectivity**: The proliferation and development of broadband networks, internet access via mobile communication devices (e.g., tablets).

• **Network Computing**: The business model of "SaaS services," interoperability of web services, distributed computing, network computing, and utility computing (also known as "cloud computing").

• **Open Technology**: Open APIs and protocols, open data formats, open-source software platforms, and open data (such as Creative Commons, open data licenses).

• **Open Identity**: OpenID, open reputation, cross-domain identity, and personal data.

• **Intelligent Networks**: Semantic web technologies such as Resource Description Framework, Web Ontology Language, SWRL, SPARQL semantic application platforms, and declarative data storage.

• **Distributed Databases**: World Wide Database (implemented by semantic web technologies).

• **Intelligent Applications**: Natural language processing, machine learning, machine reasoning, autonomous agents.

![](https://static.aicoinstorge.com/attachment/article/20250529/174850502950941.jpg)

At the end of 2015, Gavin left Ethereum.

He then founded **Parity Technologies** and developed an Ethereum client written in Rust, which once monopolized the Ethereum wallet market. The reasons for Gavin's departure from Ethereum remain unknown, but what we do know is that **Gavin's vision is to build a brand new decentralized internet world**.

"Ethereum was an experiment for me, a prototype to validate whether the technology was feasible. Ethereum was also my school; I graduated from this school, and I wanted to try to do more things."

"In fact, what I learned the most from Ethereum was not technology (at that time, Ethereum had a dedicated research team responsible for managing technical details), but social experience. Governance is one of them. I believe that enhancing the system's capabilities through governance in blockchain systems is very important; this will be a revolutionary new feature, and this is precisely what Ethereum did not do."

During his time at Ethereum, Gavin was always a practitioner, but he was not a designer, and he was also constantly brewing new innovations.

The Birth of Polkadot
-----

A year later, Gavin solved a long-standing puzzle and released the Polkadot white paper in 2016. Many people know that Polkadot aims not only to solve scalability issues but also to enable independent blockchains to communicate with each other, which is the cross-chain problem. However, when it comes to Polkadot, what you should know most is: sharding, **because sharding taken to the extreme is essentially Polkadot**.


The original words of Polkadot founder Gavin better illustrate this point:

"The design logic of Polkadot does not directly relate to interoperability. We were waiting for Ethereum's sharding technology to be released. But sharding has never been realized, and it has not been launched yet. Therefore, I wanted to create a more scalable 'Ethereum' myself, pushing the concept of sharding to a relatively extreme level, simply by not using sharding at all and designing independent chains instead. With this design, different chains can exchange information with each other, and the final result is achieved through a shared consensus layer for communication."

So how should we understand sharding? First, let's discuss the dilemma of Ethereum. Historically, Ethereum's performance issues have been its Achilles' heel. In 2018, the popular CryptoKitties caused severe congestion, which not only increased transaction times but also kept transaction fees high. It is akin to a bank with only one window and a slow processing speed; when more people come to handle business, long queues form while they wait.

However, if the bank had several windows operating simultaneously, there might not be a need to queue. This is the basic logic of sharding: **dividing the nodes of the entire network into different areas called shards, allowing a large number of transactions to be processed by different shards**, significantly improving efficiency.

Thus, in Polkadot, each shard carries core logic and allows them to transact in parallel and exchange data, ultimately linking multiple blockchains into one network.

The emergence of Polkadot is not only comparable to but even surpasses the vision of Ethereum 2.0. What is more creative is that **within Polkadot, there can be many Ethereums**. It is no longer a simple blockchain; "Polkadot aims to provide a truly open and free platform for various social innovations."

This is the ideal of Web3, the ideal of Polkadot, and the ideal of Gavin.

Polkadot 1.0
------------

The Polkadot relay chain itself does not support smart contracts, but its connected parachains\[4\] can freely define state transition rules, thus providing smart contract functionality. The distinction from other ecosystems is that, in the context of Polkadot, parachains and smart contracts exist at different layers of the stack: smart contracts are located above the parachains. Parachains are typically described as layer 1 blockchains — the difference being that they do not have to build their own security and can upgrade and interoperate.

Polkadot provides developers with the flexibility to build smart contracts, supporting both Solidity contracts executed by the EVM (Ethereum Virtual Machine) and Wasm-based contracts using ink!:

### EVM-Compatible Contracts

The Polkadot ecosystem supports the Ethereum Virtual Machine (EVM), thanks to the Frontier\[5\] toolkit. Frontier allows Substrate-based blockchains to natively run Ethereum smart contracts and achieve seamless interaction with the Ethereum ecosystem through Ethereum-compatible API/RPC interfaces. Contracts can be written in languages such as Solidity or Vyper, and the EVM is widely standardized across blockchains, including Polkadot parachains like Astar, Moonbeam, and Acala. This compatibility allows contracts to be deployed across multiple networks with minimal modifications, benefiting from a well-established and extensive development ecosystem.

For example, Astar\[6\] is a key smart contract platform on Polkadot, uniquely supporting both EVM and WebAssembly (Wasm) smart contracts through its multi-VM approach. This dual VM support allows developers to choose their preferred programming environment while maintaining full compatibility with Ethereum. The platform's runtime\[7\] is built on Substrate using FRAME, combining key components from the Polkadot-SDK and custom modules for handling its unique features.

![](https://static.aicoinstorge.com/attachment/article/20250529/174850502984174.jpg)

These chains often adopt ready-made contract modules and build upon them with additional innovations. For example: Phala\[8\]: uses contract modules in a trusted execution environment to achieve confidential smart contract execution and interoperability. Aleph Zero\[9\]: uses contract pallets in a zero-knowledge environment. t3rn\[10\]: uses contract modules as building blocks to achieve multi-chain execution of smart contracts. For more information on EVM-compatible parachains like Astar, Moonbeam, and Acala, refer to their official documentation: Parachain Contracts\[11\].

### Wasm (ink!) Contracts:

Polkadot provides the Contracts module\[12\] through the FRAME framework, which uses WebAssembly as the execution environment for contracts. In theory, any language that can be compiled to Wasm can be used to develop smart contracts, but for optimization and convenience, Parity has specifically introduced ink!\[13\].

Before discussing ink!, we first need to clarify what Substrate\[14\] and its contract module (pallet-contracts) are. Substrate is a framework for building blockchains, which can be independent blockchains or blockchains connected to Kusama\[15\] or Polkadot\[16\], known as parachains.

Substrate includes many modules, referred to as pallets in Substrate terminology. Substrate comes with a set of modules that meet many of the requirements typically found in modern blockchains — staking, fungible tokens, non-fungible tokens, governance, etc.

Substrate also includes a module for smart contracts, called the Contracts pallet. If a parachain is developed in Substrate, it can easily add smart contract functionality by including this pallet. This module is simply an execution environment that takes WebAssembly files as input. The smart contracts in this module must be compiled to the WebAssembly (Wasm) target architecture.

How does ink! play a role here? ink! is a programming language, specifically an embedded domain-specific language (eDSL) of the popular Rust programming language. This means you can use all the regular Rust syntax along with some newly added details that make the language suitable for the smart contract world. The contract module receives these ink! contracts and executes them in a secure manner. In short:

Using ink!, you can write smart contracts in Rust for blockchains built with Substrate that include the Contracts pallet.

ink! does not create a new language; it is simply standard Rust with a clear "contract format" and a dedicated `#[ink(...)]` attribute macro. These attribute macros inform ink! what different parts of the Rust smart contract represent and ultimately allow ink! to execute all the magic needed to create Wasm bytecode compatible with the Polkadot SDK. Since ink! smart contracts are compiled to Wasm, they provide high execution speed, platform independence, and enhanced security through sandbox execution.

Let’s look at a simple ink! contract. This contract stores a boolean value in its storage. After the contract is created, it sets the boolean value to `true`. The contract exposes two functions: one for reading the current value of the boolean `(fn get())`, and another for toggling the value to its opposite boolean `(fn flip())`.

#\[ink::contract\]  mod flipper {    #\[ink(storage)\]      pub struct Flipper {          value: bool,     }     impl Flipper {    #\[ink(constructor)\]    pub fn new(init\_value: bool) -> Self {      Self { value: init\_value }     }       #\[ink(message)\]    pub fn flip(&mut self) {      self.value = !self.value;     }    #\[ink(message)\]    pub fn get(&self) -> bool {      self.value     }   }}

It looks similar to the capabilities provided by Solidity, such as Storage storage, Message messages, Errors errors, Events events, etc. For contract developers, this means they can write smart contracts using ink! but can also choose to use other languages: the Solang compiler for Solidity\[17\] and ask! for AssemblyScript\[18\] (as shown below).



import { env, Pack } from "ask-lang";
import { FlipEvent, Flipper } from "./storage";

@contract
export class Contract {
  _data: Pack<Flipper>;

  constructor() {
    this._data = instantiatePack<Flipper>(new Flipper(false));
  }

  get data(): Flipper {
    return this._data.unwrap();
  }

  set data(data: Flipper) {
    this._data = new Pack(data);
  }

  @constructor()
  default(flag: bool): void {
    this.data.flag = flag;
  }

  @message({ mutates: true })
  flip(): void {
    this.data.flag = !this.data.flag;
    let event = new FlipEvent(this.data.flag);
    // @ts-ignore
    env().emitEvent(event);
  }

  @message()
  get(): bool {
    return this.data.flag;
  }
}

Adding a new language is not difficult. You just need a compiler for a language suitable for WebAssembly, and then you can implement the Contracts pallet API.

Currently, this API contains about 15-20 functions that can be used for any functionality that smart contracts might need: storage access, cryptographic functions, environment information (such as block number), access functions for obtaining random numbers or self-terminating contracts, etc. Not all of these need to be implemented in that language — ink! "Hello, World!" only requires six API functions. The following pattern describes this relationship:

Compared to the EVM, there are many advantages to choosing ink! and the Contracts pallet. Here are some of the advantages detailed in this article:

• ink! is just Rust — you can use all the regular Rust tools: clippy, crates.io[19], IDEs, etc.

• Rust is a language that integrates years of language research; it is safe and fast. Additionally, it draws major lessons from older smart contract languages (like Solidity) and incorporates them into the design of ink!. More reasonable default behaviors have been chosen, such as defaulting to private functions or disabling input by default.

• Rust is an amazing language, having been voted the most loved programming language on StackOverflow for seven consecutive years (source[20]).

• If you are a company looking to hire smart contract developers, you can hire from the Rust ecosystem, which is much larger than the niche market of Solidity developers.

• ink! is native to Substrate, using similar primitives, just like the same type system.

• The migration path from contracts to parachains is very clear. Since ink! and Substrate are both Rust, developers can reuse a large portion of code, tests, as well as frontend and client code.

• WebAssembly is an industry standard that is not limited to the blockchain world. It is continuously improved by major companies like Google, Apple, Microsoft, Mozilla, and Facebook.

• WebAssembly expands the range of languages available to smart contract developers, including Rust, C/C++, C#, Typescript, Haxe, Kotlin, etc. This means you can write smart contracts in any language you are familiar with. This design is more forward-looking than tightly coupling language and execution architecture.

For more information on this section, you can read What is Parity's ink!?[21].

Polkadot 2.0 / JAM

On February 28, Gavin Wood publicly demonstrated the DOOM game running on JAM for the first time during the JAM Tour in Shanghai! This is a historic moment for the blockchain industry; JAM transforms the blockchain from merely a network into a powerful supercomputer platform that supports conventional software like DOOM while providing strong computational power and low latency.

Putting other aspects aside, let's focus on the virtual machine. Based on my reading of the PolkaVM-related source code over the past few days, it is indeed real. The key point is that PolkaVM has a Host running the VM, providing export interfaces upwards, and then running the guest version of Doom's RISC-V code on the VM.

The source code is here:

https://github.com/paritytech/polkavm/tree/master/examples/doom

Let’s take a look at several key components of this new smart contract solution:

Revive Pallet

The Revive Pallet[22] provides the functionality to deploy and execute PolkaVM smart contracts at runtime. It is a heavily modified branch of pallet_contracts. These contracts can be written in any language that compiles to RISC-V. Currently, the only officially supported languages are Solidity (via revive[23]) and Rust (see Rust examples in the fixtures directory).

In terms of contract language compatibility with Ethereum: contracts can be written in Solidity and interact with nodes using Ethereum JSON RPC and wallets like MetaMask. At the underlying level, contracts are recompiled from YUL to RISC-V to run them on PolkaVM instead of EVM. To simplify operations, a customized version of the REMIX[24] web frontend can be used to compile contracts to RISC-V and deploy them to the Westend Asset Hub Parachain[25].

Revive

Revive[26] is the umbrella term for the “Solidity to PolkaVM” compiler project, which includes multiple components (such as the YUL frontend and the resolc executable itself). resolc is the name of the single-entry-point frontend binary executable that transparently uses all revive components to generate compiled contract artifacts. Solidity contracts can be compiled into PolkaVM executable RISC-V code, enabling the execution of Solidity contracts on Polkadot.

This requires a compiler. Its working principle is to use the original solc compiler and then recompile its intermediate representation (YUL) output into RISC-V. LLVM[27] is a popular and powerful compiler framework used as the backend for compilers, handling the heavy lifting in optimization and RISC-V code generation. revive is primarily responsible for lowering the generated YUL intermediate representation (IR) from solc to LLVM IR.

This approach provides a good balance between maintaining high levels of Ethereum compatibility, good contract performance, and feasible engineering effort. The benefit of this approach compared to implementing a complete Solidity compiler is that the task is much smaller. By choosing this method, all quirks and oddities of Solidity and its various versions can be supported.

PolkaVM

PolkaVM[28] is a general-purpose user-level virtual machine based on RISC-V. This is the most significant change compared to competing technologies. It uses a new custom virtual machine instead of the EVM to execute contracts. Currently, a PolkaVM interpreter is included in the runtime itself. Future updates will provide a full PolkaVM JIT running within the client.

• By default, it is secure and sandboxed. Code running in the virtual machine should run in a separate process and should not be able to access the host system, even in the case of an attacker with full remote code execution privileges inside the virtual machine.

• Fast execution speed. The runtime performance of code running in the VM should be comparable to that of state-of-the-art WebAssembly VMs, at least within the same order of magnitude.

• Fast compilation speed, ensuring single compilation O(n). Loading new code into the virtual machine should be almost instantaneous.

• Low memory usage. The benchmark memory overhead for each concurrent instance of the virtual machine should not exceed 128KB.

• Small binary files. Programs compiled for this VM should take up as little space as possible.

• No waste of virtual address space. The VM should not pre-allocate GBs of virtual address space for sandbox purposes.

• Complete determinism. Given the same input and the same code, execution should always return exactly the same output.

• Support for high-performance asynchronous gas metering. Gas metering should be cheap, deterministic, and reasonably accurate.

• Very simple. A programmer can write a fully compatible interpreter for this virtual machine in less than a week.

• Versioned operational semantics. Any future changes to observable semantics for client programs will be versioned and explicitly chosen to be added.

• Standardization. There should be a specification that fully describes the client-observable operational semantics of this virtual machine.

• Cross-platform. The VM will run in interpreted mode on unsupported operating systems and platforms.

• Minimal external dependencies. The virtual machine should be largely independent, have fast compilation speeds, and be resilient against supply chain attacks.

• Built-in tools for debugging and performance analysis.

Two fundamental differences from EVM:

Register machine - EVM is a stack machine. This means that function parameters are passed on an unlimited stack. PolkaVM is based on RISC-V, which is a register machine. This means it passes parameters in a limited set of registers. The main benefit of this is that, since these are register machines, it makes the conversion steps to the underlying hardware more efficient. The number of registers has been carefully chosen to be smaller than the notoriously register-scarce x86-64 instruction set. Allowing the NP-hard register allocation problem to be simplified into a simple 1-to-1 mapping is the secret to PolkaVM's fast compilation time.

Reduced word length - EVM uses a 256-bit word length. This means that every arithmetic operation must be performed on these large numbers. This makes any meaningful numerical operation very slow, as it must be converted into many native instructions. PolkaVM uses a 64-bit word length, which is natively supported by the underlying hardware. That is to say, when Solidity contracts are converted via YUL (#Revive), 256-bit arithmetic is still used because YUL is too low-level to automatically convert integer types. However, it is entirely possible to write contracts in different languages and seamlessly call them from Solidity. Imagine a system where business logic is written in Solidity, but the underlying architecture is written in a faster language, similar to Python, where most of the heavy lifting is done by C modules.

Summary

Smart Contract Programming Languages

The number of smart contract languages is increasing year by year. Choosing the first language can be challenging, especially for beginners. The choice mainly depends on the ecosystem you are interested in, although some languages are applicable across multiple platforms. Each language has its own advantages and disadvantages, and this article does not intend to introduce them one by one.

One might ask why there are so many contract languages? I summarize a few possible reasons: 1) Existing languages cannot meet the proprietary features of the chain; 2) Better performance, security, cost; 3) Taste :)

I personally have no bias against contract languages, and the following excerpts from different voices can provide some different insights, whether from the user's perspective or from the perspective of language or VM design.

Why not use Solidity? Solidity is a highly regarded pioneer, but it is constrained by many historical quirks of the EVM. It lacks common features expected by programmers, has a relatively weak type system, and lacks a unified tool ecosystem. In Sway, we let you use a complete set of modern tools to design smart contracts. You will get a fully functional language that includes generics, algebraic types, and trait-based polymorphism. You will also have an integrated, unified, and easy-to-use toolchain that includes code completion LSP servers, formatters, documentation generation, and everything needed to run and deploy contracts, allowing you to easily implement the desired functionality. Our expressive type system allows you to capture semantic errors, we provide good defaults, and conduct extensive static analysis checks (e.g., enforcing checks, effects, interactions). You can use java.lang.Integer.pattern to ensure that safe and correct code is written at compile time.

via https://docs.fuel.network/docs/sway/

Why not use Rust? While Rust is an excellent systems programming language (Sway itself is also written in Rust), it is not suitable for smart contract development. Rust excels because it can achieve zero-cost abstractions and its complex borrow-checking memory model, delivering impressive runtime performance for complex programs without a garbage collector. On the blockchain, execution and deployment costs are scarce resources. Low memory usage and short execution times make complex memory management often too expensive and not worth it, while Rust's borrow checker becomes a burden with no benefits. General-purpose programming languages are usually not suitable for this environment because their design must assume execution in a general computing environment. Sway attempts to bring all the other advantages of Rust, including its modern type system, safety methods, and good defaults, to smart contract developers by providing familiar syntax and features tailored to the specific needs of the blockchain environment.

via https://docs.fuel.network/docs/sway/

Clarity code is interpreted and submitted exactly as written. Solidity and other languages are compiled into bytecode before being submitted to the chain. The dangers of compiling smart contract languages are twofold: first, the compiler adds a layer of complexity. Errors in the compiler can lead to bytecode that differs from expectations, introducing the risk of vulnerabilities. Second, bytecode is not human-readable, making it difficult to verify what the smart contract is actually doing. Ask yourself, would you sign a contract you cannot read? If your answer is no, then what is the difference with smart contracts? With Clarity, what you see is what you get.

via https://docs.stacks.co/concepts/clarity\#clarity-is-interpreted-not-compiled

Virtual Machines and Instruction Sets

From the JVM we know to the heuristic rise of the EVM in the blockchain field, there are dozens of virtual machines that I know of, with different implementations. The core interpreter (Interpreter) is usually one of the most basic execution methods, especially outside of Just-In-Time (JIT) compilation or Ahead-Of-Time (AOT) compilation. The interpreter is still widely used for code execution, responsible for parsing and executing bytecode.

Interpreter Example

Below is a small example demonstrating a very basic interpreter, without considering various optimization mechanisms.

use std::collections::VecDeque;

#[derive(Debug, Clone, Copy)]
enum OpCode {
    Push(i32),
    Add,
    Sub,
    Mul,
    Div,
    Print,
}

struct Interpreter {
    stack: Vec<i32>,
}

impl Interpreter {
    fn new() -> Self {
        Interpreter { stack: Vec::new() }
    }

    fn run(&mut self, bytecode: VecDeque<OpCode>) {
        for op in bytecode {
            match op {
                OpCode::Push(value) => self.stack.push(value),
                OpCode::Add => self.binary_op(|a, b| a + b),
                OpCode::Sub => self.binary_op(|a, b| a - b),
                OpCode::Mul => self.binary_op(|a, b| a * b),
                OpCode::Div => self.binary_op(|a, b| a / b),
                OpCode::Print => {
                    if let Some(value) = self.stack.last() {
                        println!("{}", value);
                    }
                }
            }
        }
    }

    fn binary_op(&mut self, op: fn(i32, i32) -> i32) {
        if self.stack.len() < 2 {
            panic!("Stack underflow!");
        }

        let b = self.stack.pop().unwrap();
        let a = self.stack.pop().unwrap();
        self.stack.push(op(a, b));
    }
}

fn main() {
    let bytecode = VecDeque::from(vec![
        OpCode::Push(10),
        OpCode::Push(20),
        OpCode::Add,
        OpCode::Push(5),
        OpCode::Mul,
        OpCode::Print,
    ]);
    let mut interpreter = Interpreter::new();
    interpreter.run(bytecode);
}

Each instruction consists of an opcode (operation code) and may have parameters. The interpreter uses a stack to store computed data, with only 6 instructions.

Instruction Set Classification

From the interpreter example above, the number and scalability of instructions determine the general direction of a virtual machine. In my analysis, virtual machines can be classified by instruction set, roughly divided into the following 4 categories:

  1. The custom instruction set represented by EVM, which leads to a lot of repetitive work, such as compiler and instruction design… There were already 141 instructions before EIP-3855[29], and new instructions are still being added.

  2. WASM, out of the box, supports multiple languages, but is relatively heavy. This point is also mentioned in the Polkadot documentation. I believe that the advantage of WASM lies in its inherent multi-language support. If a chain simply wants to run a piece of logic, crudely writing state into account storage slots is quite suitable. Rapid development and quick integration, but the downside is that its instructions are not specifically designed for blockchain, making it difficult to support some special capabilities or to trim it down (150+ instructions[30]).

It should also be mentioned here that Solana's SVM executes BPF instructions, which can compile any programming language into a dynamic link library of BPF instructions, although it is relatively less popular compared to WASM.

  1. Based on the RISC-V instruction set, such as PolkaVM and many current zkVM systems: ceno, eigen zkvm, jolt, mozak vm, nexus, o1vm, openvm, powdrVM, risc0, sp1, sphinx, etc. I haven't had the chance to research others, but I can mention that PolkaVM and Nexus zkVM implement a general RISC-V instruction interpreter. Currently, most languages can output RISC-V instructions after being compiled by GCC or LLVM, which opens up perspectives from the language level and lays a foundation for future multi-language support. The basic RV32I instruction set consists of 47 instructions, with optional extensions, which is indeed streamlined compared to the 3000+ instructions of x86.

  2. Interpreted languages, such as Stacks' Clarity (Lisp), AO's Lua, and Mina's TypeScript, etc. So, to summarize, if the left hand represents EVM as a proprietary instruction, and the right hand represents the open WASM, then RISC-V is a relatively balanced choice for secondary development. Firstly, various compilers already support this instruction set, and there are many reference implementations. Secondly, it is easy to design custom instructions based on it.

Additional: Exploring the Future of Multi-Chain Smart Contracts

With the diverse development of the blockchain ecosystem, more and more projects have launched their own smart contract languages (such as Solidity, Move, Cairo, Sway, etc.) to support unique features. While this innovation enriches the tech stack, it also brings new learning costs and compatibility challenges. A core question is gradually emerging: Can mature Solidity contracts be seamlessly deployed on emerging blockchains?

To this end, we have teamed up with several researchers passionate about compiler technology to initiate the Hummanta compiler project. This project aims to break down inter-chain barriers and achieve cross-chain compilation of smart contract languages, supporting the compilation of languages like Solidity, Move, Cairo, Sway, etc., into various virtual machine environments, including: EVM and emerging VMs: PolkaVM, SolanaVM, MoveVM, FuelVM, etc.

Current Progress of the Project

We are advancing this vision from three directions:

  1. Standardization of Syntax and Instruction Sets: Systematically organizing the syntax definitions of various languages and virtual machine instruction sets to lay the foundation for cross-chain compilation.

  2. Compiler Toolchain Development: Building a parser based on LALRPOP[31], utilizing Cranelift[32]/LLVM for code generation, supporting the conversion from multiple languages to multiple target bytecodes.

  3. Integrated Development Experience: Developing the Hummanta CLI tool[33] (similar to Cargo), providing full-process support from compilation to deployment.

免责声明:本文章仅代表作者个人观点,不代表本平台的立场和观点。本文章仅供信息分享,不构成对任何人的任何投资建议。用户与作者之间的任何争议,与本平台无关。如网页中刊载的文章或图片涉及侵权,请提供相关的权利证明和身份证明发送邮件到support@aicoin.com,本平台相关工作人员将会进行核查。

欧易返20%,前100送AiCoin保温杯
链接:https://www.okx.com/zh-hans/join/aicoin20
Ad
Share To
APP

X

Telegram

Facebook

Reddit

CopyLink