SW/블록체인

블록체인 : 트랜잭션 수수료, 트랜잭션의 입력/출력, 비트코인 스크립트 : 개념, 원리, 이해

얇은생각 2022. 1. 25. 07:30
반응형

거래의 요소

차액은 해당 거래가 포함된 블록을 채굴한 마이너가 가져갑니다. 그래서 이 수수료는 거래를 다음 블록에 포함시키기 위한 장려금으로 사용되고, 해당 블록을 채굴하는 마이너는 거래의 수수료들을 수집하게 되는 것입니다. 뿐만 아니라, 수수료는 스팸 같은 블록체인 네트워크에 악영향을 미치는 노드들의 의욕을 꺾는 역할로 사용됩니다.

왜냐하면 스팸이나 DDoS를 하기 위해서 거래를 생성해야 하는데 이때 수수료가 발생하면 금전적인 문제 때문에 공격을 못 하기 때문입니다. 수수료는 앞서 말씀드린 대로 input들의 sum과 output들의 sum을 계산해서, 총 input에서 총 output을 빼면 남는 것이 수수료가 됩니다.

수수료는 거래를 만드는 대상이 정할 수 있는데, 수수료를 책정할 때는 금액에 비례해서 결정하는 것이 아니라, 거래의 크기를 기반으로 계산해야 합니다. 마이너 입장에서는 이게 1 비트코인을 전달하는 것인지 10 비트코인을 전달하는 것인지는 중요한 것이 아니라 이것이 얼마만큼의 데이터 크기 인지가 중요하기 때문입니다.

그만큼 시간이 많이 걸리기 때문입니다. 수수료가 마이너들에게 장려금이기 때문에, 이것은 마이너가 거래들을 블록에 포함 시킬 때 우선순위를 결정하는 요소로 사용됩니다. 따라서 수수료를 많이 줄수록, 거래가 블록에 빨리 포함될 확률이 높아집니다. 다만, 수수료는 의무사항이 아니며, 수수료가 없는 거래들도 시간이 지날수록 우선순위가 높아져서 언젠가는 블록에 포함될 수 있습니다. 만약 잔액을 내 주소로 다시 보내지 않는다면, 남은 금액은 수수료로서 마이너가 가져가기 때문에, 거래를 생성할 때 매우 신중해야 합니다.

 

 

코인 베이스

다음은 특별한 거래인 coinbase에 대해서 설명하겠습니다. Coinbase 거래는 모든 블록에서 처음으로 추가되는 거래입니다. 그래서 이것은 generation transaction으로 불리기도 합니다. Coinbas는 Input 값으로 UTXO를 소모하지 않는 거래입니다. 또한, coinbase라는 하나의 입력을 갖는데, 아무것도 아닌 것으로부터 비트코인이 만들어집니다.

마지막으로 하나의 출력값을 갖는데, 해당 블록을 채굴한 마이너의 비트코인 주소로 일정 금액이 전달됩니다. 이 coinbase 또한 마이너가 비트코인 네트워크를 운영하는 데 있어서 자신의 자원을 소모한 데 있어서 노력을 인정해서 주는 보상입니다.

 

 

비트코인 스크립트

거래의 입력 값과 출력 값을 설명할 때 잠금/해제 스크립트를 언급했습니다. 그 비트코인의 스크립트에 대해 설명하겠습니다. 비트코인의 거래 검증 엔진은 거래를 검증하기 위한 두 가지 스크립트(잠금/해제 스크립트)에 의존하며, 비트코인 클라이언트들은 이 스크립트를 실행해서 거래들을 검증합니다. UTXO에 위치한 잠금 스크립트와 서명이 포함되어있는 해제스크립트 모두 Forth-like scripting language로 작성됩니다.

하나의 거래가 검증될 때, 각 입력 값에 있는 잠금 스크립트들은 지출 조건을 만족하는지 아닌지 확인하기 위해서 대응되는 해제 스크립트와 함께 실행됩니다. 잠금 스크립트는 하나의 출력에 위치한 예상 지출이고, 이것은 미래에 출력값을 소비하기 위해서 만족해야 하는 조건들을 명시합니다.

추가적으로, 잠금 스크립트가 보통 비트코인 주소 혹은 공개키를 포함하기 때문에, 잠금 스크립트는 scriptPubKey 로 불립니다. 해제 스크립트는 잠금 스크립트에 의해서 출력 값에 위치한 조건들을 만족시키는 스크립트입니다. 조건을 만족시킴으로써 소유권을 인정받고, 출력 값을 소비할 수 있도록 허가 받는다고 생각할 수 있습니다.

해제 스크립트는 모든 거래 입력 값의 부분에 포함되어 있고, 대체로 사용자 지갑에 저장되어 있는 개인 키로부터 생성된 전자서명을 포함하고 있습니다. 추가로, 해제 스크립트는 전자 서명을 포함하고 있기 때문에, 해제 스크립트는 scriptSig으로 불립니다.

 

 

