EVM and Solidity Overview

Luke Park
Metadium
Published in
10 min readSep 21, 2022

Understanding the Ethereum Virtual Machine and Solidity

Ethereum virtual machine

The Ethereum Virtual Machine (EVM) is a runtime environment for smart contracts in Ethereum. EVM is sandboxed and has the characteristic of running completely isolated from other environments. Thanks to this, the code running in the EVM cannot be accessed by other processes, nor can it be accessed by an unspecified network.

https://ethereum.org Ethereum structure reorganization

The role of EVM can be broadly divided into two categories: Calculation and data storage.

Calculation

To avoid consensus problems, EVM keeps instruction sets to a minimum. Basic algebraic, bitwise, logical, and comparison operations are supported, as well as conditional and unconditional jumps. In addition, EVM supports commands for accessing information such as block number and timestamp so that the information of the blockchain can be used.

With the hard fork, the cost of each operation may be changed, and new operations may be added and deleted.

Data Storage

EVM’s data storage space is generally divided into three types: storage, memory, and stack. From the perspective of Ethereum as a whole, it can include Calldata or even block-level areas.

Storage is an area that permanently preserves data and is a key-value store that accesses 256 bits of value from 256 bits of the key. Because I/O uses a lot of hardware and time, storage-related instructions are relatively expensive and consume more gas. Because it is expensive, minimizing storage usage is the key to smart contract development. Also, storage in the EVM requires explicit permissions for read/write. Stored values that are not set to the public and set to internal or private cannot be accessed by other contracts. Instead, it can be accessed through functions with getter and setter roles, with visibility set to public or external functions.

Memory is a temporary space used by the contract, newly secured for each message call. It increases linearly, of course, the more it scales, the more expensive it becomes. Currently, since the cost increases to the quadratic level, it is necessary to consider a memory-saving technique in contract development.

For reference, the message call also has another storage area called Calldata, and it is possible to prevent a considerable cost due to the increase in memory by using it as it is without copying it to the memory. However, the memory area can be modified, but Calldata can only be read.

The stack is an area that handles input and output values for operations. EVM is not a computer hardware-like register machine but a stack machine with a simple structure. Therefore, all operations are performed on the stack. Since the maximum stack size is limited to 1024, be aware of this and use local variables or parameters appropriately.

The Log can also store data at the block level. The defined event can be stored by emitting it. However, the contract cannot access the same Log after the Log is created. Instead, it is an efficient area to access outside the blockchain. Since these log data are also recorded through the bloom filter, the Log can be found even by light clients that do not have full blockchain data in a cryptographically secure way.

In addition, there is a virtual ROM area for uploading codes to prevent forgery/falsification during code execution, and an area for storing block information and information of the blockchain itself.

Solidity

Solidity is a high-level object-oriented language for implementing smart contracts targeting the Ethereum Virtual Machine. Any programming is possible by paying the fees within the block gas limit.

Solidity was greatly influenced by several existing programming languages, especially in the early days, and was designed with much influence from JavaScript. Its effectiveness can be seen in a curly-bracket language and import methods. Even in the early days, it was very similar, such as function-level scoping and the var keyword, but now it is no longer supported for security reasons. Instead, it can be said that version 0.4 is closer to C/C++, such as variable declarations, looping statements, and overloading. Convenience and safety have been improved through subsequent major version updates, and it currently has its own unique style, such as strict type conversion. It was also influenced by Python, such as decorators (called modifiers in Solidity), multiple inheritances, the super keyword, and copy semantics of value and reference types.

Contract development languages

In addition to Solidity, EVM bytecode can be written in various languages. Vyper is a Python-like contract language. Yul/Yul+ is an intermediate language, and low-level language is used when optimization and security are essential. It is mainly used to implement EVM and common denominator work with Ewasm and optimistic rollup. FE is being developed as an easy-to-learn, easy-to-learn, developer-friendly language inspired by Python and Rust.

Although various languages exist, contract development through Solidity is the most active, for the following reasons:

  • Numerous tutorials and sample open source code
  • A variety of tools to improve development and ease of use
  • Large development community
  • Inline assembly can be used when low-level development is required while providing reasonable functionality

