[스마트 컨트랙트] 3. 이더리움에서 스마트 컨트랙트

adc0612·2022년 10월 21일
0

스마트 컨트랙트

목록 보기
3/4

EVM(Ethereum virual machine)

  • EVM(Ethereum Virtual Machine)은 우리가 짠 코드와 이더리움 블록체인 사이에 있는 가상 머신으로, 블록체인에서 코드가 실행될 수 있도록 한다.
  • 솔리디티로 작성된 dApp을 이더리움 네트워크에 올려야하지만 솔리디티는 고급언어이므로 바이트코드(bytecode)로 변환 후 바이트 코드를 다시 EVM이 해석할 수 있는 OP코드로 변환해야 실행할 수 있다. (I.e 솔리디티 코드 → 바이트코드 → Opcode 흐름)
  • 솔리디티로 작성된 스마트 컨트랙트는 EVM에서 동작하기 때문에 특정 운영체제나 하드웨어에 종속되지 않는다.

바이트코드 동작방식

  • EVM은 Opcode(명령어 집합)을 효율적으로 저장하기 위해, 바이트코드로 인코딩된다.
  • 모든 Opcode에는 1바이트가 할당된다.
  • Opcode를 7가지로 나눌수 있다.
    • 스택 조작 : POP, PUSH, DUP, SWAP
    • 산술/비교/비트 연산 : ADD, SUB, GT, LT, AND, OR
    • 환경 : CALLER, CALLVALUE, NUMBER
    • 메모리 조작 : MLOAD, MSTORE, MSTORE8, MSIZE
    • 스토리지 조작 : SLOAD, SSTORE
    • 프로그램 카운터 : JUMP, JUMPI, PC, JUMPDEST
    • 중지 : STOP, RETURN, REVERT … etc

EVM 내부 동작 구조

상태 머신(transaction-based state machine)

이더리움은 거래에 기반을 둔 상태 머신이다. 상태 머신이란 일련의 입력을 읽고, 그 입력을 기반으로 새로운 상태로 전환하는 것을 의미한다.
이더리움이라는 상태 머신은 Genesis state에서 시작한다.
그리고 트랜잭션이 실행되면, 다음 상태로 전환하게 됩니다. 더이상 트랜잭션이 들어오지 않은 마지막 상태가 바로 이더리움의 현재 상태이다.
이더리움의 상태에는 수천 개의 트랜잭션이 있다. 이 트랜잭션은 "블록"이라는 그룹에 묶여 있으며, 블록은 직전에 만들어진 블록과 이어져 있다.

전역 상태

이더리움의 전역 상태는 계정 주소와 계정 상태를 매핑한 것으로 구성되어 있다.
이 매핑은 머클 패트리샤 트리(Merkle Patricia Tree) 형태로 저장되어 있다.
트리 맨 아래에 있는 데이터는 저장하려는 데이터를 청크로 분할한 다음, 각 청크를 두개씩 모아 해시를 취하여 부모 노드를 만든다.
그렇게 하나의 루트 노드가 만들어질때까지 동일한 과정을 반복한다.

이더리움의 블록 헤더

이더리움의 블록 헤더에는 세 개의 머클 트리 구조의 루트 노드의 해시값이 저장되어 있다.

  1. 상태 트리(state tree): 트랜잭션과 연관된 계정의 상태 정보 저장
  2. 트랜잭션 트리(transaction tree): 현재 블록의 트랜잭션 정보 저장
  3. 영수증 트리(receipt tree): 현재 블록의 거래 영수증 정보 저장

트랜잭션과 메세지

트랜잭션은 EOA에서 생성되고, 일련의 과정을 거쳐 블록체인에 올라간 암호화 서명된 명령어의 집합이다.
즉, 트랜잭션은 외부 세계를 이더리움 내부의 상태로 연결해주는 다리와 같습니다. 그리고 연결의 창구가 바로 CA다.
그 외의 트랜잭션은 메시지 호출(Message Call)과 컨트랙트 생성(Contract Creations) 두 종류로 나뉜다.

컨트랙트 생성(Contract Creations) (i.e. CA생성)

새로운 CA를 만들기 위해서는 먼저 특별한 공식을 이용해 새로운 계정의 주소를 정의해야한다.
다음의 과정을 통해 새로운 CA를 만들 수 있다.

  1. 논스를 0으로 설정한다.
  2. 송신자가 CA 생성 트랜잭션에 이더를 함께 보낸 경우, 이를 CA의 잔금(balance)으로 설정한다.
  3. 잔금에서 value 만큼을 제외한다.
  4. CA의 스토리지를 빈 값으로 초기화한다.
  5. CA의 코드를 빈 문자열의 해시값으로 초기화한다.

init

  • 한번 계정을 초기화하고 나면, 트랜잭션에서 보낸 init 코드를 사용해 새로운 CA를 생성할 수 있다.
  • init 코드가 실행되는 동안 계약 생성자에 따라 CA의 스토리지를 업데이트하거나, 다른 CA를 새롭게 생성하거나, 다른 메시지 호출을 만들 수 있다.
  • 계약을 초기화하는 이 init 코드를 실행할 때는 가스를 사용한다.

    이더리움에서는 트랜잭션에 있는 연산을 수행할 때마다 비용을 청구하는데, 이 비용의 단위를 가스(gas)라고 합니다. 지금은 이 정도로 이해해도 충분합니다. 트랜잭션을 보낼 때는 코드에 수행되는 만큼의 가스를 함께 보내야 합니다.

