Ethereum is behind one of the most popular cryptocurrencies - and yet it is much more than that. This means that cryptographic money can be managed completely autonomously thanks to algorithms. But how do the so-called smart contracts work and where is the journey going?
In order to understand the principle of smart contracts in Ethereum, it is necessary to first undertake a brief excursion into the world of programming languages. The common programming languages are basically divided into two groups: interpreted and compiled languages. In the first group, programs are written in a high-level language, which are then executed by an interpreter. Two popular examples of this are Python and JavaScript. Interpreted languages are common in many application domains (such as the web) because you can get started right away. In addition, they are very universal and can be used on different platforms without the need for additional tooling.
On the other hand, there are compiled languages in which a compiler first converts the program text into another language - often binary machine code. This binary code is platform-dependent and is executed directly on a processor. The compiler can (and must) output tailor-made code for the instruction set of the processor, for example for ARM or Intel compatible CPUs. Well-known representatives of this type are C and Rust.
However, the reality is, as always, more complex than these simple categories suggest. For a long time there have been mixed forms, such as Java. The Java compiler does not translate Java code directly into "real" machine code, but into a special intermediate format. This intermediate format in turn is then executed by an interpreter - the Java Virtual Machine - on the specific processor architecture.
The smart contracts in Ethereum work in a similar way. All nodes that validate transactions in Ethereum and mine new currencies contain an instance of the Ethereum Virtual Machine (EVM). In the Yellow Paper, the technical specification of Ethereum, it is precisely defined which instructions the EVM support - and how they are to be executed.
It is an in-house development that has numerous special features:
Interaction with the outside world is not possible: All algorithmic decisions must result from the blockchain and its transactions.
Arithmetic is based on 256-bit values to make it easier to deal with addresses and large amounts of money.
Special operations such as the hash functions are built in directly to increase performance.
A cost function (fuel) is assigned to all instructions, which roughly corresponds to the required execution time and the amount of memory required. The term metering is common in English.
Programming on the EVM
Similar to the Java ecosystem, there are several programming languages for which EVM compilers are available. The most common language is Solidity, which superficially (syntactically) is reminiscent of JavaScript. As of the end of 2020, the Ethereum documentation lists two other languages: Vyper, which is based on Python, and Yul Plus, a completely independent development.
What all these languages have in common is that they are domain-specific because, in contrast to the general-purpose languages, they occupy a niche with special features and in particular a special runtime: the EVM. Of course, such domain-specific languages (DSL) are generally a good idea to reduce the complexity of applications.
But in the case of the EVM, that doesn't make much sense. After all, regardless of the lack of opportunities to interact with the blockchain-external world, it can execute any algorithm, so it is (in simple terms) Turing-complete.
So why not use an existing language and runtime environment? If necessary, you would then have to remove features, but you could fall back on longer experience, more stable tooling and - much more importantly - a broader base of programmers. Because it is old hat that nowadays the popularity of a programming language not only depends on whether you can program in it particularly concise, type-safe or dynamic, but also how easily you can access how many existing libraries and packages. This change of times is particularly illustrated by JavaScript, which is often criticized for its crude semantics, but has been the most popular programming language since the millionth NPM package at the latest.
The people behind the Ethereum specification have come to the conclusion that some problems can be solved by migrating away from an in-house development to a universal language. How practical that development is currently underway on the web to establish an alternative to the top dog JavaScript: web assembly (WASM). This is both a universal intermediate language and a binary format, paired with a specification for interpreters. As the name suggests, the open standard was originally conceived for the web; In the meantime, however, other areas of application (e.g. smartphone apps) are also being discussed.
The development of WASM is being driven by industry giants such as Microsoft, Google and Apple. What distinguishes the language is that it is designed for portability from the start. This can be recognized by the fact that numerous existing programming languages such as Rust, C ++ or Go can already compile for web assembly.
So also a perfect basis for smart contracts? In fact, Webassembly seems to be made for this purpose. Also in the browser - the original domain for WASM - it is necessary to strictly regulate the running code in order to prevent security gaps. In addition, the fact that WASM does not have garbage collection, i.e. the programmer has to take care of memory management himself, ensures the deterministic execution of algorithms. As a bonus, there are solid and efficient interpreters available for various platforms.
All of these are also criteria that are extremely important for the design of a blockchain. Therefore, the use of Ethereum flavored web assembly (EWASM) is the logical aim of the long-term planning of Ethereum 2. EWASM is fully compatible with WASM, but introduces an additional interface to the blockchain in order to be able to control typical Ethereum operations (for example the transfer of tokens). For Ethereum users, the interaction with EWASM smart contracts is transparent and works exactly like EVM contracts.
Smart contracts in web assembly
But how do you proceed if you want to program a smart contract in EWASM? On the one hand, you need a suitable Ethereum network. Because as beautiful as the vision of Ethereum 2.0 is, it is just a vision. Unfortunately, there is no official test network, but you can switch to Oasis Ethereum, which is compatible with Ethereum and, to a certain extent, offers a preview of the future Ethereum 2.0.
You also need a programming language so that you don't have to write assembly code by hand. Rust offers many advantages here. Thanks to the support of WASM in the Rust compiler, compatible smart contracts can be generated directly from a Rust program. However, Rust is currently not a sensible choice for Ethereum because the toolchain is still too fragile. Most of the examples that can be found on the Internet are already out of date shortly after publication.
That's why it's worth taking a look at Solidity here instead. The classic example of a smart contract in Solidity is an ERC-20 token, a standardized interface to manage any token on the Ethereum chain. By default, Ethereum uses the currency ether. With ERC-20 tokens, you can define other currencies, for example a token that can be exchanged one-for-one for euros. Such a contract has a fixed structure. Basically there are storage fields in the contract for:
The number of tokens in circulation (an upper limit can therefore be set)
Current account balances
In Solidity this can be defined as follows:
uint256 private totalSupply;
mapping(address => uint256) private balances;
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
require(c >= a, „SafeMath: addition overflow“);
return c;
}
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
require(b <= a, „SafeMath: subtraction overflow“);
uint256 c = a - b;
return c;
}
These two methods are used to safely add or subtract two numbers. For example, if there are not enough tokens on the source account, the transaction is aborted with an error message ("Subtraction Overflow"). The actual transfer function is then implemented quickly:
function transfer(
address recipient,
uint256 amount
) {
balances[msg.sender] = sub(balances[msg.sender], amount);
balances[recipient] = add(balances[recipient], amount);
}
First, the account balance with the sender is reduced, then increased with the recipient. Calling this method is always transactional: If either the recipient already has too many or the sender does not have enough tokens, neither of the two operations is carried out. The above solidity code can be translated to web assembly using the SOLL compiler.
Deployment and other options
This finished WASM file can be deployed on a blockchain using web3.js, as is usual with Ethereum. If you want to use Oasis for this, you can configure an appropriate provider. You can either work in the browser or in Node.js.
In order to deploy the contract, you have to create a new transaction that has not given a recipient address. The HEX-coded string of the web assembly code is transferred as data:
const receipt = await web3.eth.sendTransaction({ from: 0, data: "0061736d...", gas: 10000000 });
console.log(receipt.contractAddress);
If everything went right, the last line outputs the address of the newly created contract:
'0xad1c3896b09F86906030654F6e92D61bf0D24293'
In addition to being used in a blockchain, the WASM code generated by the compiler can theoretically also be executed unchanged in the browser, provided that the necessary Ethereum functions are provided. The web assembly tools also offer a number of other processing options, for example the binary code can be translated to C. It would therefore be entirely possible to use the same code in both smart contracts and classic applications.
Conclusion
With EWASM, the Ethereum community has set the course to put smart contracts on a solid basis in the future. In contrast to self-made EVM, web assembly offers tangible advantages - for example, broad applicability and greater security thanks to numerous analysis options.
Various Ethereum clients are already implementing this alternative VM, but some of them are not yet compatible with one another. It is a pity that the Rust toolchain has not yet been properly integrated into Ethereum. However, since the development of Ethereum 2.0 is constantly progressing and there is a high level of interest in web assembly, there will hopefully soon be a more robust tooling.