Solidity Inline Assembly

Solidity’s inline assembly is a feature that facilitates low-level development beyond the functionality of Solidity. Although it is an assembly, it is easy to develop by providing a functional style.

Example of low-level code:

3 0x80 mload add 0x80 store

Coded as follows:

mstore(0x80, add(mload(0x80), 3))

It has the same meaning, but convenience is increased thanks to the functional style, readability, and development.

Inline assemblies allow direct optimization of code to be written, but conversely, they may not benefit from optimization performed by the compiler. Therefore, it is efficient to write inline assembly only when it is determined that it can be clearly optimized and leave the rest to the compiler.

EVM Compatible Blockchain

Source: https://ethereum.org/en/eth/

Most of the projects that forked Ethereum also use EVM as it is or provide compatibility. That makes it possible to develop contracts using Solidity and a natural connection to many existing tools and services, such as REMIX, a web IDE that supports debugging, convenient contract deployment and execution, and multiple extensions.

However, since Ethereum’s EVM command update and Solidity version upgrade are being made steadily, it can be said that it is a healthy project to reflect the upgrade even after the chain fork continuously.

Metadium

For example, in the case of Metadium, the contents of the Istanbul hard fork of Ethereum are applied based on the master branch and the latest release version as of September 2022.

Istanbul is a hard fork with changes at the EVM level, including the addition of CHAINID and EXTCODEHASH opcodes. The code can be verified that these two opcodes are added to Metadium.

Two block-related opcodes have been added to the Istanbul Hard Fork.

In Istanbul, the gas cost of existing opcodes has also changed several times. For example, the gas cost of SLOAD has been changed from 200 to 800, and related codes can be found in Metadium.

Code reflecting changes in the gas ratio of opcodes related to the tri-size.

Even after Istanbul, there were many significant and minor changes to Ethereum, and their reflections could be found in the Metadium development branch. The London Hard Fork has been applied, and the famous gas-ratio mechanism change, EIP-1559, has also been applied.

The BASEFEE opcode that appeared from EIP-1559 can be verified.

Although it still exists in the development branch, Metadium tracks and continuously reflects Ethereum’s updates.

References

이더리움 가상머신

이더리움 가상머신(Ethereum Virtual Machine, 이하 EVM)은 이더리움에서 스마트 컨트랙트를 위한 런타임 환경이다. EVM은 샌드박스-ed 되어 있어 기타 환경과 완벽히 고립된 채로 구동된다는 특징을 가진다. 이 덕분에 EVM에서 구동되는 코드는 다른 프로세스가 접근하지 못하며 불특정 네트워크의 접근도 불가하다.

https://ethereum.org 이더리움 구조도 재구성

EVM이 담당하는 역할은 크게 연산과 데이터 저장의 두 부류로 구분할 수 있다.

연산

합의 문제의 발생을 피하고자 EVM에서는 instruction set을 최소한으로 유지한다. 기본적인 대수, 비트, 논리, 비교 연산이 지원되며, 조건부 및 무조건부 jump가 지원된다. 또한 블록체인 자체의 정보를 이용할 수 있도록 블록 넘버와 타임스탬프 등의 정보 접근을 위한 명령어도 지원한다.

하드포크를 통해 각 연산에 소요되는 비용의 변경, 새로운 연산의 추가 및 삭제 등이 이루어질 수 있다.

데이터 저장

EVM의 데이터 저장 공간은 일반적으로 스토리지, 메모리, 스택의 세 종류로 구분한다. 이더리움 전체의 관점에서 보면 Calldata나 블록 레벨 영역까지도 포함할 수 있다.

스토리지는 데이터를 영구히 보존하는 영역으로, 256bits의 키(key)로부터 256bits의 벨류(value)에 접근하는 키-벨류 스토어이다. I/O에 하드웨어 비용 및 시간을 많이 사용하기 때문에 스토리지와 관련된 명령어들은 상대적으로 비싼, 더 많은 가스(gas)를 소모하는 특징이 있다. 비용이 많이 들기 때문에 스토리지 사용은 최소화하는 것이 스마트 컨트랙트 개발의 핵심이다. 또한 EVM에서의 스토리지는 읽기/쓰기에 명확한 권한이 필요하다. Public으로 설정되어 있지 않고 internal이나 private으로 설정된 저장값은 다른 컨트랙트가 접근할 수 없다. 대신 Public이나 external 함수로 가시성이 설정된, getter와 setter 역할의 함수들을 통해 접근할 수 있다.

