Leo's Garage

Mastering Bitcoin 2nd - Programming The Open BlockChain Ch.6-2 본문

BlockChain/Mastering Bitcoin

Mastering Bitcoin 2nd - Programming The Open BlockChain Ch.6-2

LeoBehindK 2020. 1. 19. 10:11
728x90
반응형

이전 글에 이어서 Ch 6장 Transactions의 나머지 부분을 정리해보도록 하겠다.

전에 썼던 포스팅에서는 실제 bitcoin Core에서 조회할 수 있는 JSON형태의 Transaction 내역을 살펴보았다. 앞에서 보았다 시피, "Vin"으로 표현된 input부분과 "Vout"으로 표현된 output 부분으로 나눠져 있음을 볼 수 있었다. 

이번에는 과연 실제로 Transaction이 실행될 때, 어떤 식으로 script가 동작하는지 살펴보도록 하자.

 앞에서 보았다 시피,  UTXO에 있는  Locking script와 Unlocking script는 모두 Script 언어로 작성되어 있다. 만약에 Transaction이 유효하다면, 각 input에 있는 Unlocking script가 각각 이에 대응하는 Locking script에 대하여 실행되면서 실제로 해당 UTXO를 소비할 권한이 있는지를 확인하게 된다.

 Script 언어는 굉장히 심플하고 임베디드 환경과 같은 제한된 환경에서도 동작할 수 있게 설계되었다. 현대적인 고급 언어가 하는 멋진 일들을 할 수는 없고 단지 아주 최소화된 작업만 수행할 수 있다. 이러한 언어로 프로그래밍된 언어를 검증하는데 사용하고 있고 가장 중요한 일이다.

 

 

 Turing Incompleteness

비트코인 Transaction Script언어에는 흔히 현대 언어가 가지고 있는 loop 문법이나 Complex flow control과 같은 기능이 존재하지 않는다. 이러한 점이 비트코인 script 언어를 튜링 불완전한 언어라고 부르는 이유이다. 이러한 점 때문에 비트코인 script 언어는 복잡도가 제한되어 있고 실행 시간이 예측 가능하다. 즉 script 언어는 general-purpose 언어가 아니라는 말이다.

 그럼 왜 비트코인에서는 이렇게 제한적인 언어를 Transaction 언어로 선택한 것일까? 그 이유는 간단하다. 바로 Loop와 같은 기능에 의해 무한 루프에 빠지거나 DDOS 공격에 의해 비트코인 네트워크가 손상되는 것을 방지하기 위해서 이다. 즉 애초에 무한 루프나 Logic이 꼬여서 폭발하는 일 따위는 만들지 않겠다는 말이다.

 

 

Stateless Verification

비트코인 Transaction script에는 어떠한 State를 가지고 있지 않다. 이 말은 어떤 Script를 실행하기 전에는 어떤 State도 존재하지 않으며, Script 내에 검증에 필요한 모든 정보가 담겨 있다는 말이다. 이러한 점은 어떠한 Bitcoin Network에서도 동일한 Script에 대해서 항상 같은 결과를 도출한다는 것을 보장해준다.

 

 

Script Construction ( Lock + Unlock )

Combining scriptSig and scriptPubKey to evaluate a transaction script

 

이전 포스팅에서 언급했던 Unlocking Script(scriptSig) 와 Locking Script(scriptPubKey)를 볼 수 있다.

Locking Script는 output 쪽에 있는 UTXO 사용 조건이라고 볼 수 있다. 이 말은 미래에 이 ouput을 사용하기 위해서는 반드시 해당 조건을 만족시켜야 함을 의미한다. 흔히 scriptPubKey라고도 부르며 이유는 public key를 가지고 있기 때문이며, witness script나 cryptographic puzzle이라고도 부른다.

Unlocking Script는 Locking Script의 조건을 만족시키고 해제하기 위한 Script이다. Unlocking script는 모든 Transaction input의 일부이다. 대부분의 경우, 소유자의 Private key로부터 Wallet에 의해 생성된 Digital signiture를 가지고 있다. 보통 ScriptSig라고 부르며 이유는 Signature를 가지고 있기 때문이다. 

 

모든 비트코인 검증 노드들은 transaction을 검증하기 위하여 Unlocking Script와 Locking Script를 함께 실행시킨다. 비트코인 노드들은 Unlocking Script를 복사하고, 각각 Unlocking Script가 Reference하고 있는 UTXO들의 Locking Script를 복사해온다. 이러한 두 Script는 차례대로 실행된다. 만약에 Locking script의 조건이 Unlocking Script에 의해 만족되면 검증이 된다. 그리고 모든 input에 대해 검증이 끝나면 Transaction이 검증되게 된다.

UTXO는 블록체인 내에 기록되어 있는다. 그러므로 새로운 Transaction에 의해서 소비가 실패했다고 해서 어떤 영향을 받지 않는다. 오직 검증된 Transaction만이 Output을 소비하고 UTXO를 UTXO set에서 제거하게 된다.

 

The Script execution stack

