Smart contract programming languages dissected
By: Inal Kardanov
Tags: Smart Contracts, Programming Languages, Decentralization, Blockchain, Programming

In this article, Inal Kardanov, Waves developer advocate discusses the advantages and drawbacks of major smart contract languages.

Comparing programming languages is hardly a rewarding task, although quite common among developers. I believe this approach is totally wrong as any language could be good for a certain range of tasks and totally useless for others.

In this article, I’ll try to find out what tasks Waves’ smart contract language Ride is good (and even excellent) for. For this purpose, I’ll make comparisons with Solidity, which is, arguably, the most popular smart contract language, as well as less common but still popular Rust and C++.

Very often — especially in the Russian-language developer community — you can come across language-shaming directed against PHP or JavaScript and programmers using those languages. Unlike that approach, this article aims to highlight major differences between languages rather than insist on the superiority of any language.

Solidity

Solidity is an object-oriented Turing complete programming language for writing smart contracts. It’s the most common smart contract language, and its usage goes beyond the Ethereum blockchain. Solidity has been influenced by JavaScript, C++, Python and, partially, PowerShell (according to Wikipedia).

Solidity’s syntax was designed to be similar to ECMAScript (JavaScript) to simplify mastering the language by developers. However, at this point, Solidity’s similarities to JavaScript are few and far between.

Let’s consider the simplest code example taken from https://solidity-tour.certik.io and examine its patterns:

The keyword contract replaces class to describe a contract. Within a contract, we have a variable and several functions. Let’s examine them more closely.

Functions are divided into public and private. Public functions can be called by any user or another smart contract. Public functions can also have additional restrictions, public view and public pure . public view applies to functions that can read a contract’s state but cannot update it, while public pure functions can neither read nor update the state.

All arguments transferred to functions have a type, while the language also requires returnable type description, as strict typization should help avoid errors.

Solidity’s built-in types are oriented at blockchain operation and specifics, which enables a quick understanding of the context. The above example contains the function payBill , which uses the type address . This language primitive makes work with accounts especially convenient. For instance, to execute a transfer, it’s sufficient to call the method `transfer` from the object billsAddress .

Solidity also enables setting `modifiers`, which most often are restrictions for functions.

The language also contains convenient data types — struct , mapping and arrays. If necessary, direct execution of code for the Ethereum Virtual Machine (EVM) is possible:

Still, in some instances, the language’s flexibility causes problems as a developer gets a chance of “shooting himself in the leg.”

To start writing in Solidity, you don’t need substantial experience. However, to write a sufficiently complicated application and avoid critical errors, the significant experience is required. Meanwhile, some of the features are puzzling. For instance, the presence of (potentially infinite) `while` raises many eyebrows.

Since the purpose of this article is language comparison, let’s look at the `Tic-Tac-Toe` implementation in different languages.

If you want to learn more about Solidity, I quite recommend that you start with this interactive course https://solidity-tour.certik.io/

Ride

Ride is a compilable, static-typed functional programming language with lazy execution, aimed at building decentralized apps. The language was created to help developers write code without errors.

Ride is a non-Turing complete language. It has no cycles (in traditional sense) or reentrancy and imposes many restrictions that make apps simple for understanding and debugging. Meanwhile, using Ride and all capacities of the Waves blockchain, you can build Turing-complete systems.

The language has been substantially influenced by Scala and F#. Ride isn’t exactly similar to these languages, but starting to write in Ride will be easier for developers knowing them. At the same time, the language is simple for developers in all other languages and an initial study of Ride and its tools normally takes about an hour.

Let’s consider some code in Ride:

Ride is much simpler than Solidity and has a smaller standard library. It contains standard primitives, such as List , and those typical of blockchain, such as Address or Transaction .

Instead of the modifiers public or private , the language uses annotations like @Callable , available to all blockchain users, and @Verifier , executed for smart accounts. Functions without modifiers are considered private and are available only within a specific file. Unlike Solidity, Ride currently has no libraries or options for linking functions from another file to a script.

Ride doesn’t allow writing VM code and doesn’t even have cycles in the traditional sense, just syntactic sugar as FOLD).

The features of Ride’s syntax include the Pattern-matching mechanism, shown in the above example. Another feature is the types of function results. Unlike Solidity, there is no need for a returnable type as the compiler will determine the type based on code.

Ride’s simplicity provides more substantial security guarantees than Solidity, but also has negative consequences, such as the impossibility of calling one contract from another and the absence of libraries. Composability in Ride is based on the general state, which can be read by all contracts. A contract doesn’t have a private state, which can be very convenient on many occasions.

If you want to learn more about Ride, I suggest a course on Coursera or the book “Mastering Web3.”

Rust

Recently, the use of general-purpose languages for smart contract writing has become more and more popular. Most commonly, Rust (Solana, Polkadot) and/or C/C++ (EOS) have been used. These platforms chose not to create their own blockchain language but implement a library that includes all necessary functions and primitives. For instance, Solana suggests using `solana_sdk`, in which PublicKey , ProgramResult etc. are described.

Within the scope of this article, I won’t discuss the language’s syntax. Instead, I suggest examining the implementation of `state` for a token in Solana SDK:

https://github.com/solana-labs/solana-program-library/blob/master/token/program/src/state.rs

The use of Rust or any other language has its advantages, as a developer with such skills can find work beyond smart contract creation, while entry barriers are extremely low for those familiar with that language. Still, writing a regular program in Rust may have nothing to do with smart contract development as restrictions imposed by blockchain runtime.

Conclusion

All languages have their advantages and drawbacks, which are summarized in this table.

If you’re just beginning writing smart contracts, the first suggestion is examining Solidity and Ride, which have blockchain-specific primitives and can help understand blockchain and its operation principles more quickly.