메모리는 각 메시지 콜마다 새롭게 확보되는, 컨트랙트가 사용하는 임시 공간이다. 선형적으로 증가하는데, 당연히 더 많이 확장될수록 더 비싸다. 이때 비용이 Quadratic 수준으로 증가하기 때문에 컨트랙트 개발에 메모리 절감 기법의 고려가 필요하다.

참고로 메시지 콜 역시 Calldata라는 또 하나의 저장 영역을 가지는데, 이를 메모리에 복사하지 않고 그대로 이용하는 등의 기법으로 메모리 증가에 따른 막대한 비용 지불을 방지할 수 있다. 단, 메모리 영역은 수정이 가능하지만 Calldata는 읽기만 가능하다.

스택은 연산을 위한 입력값과 출력값을 다루는 영역이다. EVM은 컴퓨터 하드웨어-like한 레지스터 머신이 아닌, 단순한 구조의 스택 머신이다. 따라서 모든 연산은 스택에서 이루어진다. 최대 스택 사이즈가 1024로 한정되어 있기 때문에, 이를 유의하며 로컬 변수나 파라미터를 적당히 사용해야 한다.

Log를 통해 데이터를 블록 레벨에 저장할 수도 있다. 정의한 이벤트(event)를 emit 하는 것으로 저장할 수 있다. 단, 컨트랙트는 로그가 생기고 난 이후 다시 같은 로그에 접근할 수는 없다. 대신에 블록체인 밖에서 접근하기에 효율적인 영역이다. 이 로그 데이터들은 블룸필터를 통해 또 기록되기 때문에, 암호학적으로 안전한 방법을 통해 전체 블록체인 데이터를 가지고 있지 않은 라이트 클라이언트에서도 로그를 찾을 수 있다.

이외에도 코드 수행 시 위/변조를 방지하기 위해 코드를 업로드하는 가상 ROM 영역, 블록 정보들과 블록체인 자체의 정보를 저장하고 있는 영역 등이 있다.

솔리디티

솔리디티(Solidity)는 이더리움 가상머신을 타겟으로 하는, 스마트 컨트랙트를 구현하기 위한 객체지향 고수준 언어이다. 블록 가스 한도 안에서 수수료만 지불할 수 있다면 모든 종류의 프로그래밍이 가능하다.

솔리디티는 여러 기 존재하는 프로그래밍 언어들의 영향을 많이 받았는데, 특히 초창기에는 자바스크립트의 영향을 많이 받아 설계되었다. 중괄호 언어(Curly-bracket language)라는 점과 import 방식 등에서 그 영향을 살펴볼 수 있다. 심지어 초창기에는 함수 레벨 스코핑이나 var 키워드가 존재하는 등 굉장히 유사했으나, 현재는 보안을 이유로 더 이상 지원하지 않는다. 오히려 0.4버전부터는 변수 선언, 반복문, 오버로딩 등 C/C++에 가까운 모습이라 할 수 있다. 이후 계속된 메이저 버전 업데이트를 통해 편의성과 안전성이 개선되며, 엄격한 타입 변환 등 현재는 나름 독자적인 스타일을 갖추고 있다. 파이썬으로부터도 영향을 받았는데, 데코레이터(솔리디티에서는 모디파이어로 불림)나 다중상속과 super 키워드, 값과 참조 타입의 copy 시멘틱 등이 이에 해당한다.

컨트랙트 개발 언어들

솔리디티 이외에도 다양한 언어로 EVM 바이트코드를 작성할 수 있다. 바이퍼(Vyper)는 파이썬과 유사한(Pythonic) 컨트랙트 언어이다. Yul/Yul+는 최적화와 보안을 중시할 때 사용하는 중간 언어이자 저수준 언어이다. EVM뿐만 아니라 Ewasm과의 공통분모 작업 그리고 옵티미스틱 롤업 등의 구현에 주로 사용된다. FE는 파이썬과 러스트로부터 영감을 받은, 쉽게 배울 수 있는, 이더리움 에코시스템 입문 개발자용 언어로 개발 중이다.