메세지 호출(message call)

  • 새 계정이 생성되지 않기 때문에 메시지 호출 실행에는 init 코드가 포함되지 않는다. 그러나 입력 데이터를 가지고 있을 수는 있다.
  • 메시지 호출은 한번 실행되면 출력 데이터를 포함한 추가적인 요소들을 가지게 될 수도 있는데, 이 추가 요소들은 뒤에 이어질 다른 실행에 필요한 데이터다.
  • CA 생성과 마찬가지로, 메시지 호출을 실행할 때 가스가 부족하거나, 트랜잭션이 잘못되어 종료되는 경우 사용된 가스는 환불되지 않습니다. 남은 가스는 모두 소비되며, 상태는 직전 상태로 돌아간다.

트랜잭션 실행 모델과 EVM

트랜잭션 처리를 실제로 처리하는 프로토콜은 EVM이다.
EVM의 구성 요소

  • 스택
    EVM은 비트코인 스크립트와 마찬가지로, 스택 기반 아키텍쳐를 가지고 있다.
    EVM 내에는 하나의 빈 스택이 있으며, 스택에 들어가는 요소의 크기는 256bit이며, 스택의 최대 크기는 1024bit이다.
  • 메모리
    EVM은 메모리를 가지고 있으며, 메모리에서는 word-address 형식의 바이트 배열로 데이터를 저장한다.
    메모리는 휘발성이기 때문에, 프로그램이 종료되면 메모리에 들어있는 데이터는 사라진다.
  • 스토리지
    메모리와 다르게, 스토리지는 비휘발성이며 시스템 상태에 따라 유지된다.
    EVM은 특정한 명령어로만 접근할 수 있는 "가상 ROM"이라는 공간에 프로그램 코드를 분리해서 저장해둔다.

EVM은 트랜잭션을 반복적으로 실행하며, 각 사이클에서 시스템 상태(이더리움의 전역 상태)머신 상태(machine state)를 계산한다. 머신 상태는 아래와 같이 구성된다.

  • 사용 가능한 가스
  • 프로그램 카운터
  • 메모리에 들어있는 값
  • 메모리에서 활성화된 단어의 수
  • 스택에 들어있는 값

솔리디티(Solidity)

  • 솔리디티는 스마트 컨트랙트를 실행하는 객체 지향(object-oriented), 정적 타입(static typed), 고급(high-level) 스크립트 언어로, EVM에서 실행된다.
  • 이더리움을 위해 특별히 제작된 솔리디티(Solidity)는 EVM상에서 작동하는 스마트 컨트랙트를 개발하기 위해 설계되었다.
  • 솔리디티는 컨트랙트 기반의 고급 프로그래밍 언어다.(Javascript과 유사)
  • 솔리디티는 정적 타입 스크립트 언어로, 런타임 언어와는 달리, 컴파일 시 제약 조건을 확인하고 적용한다.
  • 솔리디티는 튜링 완전한다.

    튜링 완전(Turing-Complete): 어떤 프로그래밍 언어나 추상 기계가 튜링 머신과 동일한 연산 능력을 갖출 때를 말한다.
    불완전(Turing-Incomplete): 반대로 튜링 머신보다 연산 능력이 떨어질 경우를 말한다
    튜링머신: 일반적으로 아는 컴퓨터 언어들처럼 기본적인 연산과 조건문, 반복문 등을 모두 수행할 수 있는 기계

솔리디티 개발 도구

  • Remix IDE
    Remix는 솔리디티를 사용한 dApp 개발을 도와주는 통합 개발 환경이다.
    Remix IDE는 자바스크립트로 만들어졌기 때문에 브라우저에서 사용가능하며, 로컬이나 데스크톱 버전을 사용할 수도 있습니다.
  • solc
    솔리디티는 고급 언어이기 때문에 가상 머신인 EVM은 솔리디티를 읽을 수 없다.
    따라서 솔리디티를 바이트코드로 컴파일해야 하는데, 이때 사용하는 컴파일러가 solc이다.
  • Ganache
    Ganache는 개발 단계에서 시뮬레이션 테스트 환경을 구성해주는 도구이다.
    실제 이더리움 메인넷에서 테스트를 하기 위해서는 이더를 내야 하지만, Ganache를 사용하면 채굴 없이 가상 이더리움 환경에서 트랜잭션 제한 없이 테스트를 할 수 있다.
  • TestNet
    이더리움에서 제공하는 퍼블릭 테스트 네트워크를 TestNet이라고 합니다. 테스트 네트워크는 실제 이더리움과 비슷하지만 실제 트랜잭션이 이루어지지는 않습니다. 이더리움에는 현재 Goerli 등의 퍼블릭 테스트넷이 제공되고 있다.
  • 프레임워크: Truffle, Embark, Dapple
    솔리디티 코드를 이더리움 네트워크에 올리기 위한 여러 복잡한 과정을 해결해주는 다양한 프레임워크들이 있습니다. 이 프레임워크들은 솔리디티 코드에 대해 테스트, 디버깅, 컴파일, 배포를 제공한다.

0개의 댓글