비트코인 Script 언어는 Stack-based 언어라고 불려진다. 이유는 Stack이라고 불리는 데이터 구조를 사용하기 때문이다. Stack은 쉽게 말해 쌓아올린 카드 같은 구조라고 생각하면 된다. Stack에는 두 동작이 있는 Push와 Pop이 있다. Push는 Stack에 아이템을 넣는 행위를 하고 Pop은 아이템을 빼내는 행위를 한다. Stack 구조에서는 오로지 맨 위에 쌓인 아이템에 대해서만 관심을 갖는다. 따라서 이런 구조를 컴퓨터 사이언스에서는 흔히 LIFO(Last In First Out)이라고 말한다.

Bitcoin's script validation doing simple math

위의 그림은 Bitcoin script가 검증하는 과정을 아주 간략하게 수학적으로 보여준 예시이다. 순서는 맨 위의 그림부터 아래로 순차적으로 내려오면서 진행된다. Stack은 왼쪽에 위치하고 있으며 오른쪽은 Script Language를 의미한다. 

첫 번째 그림을 보면, Execution pointer가 2를 가리키고 있다. 해당 값을 Stack에 가져온다. 그 다음에 3을 가져와서 Stack에 쌓는다. 그 다음으로 가면 ADD라는 명령어에 Execution pointer가 가르키게 되는데 여기서 ADD 명령어는 앞의 두 값을 Pop하게 하여 더하고 그 결과를 다시 Push하는 동작을 한다. 그 결과 5가 쌓인 것을 볼 수 있다. 그 다음으로 5가 다시 쌓이게 되고 EQUAL이라는 명령어가 들어는데, 이 명령어도 마찬가지로 이 전 두 값을 가져와서 비교 후 값이 일치하면 True를 다르면 False를 Push하게 된다.

위와 같은 과정으로 Script언어가 동작하게 된다.

 

Pay-to-Public-Key-Hash (P2PKH)

비트코인 거래에서 가장 많은 부분을 차지하는 거래 방법은 P2PKH script를 사용하는  방법이다. 이 방법의 Output은 비트코인 주소로 알려져있는 Public key의 Hash로 Lock이 걸려 있다. 이 Output을 Unlock하기 위해서는 Public Key와 함께 Private key로 만든 Digital Signature를 제시해야 한다. 

Evaluating a script for a P2PKH transaction (part 1 of 2)

위의 과정은 실제 비트코인 네트워크에서 일반적인 P2PKH 방식의 Script로 구성된 Transaction을 검증하는 방법이다. 위의 Script 순서는 앞 서 보았다시피 Unlocking script + Locking script로 되어 있음을 알 수 있다. 위의 세 과정을 살펴보면, Sig와 Pubk를 넣고 DUP 명령으로 Stack의 가장 위에 있는 아이템을 한 번 복사하여 다시 PUSH하는 과정을 거친다.

Evaluating a script for a P2PKH transaction (part 2 of 2)

HASH160 명령을 통해서 가장 위에 있는 PubK를 Hashing한다. 이 과정을 거치면 PubK는 PubKHash가 된다. 그리고 또 다시 PubKHash를 넣고 EQUALVERIFY 명령으로 둘의 값을 비교한다. 그 다음에 CHECKSIG를 사용하여 Locking Script가 가지고 있는 Signature가 PubK와 관련이 있는지를 확인하고 확인이 되면 True를 다시 Push한다.

 

Digital Signature (ECDSA)

위의 과정을 살펴보면, 결국 핵심은 Unlocking Script에 있는 PubK를 이용하여 Locking Script 내 에 있는 PubKHash와 일치 여부를 확인하고 이것이 확인이 될 경우에 Locking Script 내의 Signature와 PubK의 관계를 체크하는 것을 알 수 있다. 여기서 Signature는 대체 무엇인지 궁금할 것 이다.

 Bitcoin에서 사용하는 Signature Algorithm은 Elliptic Curve Digital Signature Algorithm이다. 흔히 ECDSA라고 이야기하는 것이다. 이러한 알고리즘을 사용하는 이유는 다음과 같다. 

The signature proves that the owner of the private key, who is by implication the owner of the funds, has authorized the spending of those funds
The proof of authorization is undeniable (nonrepudiation).
The signature proves that the transaction have not and cannot be modified by anyone after it has been signed.

 

ECDSA는 사실 암호학에서 다루는 내용이다. 이에 대한 내용을 다루는 것도 상당한 분량을 요구하는데 이 부분은 추후에 다른 포스팅에서 다루도록 하겠다.

 

6장까지 정리해보았다. 아마 내 포스팅을 보는 분들 중 실제로 컴퓨터 공학을 전공하지 않았다면, 이해하기 어려운 부분이 많이 있을 것이라 예상된다. 필자도 실제로 비트코인을 공부해보기 전에는 수학적 내용이 이렇게 많이 들어 있을 줄은 전혀 예상하지 못했다. 어쨌든 정리를 해가면서 추가로 필요한 내용들은 차츰 보충하도록 하겠다.

제주 삼다수, 2L, 12개

파트너스 활동을 통해 일정액의 수수료를 제공받을 수 있음

728x90
반응형
Comments