다양한 언어가 존재하지만 솔리디티를 통한 컨트랙트 개발이 가장 활발한데, 다음과 같은 이유가 있다:

수많은 튜토리얼과 샘플 오픈소스 코드들

개발 및 사용 편의성을 증진시키는 다양한 도구들

큰 개발 커뮤니티

적당한 기능성을 제공함과 동시에, 저수준 개발이 필요한 경우 인라인 어셈블리를 사용할 수 있음

솔리디티 인라인 어셈블리

솔리디티의 인라인 어셈블리는 솔리디티의 기능성을 넘어선 저수준의 개발을 편리하게 하는 기능이다. 어셈블리임에도 불구하고 Functional 스타일을 제공해서 쉬운 개발이 가능하다.

가령 다음과 같은 저수준 코드를

다음과 같이 코딩할 수 있다.

동일한 의미를 가지고 있으나 Functional 스타일을 제공하는 덕분에 가독성과 개발 편의성이 증대된다.

인라인 어셈블리를 통해 직접 최적화된 코드를 작성할 수 있지만, 역으로 컴파일러가 수행하는 최적화의 혜택을 받지 못할 수 있다. 따라서 확실하게 최적화할 수 있는 부분으로 판단될 경우에만 인라인 어셈블리로 작성하고 나머지는 컴파일러에게 맡기는 것이 효율적이다.

EVM 호환 블록체인

Source: https://ethereum.org/en/eth/

이더리움을 포크(fork)한 여러 프로젝트들도 대부분 EVM을 그대로 사용하거나 호환성을 제공하고 있다. 그 덕분에 솔리디티를 사용한 컨트랙트 개발이 가능하며, 이미 존재하는 여러 도구 및 서비스에 자연스러운 연결이 가능하다. 가령 디버깅, 편리한 컨트랙트 배포 및 실행, 그리고 여러 확장프로그램을 지원하는 웹 IDE인 REMIX를 활용할 수 있다.

다만 이더리움의 EVM 명령어 업데이트와 솔리디티 버전업은 꾸준히 이루어지고 있기 때문에, 체인 포크 이후에도 지속해서 해당 업그레이드 반영을 해주는 것이 건강한 프로젝트라 할 수 있겠다.

메타디움

예를 들어, 메타디움의 경우 2022년 9월 현재 master 브랜치최신 릴리즈 버전을 기준으로 이더리움의 이스탄불 하드포크 내용까지 적용되어 있다.

이스탄불은 CHAINID와 EXTCODEHASH opcode가 추가되는 등 EVM 레벨에서의 변화가 있었던 하드포크이다. 실제로 메타디움에 이 두 opcode가 추가되어 있음을 코드로 확인할 수가 있다.

이스탄불 하드포크에 도입된, 블록과 관련된 opcode 두 개가 추가되어 있다.

또한 이스탄불에서는 기존 opcode의 가스 비용도 여럿 변경되었다. 가령 SLOAD의 가스 비용이 200에서 800으로 변경되었는데, 메타디움에서도 관련 코드들을 살펴볼 수 있다.

트라이 사이즈와 관련된 opcode들의 가스비 변경 사항을 반영한 코드

이스탄불 이후에도 크고 작은 변경사항들이 이더리움에 많이 있었는데, 이들의 반영사항은 메타디움 개발 브랜치에서 확인할 수가 있었다. 현재를 기준으로 런던 하드포크까지 적용되어 있으며, 그 유명한 가스비 메커니즘 변경인 EIP-1559도 적용되어 있다.

EIP-1559로부터 등장한 BASEFEE opcode를 확인할 수 있다.

아직은 개발 브랜치에 존재하긴 하지만, 메타디움에서는 이더리움의 업데이트를 추적하여 지속해서 반영해주고 있음을 알 수 있다.

Writer : Luke Park

참고문헌

https://ethereum.org/en/developers/docs/

https://docs.soliditylang.org/en/v0.8.16/

https://remix-ide.readthedocs.io/en/latest/

--

--