암호 화폐가 단순히 기존 통화의 대용품이 아니라, 미래를 이끌어나갈 차세대 기술로 부상할 수 있었던 건 스마트 컨트랙트라고 해도 과언이 아닐 만큼, 스마트 컨트랙트는 블록체인의 핵심 요소 중 하나이다. 그렇기 때문에, 거의 모든 블록체인 프로젝트는 스마트 컨트랙트를 지원하기 위해 스크립트 언어나 가상 머신을 내장하고 있다. 다만, 프로젝트에 따라 지원하는 스크립트 언어, 가상머신이 다르기 때문에, 지원하는 스마트 컨트랙트의 범위가 다를 수는 있다
Ethereum
스마트 컨트랙트라고 하면 Ethereum을 떠올릴 만큼, Ethereum은 스마트 컨트랙트로 유명한 블록체인 프로젝트이다. 백서에 Ethereum의 개발 목적 중 하나가 bitcoin 스크립트의 한계를 뛰어넘기 위함이라고 한 만큼, Ethereum의 스크립트는 나중에 설명할 bitcoin의 스크립트와는 차별화되는 특징을 가지고 있다. 그중 가장 큰 특징으로는 loop를 지원해서 튜링 완전성을 충족시킨다는 것, 그리고 무한 루프 문제를 해결하기 위해 gas 시스템을 도입했다는 점이다. Gas는 Ethereum에서 거래 수수료를 지칭하는 말로, 트랜잭션을 처리하는데 필요한 계산 1회 당 비용과 총 필요한 계산 횟수의 곱으로 계산된다. 트랜잭션을 생성할 때, 계산 1회 당 비용과 gas 상한선을 미리 설정해 두기 때문에, 트랜잭션이 무한 루프에 빠지더라도 계산 비용이 gas 상한선을 초과하게 되면 트랜잭션이 취소되어 무한 루프에서 탈출할 수 있다. 이 때 주의할 점은, 트랜잭션이 취소 될 때 다른 내용들은 그대로 원상복구 되지만, 수수료가 gas 한도치만큼 빠진다는 점이다. 그래서 필요한 계산량이 gas 한도치를 초과하지 않도록 조심할 필요가 있다. Ethereum 은 가상 머신으로 Ethereum Virtual Machine을 사용하고, 스크립트 언어로는 solidity를 사용한다.
Bitcoin
Bitcoin이 초창기 가상 화폐라서 bitcoin에서 스마트 컨트랙트가 안된다고 생각하거나, 무관심한 분들도 많지만, bitcoin도 가상머신, 스크립트 언어를 지원하고 있다. Bitcoin는 Ethereum과는 다르게 loop를 지원하지 않아 튜링 불완전하다. Bitcoin에서 트랜잭션은 그 트랙잭션의 outputs에 있는 lock script가 다음 트랙잭션의 inputs에 있는 unlock 스크립트로 풀리면 거래가 진행되는 방식으로 구성되어 있다. 이 부분을 좀 더 자세히 살펴보면, Bitcoin의 가상 머신은 two-stack machine으로 이루어져 있다. 각각의 스택에는 임의의 길이의 배열이 저장될 수 있으며, 처음 시작할 때는 비어있는 채로 시작한다. 종료될 때, 스택의 맨 위에 있는 값이 참이라면, lock script가 풀린다. Bitcoin script에서 쓰이는 연산 코드를 Opcode라고 하고, 이 코드를 이용해서 lock 스크립트가 원하는 조건을 만족 시키면 풀리도록 스마트 컨트랙트를 작성할 수 있다.
이해를 돕기 위해, 가장 흔하게 쓰이는 거래 형식인 Pay-to-Public-Key-Hash의 스크립트가 어떻게 퍼블릭 키와 서명 값이 일치 할 때만 트랜잭션이 실행되도록 하는지 살펴보자. 맨 처음, Unlock script가 실행되므로, <sig>, <pubkey>가 차례로 스택에 쌓인다. 그 다음, lock script가 실행된다. OP-DUP가 현재 스택에서 가장 위에 있는 아이템인 <pubkey>를 복사하여 스택의 위에 올려두고, OP_Hash160으로 맨 위에 있는 <pubkey>가 해시 되어 <hash(pubkey)>가 된다. 그 다음 명령어인 <hash(pubkey)>값이 스택에 쌓이고, OP_EQUALVERIFY로 현재 스택 가장 위에 있는 두 해시 값이 같은지 아닌지를 비교하고 두 해시 같으면 계속 진행, 틀리면 트랜잭션이 무효처리된다. 그리고 마지막 명령어인 OP_CHECKSIG로 <pubkey>와 <sig>가 일치하는지 확인하고 스택에서 제거한 뒤, 일치하면 1, 아니라면 0을 스택에 쌓는다. 1이라면 lock script가 풀릴 것이고, 아니라면 풀리지 않을 것이다.
CodeChain
CodeChain을 설계하면서, 어떻게 설계를 해야 할 지 많은 고민을 있었는데, 그 중에서 특히 loop지원 여부에 제일 많은 고민을 했다. 긴 고민 끝에, 거래 플랫폼에서는 안정성이 중요하고, loop 기능 없이도 필요한 거의 대부분의 스마트 컨트랙트를 지원할 수 있다고 판단하여 loop 기능을 지원하지 않기로 했다. 그래서 CodeChain은 스크립트 부분만 따지면, 트랜잭션이 끝난다는 것을 보장하기 위해, loop기능을 빼서 튜링 불완전하다는 점에서 Ethereum보다는 bitcoin에 가깝다고 볼 수 있다.
CodeChain에서는 서비스에 블록체인을 최적화 시키기 위해 ‘Burn’이라는 새로운 상태를 추가, lock script와 매개 변수의 분리, single stack machine, unlock script는 push만 할 수 있도록 제한을 걸어 두는 등 여러 변화를 주었다. 그 중에서 ‘Burn’은 특정 자산을 영구적으로 사용 불가로 만들며, UTXO에서 특정 자산을 지우기 위해 추가한 상태이다. 이 상태로 바뀌게 되면, 이 자산은 UTXO에서 사라지게 되어, UTXO 크기를 조절해 가면서 쓸 수 있게 된다. Burn된 자산은 앞으로 다른 트랜잭션에서 사용 불가 하도록 처리된다.
CodeChain 스크립트의 Opcode로는 NOP, Boolean, Flow Control, Stack Manipulation, Cryptography 가 있다. Flow control에 점프는 있지만, 백점프는 없다. 트랜잭션 실행 과정은 다음과 같다. 일단 실행하기 전, unlock script가 유효 한지와 lock 스크립트를 해시로 돌린 값이 lock script hash와 같은지, 이 두가지를 확인을 한다. 이 두 가지 모두 유효하다면, 트랜잭션이 실행이 되고, unlock 스크립트, 매개 변수, lock 스크립트를 차례로 실행한 값에 따라 성공하거나, 실패하거나, Burn이 된다.
CodeChain 스크립트의 Opcode로는 NOP, Boolean, Flow Control, Stack Manipulation, Cryptography 가 있다. Flow control에 점프는 있지만, 백점프는 없다. 트랜잭션 실행 과정은 다음과 같다. 일단 실행하기 전, unlock script가 유효 한지와 lock 스크립트를 해시로 돌린 값이 lock script hash와 같은지, 이 두가지를 확인을 한다. 이 두 가지 모두 유효하다면, 트랜잭션이 실행이 되고, unlock 스크립트, 매개 변수, lock 스크립트를 차례로 실행한 값에 따라 성공하거나, 실패하거나, Burn이된다.
실제로 스크립트를 실행시켜 burn이 되는 과정을 살펴보자. 맨 처음 unlock script에서 <sigB>를 push 하고, 매개 변수 <pubkeyA>와 <pubkeyB>가 스택에 쌓인다. 그 다음, COPY 2가 stack의 맨 위에서 두 칸 아래 있는 아이템을 복사하므로, <sigB>가 스택 맨 위에 복사된다. CHKSIG를 하면, <sigB>와 <pubkeyA>가 일치하지 않으므로, 이 두값이 사라지고, 스택에 0이 쌓인다. 스택 맨 윗 값이 0이므로, JNZ 3 에서는 스택 맨 위에 있던 0만 사라진다. CHKSIG를 하면, <pubkeyB>와 <sigB> 값이 일치하므로, 이 두값이 사라진 뒤 1이 스택 맨 위에 쌓이고, JZ 2 에서는 스택 맨 위에 있던 1 값만 사라진다. 그 다음 명령은 BURN이므로 Burn이 실행된다. 만약 unlock script에서 push 되는 서명이 <sigA> 라면, JNZ 3 에서 3칸 뒤로 건너뛰므로 POP되어 아무 일도 일어나지 않고, 서명이 <sigA>도, <sigB>도 아니라면 JZ 2 에서 pop을 건너뛰므로 마찬가지로 아무 일도 일어나지 않는다. 따라서, 이 스크립트를 사용하면 B가 사용했을 때에만 자산이 Burn하도록 할 수 있다.
지금까지 Ethereum, bitcoin, 그리고 CodeChain의 가상 머신과 스크립트 언어를 살펴 보았는데, Atomic Swap처럼, 튜링 불완전 하더라도 응용 할 수 있는 분야는 많다. 따라서, 좀 더 최신 기술이라고 튜링 완전성, Ethereum의 스크립트 언어에만 너무 집중하기 보다는, Bitcoin 같은 다른 프로젝트에서도 꾸준히 연구를 하고 있으니 시야를 넓혀서 지금 내가 가장 잘 활용 할 수 있는 가상 머신과 스크립트 언어에는 무엇이 있나 생각 해 볼 필요가 있다.
Originally published at medium.com on July 3, 2018.