• 본 게시글은 K-MOOC 묶음강좌 '블록체인 암호화폐:입문부터 심화까지' 강의를 수강하고 공부하며 정리한 내용입니다.
해시함수는 블록체인의 암호화를 위해 사용되는 함수입니다.
해시포인터는 정보가 저장된 곳을 가리키는 일종의 포인터로 마지막으로 기억하는 데이터의 해시값(자료구조)을 의미합니다. 원하는 정보를 다시 요청하거나 해시가 가리키고 있는 데이터가 변경되었는지(데이터의 위변조) 검증하는 데 사용할 수 있습니다. 이전 블록을 가리키는 해시 포인터를 가지고 있는 블록들이 링크드 리스트로 연결된 구조이고 이전 블록의 데이터가 변경되면 해시 포인터 또한 변경되므로 리스트 내의 데이터 변조를 감지할 수 있습니다.
대칭키 알고리즘은 데이터를 암호화, 복호화할 때 하나의 같은 키만을 사용하여 데이터를 변환하는 알고리즘으로, 비대칭키 알고리즘보다 계산 속도가 빠르다는 장점을 가지고 있습니다.
예시: 트리플데스(3DES), AES
비대칭키 알고리즘은 서로 다른 두 개의 키인 공개키(public key)와 개인 키(private key)를 이용합니다. 이 때 공개키는 공개적으로 알려져있는 키로 누구나 얻을 수 있고, 개인키는 개인 혼자만 소유하는 키로, 누구에게도 공유하지 않습니다.
공개키 암호화 방식은 공개키를 이용하여 데이터를 암호화하고, 개인키를 이용하여 원본 데이터로 복원하는 방식을 이야기 합니다.
전자서명은 특정 사용자가 문서를 보냈다는 것을 증명, 또는 검증하기 위한 시스템입니다. 전자서명을 위해 개인 키로 암호화된 문서를 제공하여 공개키로 이 문서를 복호화해서 풀리면, 전달받은 데이터가 해당 사용자가 보낸 문서임을 증명할 수 있습니다.
예시: RSA
블록체인 네트워크 상에서 거래 발생시, 거래를 검증하기 위해서 디지털 서명 기술이 사용됩니다. 전자 서명은 다음과 같은 보안 요구사항을 충족해야 합니다.
디지털 서명은 다음과 같은 과정을 거쳐 진행됩니다.
디지털 서명의 과정은 원본데이터가 아닌 메시지를 해시한 해시값과 서명자의 개인키를 이용해서 서명을 생성한다는 것이 핵심입니다. 원본데이터의 크기가 클 경우 서명하는데에 시간이 오래 걸리고 정보의 양이 많아지게 되므로 메시지의 길이를 줄이기 위해 해시함수를 사용합니다. 또한, 해시함수를 사용하면 메시지의 무결성을 보장할 수 있습니다.
비트코인은 2008년 가을 익명의 개발자 또는 단체인 사토시 나카모토에 의해 개발된 최초의 암호화폐 기반의 디지털 지불 시스템입니다. 블록체인이라는 분산 장부 기술이 사용되었습니다.
블록은 블록체인에 거래를 포함시키기 위해, 하나에 합쳐놓은 컨테이너 데이터구조입니다. 메타 데이터를 담고 있는 블록 헤더와 트랜잭션들을 담고 있는 블록 바디로 이루어져 있습니다. 비트코인을 기준으로 블록헤더는 80바이트, 블록바디는 최소 250바이트의 용량을 가지고 있습니다. 블록은 블록체인에서 데이터가 갱신되는 한 주기 또는 최소 단위로, 트랜잭션 단위로 장부가 업데이트 되는 것이 아닌 블록 단위로 업데이트 되어 블록에 포함된 트랜잭션들이 블록체인에 한번에 저장됩니다.
블록 해시는 비트코인에서 블록의 주요 식별자로 블록의 고유한 값입니다. 한 블록의 암호화 해시로 블록을 식별할 수 있고, 해시함수의 입력값으로 블록의 전체값이 아닌 헤더가 들어가 블록 헤더 해시라고도 할 수 있습니다. 다음 블록의 previous hash값으로 포함되어 블록들이 체인처럼 연결될 수 있도록 하는 역할을 합니다. 어떤 블록이 수정되면 해시값이 바뀌어, 이후로 연결된 모든 블록의 previous hash, block hash가 달라져 블록체인에 비가역성을 부여합니다.
비트코인에서 블록 해시는 블록헤더에 SHA-256 function을 두번 적용시켜서 나온 결과를 사용, 32byte의 길이를 가집니다.
Merkle root는 블록 바디에 들어있는 모든 거래 내용의 축약본이고, 만약 블록안의 거래가 수정되면 Merkle root도 변하여 블록 헤더의 해시값도 변하게 됩니다. 따라서 블록헤더만으로 해시값을 만들어도 블록 전체가 변경되지 않았다는 것을 보장할 수 있습니다.
블록의 높이는 최초 0부터 시작하여 블록이 생성될때마다 1씩 증가합니다. 인덱스로 활용되며, 블록체인에서 블록의 위치를 나타내는 중요한 지표입니다. 블록체인의 분기(Fork)가 발생하였을 때, 동일한 두개의 블록이 같은 블록의 높이를 가질 수 있는데 높이로는 블록을 식별할 수 없습니다. 이러한 경우에 블록체인에 연결되는 블록은 두개의 동일한 높이의 블록 중 하나만 포함됩니다.
비트코인(블록체인)의 첫번째 블록을 제네시스 블록이라고 하며, 사토시 나카모토가 비트코인을 개발하여 처음 블록을 생성시킨 2009년에 만들어졌습니다. 블록체인 내의 모든 블록들의 공통 선조가 되며, 비트코인 코어 등의 클라이언트 소프트웨어들 안에 고정적으로 인코딩되어 있습니다. 블록체인을 시작하는 어떠한 노드들은 적어도 하나의 제네시스 블록을 가지고 시작하고 이것은 변경될 수 없습니다. blockchain.info로 접속하여 비트코인의 genesis block과 일반 블록의 구조를 볼 수 있습니다. 노드들은 전체 블록체인 복사본을 각자 유지합니다.
머클트리는 이진 해시트리라고도 하며, 규모가 큰 데이터 집합의 완전성을 효율적으로 요약하고 검증하는데 사용되는 데이터 구조입니다. 비트코인 내에 있는 블록 각각은 머클 트리를 이용하여 해당 블록에 들어있는 모든 거래의 요약본인 머클 루트(Merkle Root)를 가지고 이것을 블록 헤더 내에 포함하고 있습니다. 머클트리를 구성하기 위해서는 리프가 짝수여야하고, 따라서 거래가 홀수일 경우에는 마지막 거래를 복사하여 마지막 리프에 위치시킵니다. 머클 루트 해시 하나가 남을 때까지 노드쌍을 반복적으로 해싱하여 머클트리를 만듭니다.
트랜잭션(거래)는 비트코인 시스템에서 가장 중요한 요소이며, 비트코인 시스템 내에 있는 참가자들 간 입력값(자금원)으로부터 출력값(목적지)까지 가치의 전송을 인코딩하는 데이터 구조입니다. 각 거래는 전 세계적인 장부에 들어있는 공개된 항목입니다.
비트코인의 잔액은 계정에 그만큼의 잔액이 저장된 것이 아닌 블록체인에 흩어져서 산재해있는 소비되지 않은 거래 출력(UTXO)만 있고, 이것이 특정한 소유자들에게 잠겨있는 것입니다.
Data Output을 제외한 거의 모든 출력값은 소비가능한 비트코인 덩어리를 만들고 이것을 UTXO라고 부릅니다.
거래 출력값의 구조
블록체인에 저장되어 있는 하나의 특정한 UTXO를 의미합니다.
거래 입력값의 구조
거래 입력값과 거래 출력값의 차액을 말합니다. 블록을 채굴하는 마이너들이 가저가게 되고, 이는 스팸같은 악영향을 미치는 노드를 방지하는 역할을 할 수 있습니다. 거래를 만드는 대상이 정할 수 있고, 금액에 비례한 결정이 아닌 거래의 크기를 기반으로 계산해야합니다. 마이너들은 수수료가 높은 거래가 포함된 블록을 먼저 채굴하게 되기 때문에 수수료가 높은 거래가 블록에 포함될 확률이 높습니다.
Base앞에 coin이 들어가야 하나, 거래소 레퍼럴 문제인지 글이 비공개 처리되어 베이스 거래로 칭하겠습니다.
모든 블록에서 처음으로 추가되는 거래를 베이스 거래라고 합니다. 코인베이스 거래는 Input 값으로 UTXO를 소모하지 않는 거래이며, base라는 하나의 입력을 갖는데 아무것도 아닌 것으로부터 비트코인이 만들어집니다. 마지막으로 하나의 출력값을 갖는데, 해당 블록을 채굴한 마이너의 비트코인 주소로 일정 금액이 전달됩니다. base 또한 마이너에게 주어지는 보상입니다.
비트 코인의 거래 검증 엔진은 거래를 검증하기 위한 두 가지 스크립트(잠금/해제)로 이루어져 있습니다. UTXO에 위치한 잠금 스크립트와 서명이 포함된 해제 스크립트 모두 Forth-like scripting language로 작성되었습니다. 하나의 거래가 검증될 때, 각 입력값의 잠금 스크립트들은 지출 조건을 만족하는지 아닌지 확인하기 위해 대응되는 해제 스크립트와 함께 실행됩니다.
하나의 출력에 위치한 예상 지출이고, 미래에 출력값을 소비하기 위해 만족해야하는 조건들을 명시합니다. 보통 비트코인의 주소 혹은 공개키를 포함하기 때문에 scriptPubKey로 불립니다.
잠금 스크립트에 의해서 출력 값에 위치한 조건들을 만족시키는 스크립트입니다. 조건을 만족시킴으로써 소유권을 인정받고, 출력값을 소비할 수 있도록 허가 받습니다. 모든 거래 입력 값의 부분에 포함되어 있고, 대체로 사용자 지갑에 저장되어 있는 개인 키로부터 생성된 전자서명을 포함하고 있습니다. 전자서명을 포함하고 있어 scriptSig로 불립니다.
Forth언어처럼 구성되고 역 폴란드식 표기법을 따르며 데이터 구조인 스택을 사용하는 스택 기반의 언어입니다. 범위가 한정되도록 고안된 매우 단순하고 가벼운 언어이고, 다양한 하드웨어에서 실행 가능합니다. 왼쪽에서 오른쪽으로 각 명령어를 처리하며 스크립트가 실행됩니다.
실행이 의도적으로 한방향으로만 제한되어 루프가 없고 복잡한 흐름 제어 기능들이 없어 튜링 불완전함을 보장하고 무한루프나 DoS공격 등 논리폭탄을 만들지 않음을 보장합니다.
스크립트 실행전이나 스크립트 실행 후에 저장되는 상태가 없어 모든 정보가 해당 스크립트 안에 포함되어 있어 어떤 시스템에서도 예측가능하고 동일한 방식으로 실행됩니다.
비트코인 개발자들은 비트코인 코어 클라이언트에 의해 처리될 수 있는 스크립트의 유형에 제한을 도입했습니다.
비트코인의 거래에는 블록 상의 장부에 기록되기 위해 유효한 서명이 필요합니다. 서명은 디지털 키가 있어야 생성 가능하고, 디지털 키의 복사본만 있으면 해당 계좌에서 비트코인을 관리할 수 있습니다. 키는 개인키(비밀번호,PIN 번호와 같음)와 공개키(계좌번호와 같음)로 구성되어있습니다.
공개키 암호법을 사용해 한쌍의 키를 생성하고, 이 과정에 사용하는 암호함수들은 불가역성을 가져 역방향으로 계산하는 것이 거의 불가능합니다. 개인키는 무작위 숫자 추출을 통해 생성하고, 개인키로부터 타원곡선 암호법을 이용하여 공개키를 생성합니다. 이 공개키로부터 비트코인의 주소를 생성합니다.
개인키는 1~2^256 사이의 무작위 숫자를 선택하여 생성합니다. 재현할 수 없도록 보안이 철저한 무작위성을 가진 난수생성기(프로그래밍 언어에서 제공하는 것이 아닌)를 사용합니다. 생성된 난수를 Base58Check를 통해 인코딩하면 지갑에서 볼 수 있는 형태의 개인키를 생성할 수 있습니다.
Base58
텍스트 기반 2진법 인코딩 포맷으로 여러 암호화폐에서 사용하기 위해 개발되었습니다. Base64에서 자주 실수가 발생하거나 특정 글자체에서 동일하게 보일 가능성이 있는 몇몇 문자들을 제외한 58개의 문자를 이용합니다.
Base 58Check의 Checksum은 중복 검사를 위한 4바이트의 필드로 인코딩 되고 있는 데이터의 끝부분에 추가되는데, 이것을 이용하여 지갑 소프트웨어가 잘못 입력된 비트코인 주소를 유효한 도착지로 승인하는 것을 방지할 수 있습니다.
공개키는 개인키에 타원곡선 암호법(Elliptic Curve Cryptography)을 적용해 생성합니다.
타원곡선 암호법(Elliptic Curve Cryptography)은 무작위 숫자인 개인키를 출발점으로 곡선 위에서 미리 정해진 값인 생성포인트 G를 곱하여 곡선상의 다른 곳에 위치한 포인트를 얻음으로써 공개키를 생성합니다. 이때 생성포인트는 모든 비트코인 사용자들이 모두 동일하므로 개인키 k에 G를 곱하게 되면 공개키 K를 얻을 수 있습니다. (K=k*G)
비트코인 주소는 공개키로부터 생성되고, 숫자1로 시작하며 숫자와 문자의 조합으로 이루어져 있습니다. 공개키를 표현하는 수단이자, 공개키에서 일방 암호화 해싱을 사용하여 생성된 결과물입니다. 공개키로부터 비트코인 주소를 만들기 위해 보안해시알고리즘(SHA)과 RIPEMD 알고리즘을 사용합니다.
비트코인 주소를 생성하는 과정은 다음과 같습니다.
비트코인 주소의 생성과정
공개키 K를 SHA256으로 해싱 → 256bit의 해시값 → 해시값을 RIPEMD160으로 해싱 → 160bit의 숫자
공개키와 비트코인 주소는 동일하지 않습니다. 비트코인 주소는 Base58check 인코딩을 통해 사용자가 읽을 수 잇는 형태로 전환되어 제공되고, 디지털 키는 지갑에 저장됩니다.
지갑은 개인키 및 공개키를 저장하고 다양한 블록과 상호작용하여 사용자가 암호화폐를 보내고 받을 수 있도록하는 소프트웨어를 말합니다.
지갑은 다음과 같은 기능을 기본적으로 제공합니다.
비트코인 P2P 프로토콜을 실행하는 노드의 집합을 의미합니다. 비트코인 네트워크는 인터넷 상 P2P 네트워크 아키텍처 구조로 이루어져 있습니다. 모든 노드가 동등한 지위를 가지고, 모든 노드가 네트워크 서비스를 공급하는 역할을 분담합니다.
P2P protocol+Pool mining protocol+Stratum protocol+Bitcoin System으로 구성된 네트워크를 확장 비트코인 네트워크라고 합니다.
비트코인의 노드는 모두 동등한 지위를 가졌지만 지갑 서비스, 채굴, 데이터베이스, 라우팅 등의 기능을 하며 기능에 따라 각각의 역할이 다릅니다. 모든 노드는 네트워크 내에 라우팅의 기능을 가집니다.
라우팅
거래와 블록을 검증하고 전파하며 이웃노드들과의 연결을 유지하는 기능
모든 기능을 보유한 노드를 full 노드라고 부르고, 풀노드는 항상 가장 최신의 블록체인 복사본을 가지고 있으며 외부 참조 없이 모든 거래를 검증할 수 있습니다. 이웃 노드들에 연결하기 위해 노드는 일반적으로 8333번 포트로 TCP 커넥션을 연결합니다.
블룸필터는 확률적 검색 필터로서 원하는 패턴이 무엇인지 정확하게 규정할 필요없이 원하는 패턴을 설명하는 방식의 필터입니다. Wallet을 synchronize하는데 유용하게 사용됩니다. 확률로서 프라이버시를 보호하면서 검색 패턴을 표현하기 위한 효율적인 방법을 제공합니다.
채굴은 새로운 블록과 비트코인이 블록체인 네트워크 상에 추가되는 과정을 말합니다. 블록체인 네트워크 상에서 암호화 해시 알고리즘 기반의 문제를 다른 노드들보다 빠르게 해결하여 블록을 생성할 권한을 얻기 위해 각 노드들이 경쟁하는데, 이 문제에 대한 답을 찾는 과정을 작업증명(Proof of Work)이라고 합니다.
마이닝(채굴)을 위해 컴퓨팅 파워를 제공하면 새 블록으로부터 새로운 코인을 생성하거나, 블록 내의 거래에 대한 수수료를 보상으로 받을 수 있습니다.
Mining Node는 비트코인 네트워크 상에 있는 미승인 거래를 전송받아 다른 노드들에게 전파하는 노드를 말합니다. 미승인 거래들을 새로운 블록에 추가하는 역할을 합니다.
마이닝 풀은 개인 채굴자들이 다른 사람과 함께 마이닝하여 채굴 확률을 높이도록 한 것입니다. 개개인의 컴퓨팅 파워를 인터넷을 통해 모아 채굴 확률을 높이고 투자된 지분만큼 수익을 배분받습니다.
마이닝 풀을 이용하여 채굴하는 과정
1. 얻고자하는 암호화폐 선택하고 마이닝 풀을 찾음
2. 마이닝 풀별로 보상금 분배 기준이 다르므로 이익이 극대화되는 유리한 풀을 선택
3. 선택한 풀의 웹사이트에 계정을 만들고 채굴 시작
거래를 검증하기 위한 조건
1) 트랜잭션 구문과 데이터 구조가 정확해야 함
2) 코인 베이스 거래는 전송할 수 없음
3) 각각의 입력값에 대해 참조 출력값이 풀 내의 어떠한 거래 내부에 이미 존재한다면 해당 거래는 거부되어야 함
4) 짝을 이루는 거래가 풀에 존재하지 않는 경우 고아 거래 풀 추가
5) 각각의 입력값에 대해 참조 출력값은 존재해야 하며, 해당 UTXO가 이미 소비된 상태가 아니어야함
6) 입력값 금액이 출력값 총액보다 작은 경우 해당 거래 거절
7) 새로운 블록에 포함되기에 거래 수수료가 너무 작은 경우 해당 거래 거절 가능
채굴된 블록이 유효한지 검증하기 위한 조건
1) 블록의 데이터 구조는 문법적으로 유효해야 함
2) 블록 헤더의 해시값은 사전에 정의된 목표 난이도보다 작아야 함
3) 해당 블록의 타임스탬프는 향후 2시간 이내
4) 해당 블록의 크기가 허용가능한 한도내에 있어야 함
5) 블록 내에 포함되는 제일 첫 거래는 코인베이스 생성거래임