비트코인 스크립트 언어

비트코인 거래 스크립트 언어는 Forth 언어처럼 구성되고 역 폴란드식 표기법을 따르는 스택 기반의 실행 언어입니다. 이 스크립트 언어는 스택이라고 불리는 데이터 구조를 사용하기 때문에 스택 기반의 언어라고 합니다. 또한, 스크립트는 범위가 한정되도록 고안된 매우 단순하고 가벼운 언어이고, 다양한 하드웨어에서 실행이 가능합니다.

그리고 왼쪽에서 오른쪽으로 각 명령을 처리하며 스크립트가 실행됩니다. 비트코인 스크립트언어는 실행이 의도적으로 한 방향으로만 제한되어 루프가 없고 복잡한 흐림 제어 기능들이 없습니다. 따라서 이것은 스크립트 언어가 튜링 불완전함을 보장하고 해당 언어가 무한 루프나 DoS 공격과 같이 비트코인 네트워크에 해를 유발시키는 논리 폭탄을 만들지 않는다는 것을 보장합니다.

또한, 제한된 언어는 거래 검증 메커니즘이 취약점으로써 사용되는 것을 예방합니다. 또한, 비트코인 스크립트 언어는 상태가 없습니다. 즉, 스크립트의 실행 전이나 스크립트의 실행 후에 저장되는 상태가 없다는 것을 의미합니다. 그래서 스크립트를 실행하기 위해 필요한 모든 정보가 해당 스크립트 안에 포함되어 있습니다.

이것은 스크립트가 어떠한 시스템에서도 예측 가능하며 동일한 방식으로 실행됨을 의미합니다. 이러한 특징 때문에, 만약 하나의 시스템이 어떤 스크립트를 유효화한다면 비트코인 네트워크에 존재하는 시스템 전체가 해당 스크립트를 유효화할 것이라 확신할 수 있고, 이렇게 결과에 대한 예측 가능성이 비트코인 시스템의 핵심 이점입니다.

비트코인에 존재하는 표준 거래 유형을 알아보고, 가장 많이 사용되는 거래 유형의 스크립트 검증 예시를 설명하겠습니다. 비트코인 개발자들은 비트코인 코어(Core) 클라이언트에 의해서 처리될 수 있는 스크립트의 유형에 대해서 제한을 도입했습니다. 총 다섯 가지의 표준 거래 타입을 만들고 비트코인 코어 클라이언트와 그 클라이언트를 사용하는 마이너들에 의해서 받아들여지는 거래의 타입을 제한했습니다.

 

 

거래 유형

먼저 Pay-to-Public-Key-Hash입니다. 비트코인 네트워크에서 처리되는 대다수의 거래들이 바로 이 Pay-to-Public-Key-Hash이며, P2PKH 거래로 알려졌습니다. 이 거래들은 비트코인 주소로 알려져 있는 공개키 해시를 이용해 출력 값에 대한 예상 지출을 실행하는 잠금 스크립트가 포함되어 있습니다.

비트코인 주소에 지불하는 거래에는 P2PKH 스크립트가 포함되어 있고, P2PKH 스크립트로 잠겨있는 출력 값은 공개키와 공개키에 대응하는 개인 키가 생성한 디지털 서명을 사용해야만 해제가 가능합니다.

다음은 Pay-to-Public-Key입니다. Pay-to-Public-Key는 Pay-to-Public-Key-Hash보다 좀 단순한 비트코인 지불 방식입니다. 그리고 Pay-to-Public-Key는 공개키가 잠금 스크립트 내에 자체적으로 저장되어 길이가 훨씬 짧아지게 되며, 현재 Pay-to-Public-Key는 코인베이스 거래에서 보입니다.

Multi-signature(다중 서명)는 N개의 공개키가 스크립트 내에 기록되어 있고, 예상 지출 상태를 풀기 위해서는 이 중에서 적어도 M개 이상의 개인 키로부터 생성된 서명을 제공해야 한다는 조건을 설정합니다. M-of-N 제도로도 알려져 있는 다중 서명은 N이 키의 총 개수이고, M은 유효화를 위해 필요한 서명의 기준 개수입니다. Pay-to-Script-Hash(P2SH)는 다중 서명의 문제를 해결하기 위해서 나왔습니다.

다중 서명 스크립트가 효과적이기는 하지만 사용하기가 번거롭습니다. 다중 서명 스크립트에 지불하는 고객에게 하나하나 다 설명을 해야 하기 때문입니다. 또한, 결과값으로 나온 거래의 크기가 단순한 지불 거래보다 큽니다. 이는 구매 거래 스크립트가 여러 개의 공개키를 가지고 있어서 공개키가 길어지기 때문인데, 이렇게 스크립트가 길어지면 거래데이터의 크기가 고객에게 수수료 부담을 주게 될 것입니다.

추가적으로, 구매 거래 스크립트 같은 대규모 거래 스크립트는 소비될 때까지 모든 full node의 RAM 속에 있는 UTXO세트에 보관될 것인데, RAM 자원 사용의 팽창을 야기 시킵니다. 이러한 문제들 때문에 실제 사용을 어렵게 하는데, Pay-to-Script-Hash는 지불에 대해서 복잡한 잠금 스크립트를 암호 해시로 대체함으로써, 앞서 언급한 문제들을 해결하고 비트코인 주소에 지불하는 것만큼 쉽게 복잡한 스크립트를 사용할 수 있도록 하기 위해서 개발되었습니다.

마지막으로 Data Output은 비트코인 지불과 관련이 없는 데이터를 저장하기 위해서 블록체인을 사용하는 것을 의미합니다. 가장 많이 사용되는 거래 유형인 Pay-to-Public-Key-Hash transaction을 위한 스크립트를 검증하는 것을 단계적으로 설명하겠습니다.

이 예제의 상황은 이렇습니다. B가 A에게 비트코인을 보내는 것입니다. 그러면 해당 거래에 출력 값에 A의 공개키 해시로 예상 지출이 잠겼을 것입니다. 이후에 A가 C에게 비트코인을 보낼 때 해당 이전에 B가 보내줬던 출력 값을 C로 보내는 거래의 입력 값으로 사용하고 싶은 상황입니다. 이때 더 이전 거래에서 이전 거래의 출력 값에 있는 잠금 스크립트와 현재 거래에서 입력 값에 포함한 해제 스크립트를 결합한 복합스크립트를 만들어서 검증을 해야 합니다.

 

블록체인 : 트랜잭션 수수료, 트랜잭션의 입력/출력, 비트코인 스크립트 : 개념, 원리, 이해 1

 

그림은 현재 복합 스크립트가 만들어진 상황입니다. 왼쪽의 빨간 박스 안에는 해제스크립트가 있고, 오른쪽의 빨간 박스 안에는 잠금 스크립트가 있습니다. 이제 단계별로 진행하도록 하겠습니다. 왼쪽부터 오른쪽으로 실행되기 때문에, 처음에는 [sig] 라는 서명이 스택에 푸시 됩니다. 그 다음 [PubK]라는 공개키가 스택에 푸시 됩니다.

앞의 예시와 연관해서 생각해본다면 A의 서명과 공개키가 차례로 스택에 푸시 되었다고 생각할 수 있습니다. 그 다음 DUP은 스택의 맨 위에 있는 것은 복사해서 스택 맨 위에 푸시를 하라는 것입니다. 따라서 [PubK]가 복사되고 스택 위로 푸시 됩니다. 그 다음 HASH 160을 실행해서 스택 맨 위에 있었던 [PubK]의 해시가 스택의 맨 위에 저장됩니다.

그 다음 잠금 스크립트 안에 있던 [PubKHash]가 스택에 푸시 됩니다. 이것은 앞의 예시와 연관 지으면 A의 공개키 해시가 스택에 푸시 된 것입니다. 그 다음 EQUALVERIFY를 실행을 하여 스택 맨 위에 있는 두 개의 값을 비교해서 만약 같으면 두 개를 스택에서 제거합니다. 예시와 연관해서 생각해보면, 둘 다 A의 공개키 해시 값이기 때문에 스택에서 둘 다 해제됩니다. 다음은 CHECKSIG를 실행하면 [sig] 와 [PubK]가 매치가 되는지 확인하고 맞으면 true를 스택의 꼭대기에 푸시합니다.

예시와 연관해서 생각해보면, 앞에서 A의 서명과 공개키를 푸시했기 때문에, 두 개의 값의 매치가 되며 true를 스택에 푸시할 것입니다. 이렇게 스크립트의 검증은 끝나고, 결과가 true이기 때문에 성공적으로 검증을 마쳤고 해당 예상 지출은 입력으로 사용될 것입니다. 여기까지 비트코인에서 거래의 요소로는 뭐가 있고, 거래는 어떻게 처리되는지에 대해서 설명 드렸습니다. 거래를 위해서는 어떠한 대상에게 보내는 것인지 기록해야 하기 때문에 대체로는 대상을 식별하는 비트코인 주소를 필요로 합니다.

 

 

 

참조

http://www.kmooc.kr/courses/course-v1:POSTECHk+CSED490U1+2021_T1/about 

 

블록체인 입문

블록체인과 암호화폐 기술을 깊이 배우기에 앞서, 비 전공자들도 이해를 할 수 있는 수준으로 블록체인과 암화화폐에 대한 high-level 설명 및 응용 예시를 제공하고 실제 상황에 적용할 수 있다.

www.kmooc.kr

반응형