Blockchain - bitcoin
Bitcoin
1. 개요
이전 blockchain의 개요 포스팅에서 언급했듯이 2008년 세계 금융 위기로 인해 생겨난 개개인간의 전자 결제 시스템이다.
사토시 나카모토(높은 확률로 가명이다)라는 사람이 백서(Bitcone : A Peer-to-peer Electronic Cash System)를 발표함에 따라 시작되었으며
blockchain 기술의 모태가 되었다. 사이퍼펑크(사이버 펑크가 아니다) 즉, 사회적, 정치적 변화의 방법으로 강력한 암호 기술과 프라이버시 강화 기술의 광범위한 사용을 옹호하는 이들의 사상에서 시작되었다고 봐도 무방할 듯 하다.
소위 말해서 이러한 blockchain 기술은 탈 중앙화가 가장 주요한 내용이다. 중앙화가 되어있다는 것은 내가 어떤 작업이나 결제를 했을 때 요청할 곳이 정해져있다는 뜻이다. 하지만 탈 중앙화라면 그런 요청할 곳이 정해지지 않았다는 뜻인데, 그렇다면 어떻게 결제와 작업에 대해서 보증하고 보관할 수 있을까?
이를 컴퓨터 공학적인 관점에서 알아보겠다.
2. 비트코인에서 사용되는 주요 암호 개념
기본적으로 암호화폐라는 것은 말 그대로 암호를 사용했기 때문에 암호화폐라고 불리는 것이다. 때문에 암호에 대해서 약간의 이해는 있어야 이후 서술할 내용에 대해서 어느정도 이해 할 수 있을 것이다.
1) SHA256
암호학을 배웠다면 이름은 들어봤을 함수이다. 미국 국가 안보국(NAS) 설계한 암호이며, 어떤 값을 넣으면 그에 따른 고정된 크기의 무작위값이 나타나는 함수이다. 입력값의 크기가 달라도 실제로 처리될때는 해당 입력 값의 크기를 일정 크기로 맞춰서 처리하며, 출력값은 256bit이다. (때문에 sha512는 출력 값이 512bit이다) 약간의 값이라도 달라진다면 결과값 역시 완전 달라지기 때문에(이를 눈사태 효과라고 한다) 어떤 데이터가 변조되었는지 확인하기에 용이하여 데이터 무결성을 판단하는데 사용한다.
2) 공개키 암호화
비대칭 암호 방식이라고도 불리며 전자서명시 많이 사용한다. 비밀키와 공개키로 이루어져있으며 비밀키로 암호화시 공개키로 복호화가능하고 공개키로 암호화시 비밀키로 복호화 가능하다. 비트코인에서는 타원곡선 디지털 서명 알고리즘(ECDSA)를 사용한다.
3. 전체적인 구조
1) bitcoin node
이 bitcoin에 대해서 이해하기 위해서는 먼저 bitcoin node라는 것을 알아야한다. 내가 이 bitcoin에 대해서 가장 의문스러웠던게 바로 이 탈중앙화 부분이었다. 결제를 하건 송금을 하건 요청을 할 텐데, 이 요청을 받는곳은 대체 어디인가 하는 것이다. 이때 이 요청을 받는 주체가 바로 bitcoin node(이하 노드)이다.
bitcoin에서 설명하는 명세를 지키는 프로그램이라면 뭐든 노드로 사용할 수 있다. 하지만 bitcoin 공식 사이트에서 코어라는 이름으로 배포하며 이러한 코어가 현재 점유율이 가장 높다. 설치하면 누구든 운영가능하며 요청 수용의 주체이다. 물론 bitcoin 커뮤니티에서 자체적으로 운용하는 노드도 많다. dns이름으로 제공되며, 해당 dns로 접근시 항상 켜져있는 무작위 노드의 주소를 받는다. 커뮤니티에서 운용중인 노드들은 후원을 받아서 운용되며 처음 노드를 설치하고 운용할때 진입점이 된다.
그렇다면 커뮤니티에서 운용하는 노드가 모종의 이유로 shutdown 된다면 비트코인은 운용할 수 없는걸까? 그건 아니다. 일단 노드가 가동되면
가장 가까운 대략 8개의 노드와 연결된다. 해당 노드에서 어떤 결제가 일어나면 관련 내용이 이 8개에 전파되고 내용을 전파받은 8개는 다른 노드에 다시 전파하는 식인 것이다.(토폴로지 적으로는 mesh network에 가깝다) 때문에 만약에 커뮤니티에서 운용되는 노드가 shutdown되더라도 한번 접속한 다른 노드의 주소를 기억하고 있기 때문에 운용간에는 문제가 없으며, 전파된 결제 내역은 노드에 노드를 통해 전파되어 전체 네트워크로 전파된다.
이러한 노드도 사실은 여러 종류가 있다.
a. Full node
비트코인의 모든 규칙을 완벽하게 검증하는 노드를 풀 노드 라고 한다. 우리가 일반적으로 생각하는 노드이며 모든 결제 기록(블록체인)을 가지고 있고, 검증할 수 있으며 다른 노드와 합의를 하는 주체이다.
b. Lightweight node
라이트 노드는 전체 블록체인을 다운로드하지 않는다. 대신, 거래의 진위 여부를 검증하기 위해 블록 헤더만 다운로드한다.
때문에 매우 가벼우며 유지 관리 및 운영이 쉽다. 라이트 노드는 간소화된 결제 검증(SPV)이라는 방법을 사용하여 거래를 검증하며 이 과정에서 Full node의 도움을 받으므로 Full node 의존적이다.
2) 블록 구조
비트 코인은 블록체인이라는 말 답게 블록의 체인으로 이루어져있다. 크게보면 아래와 같은 구조인 것이다.
해당 블록의 구조는 아래와 같다.
a. 블록
| 필드 | 설명 | 크기 |
| Magic no | 항상 0xD9B4BEF9 | 4 bytes |
| Blocksize | 블록 끝까지 이어지는 바이트 수 | 4 bytes |
| Blockheader | 6개 항목으로 구성되어있음(아래 내용 참고) | 80 bytes |
| Transaction counter | 양의 정수 VI = VarInt | 1 - 9 bytes |
| transactions | 비어있지 않은 거래 목록 | 트랜잭션 갯수에 따름 |
b. 블록 헤더
| 필드 | 목적 | 업데이트 되는 시기 | 크기 (Bytes) |
| Version | 블록 버전 번호 | 소프트웨어를 업그레이드하면 새로운 버전이 지정된다 | 4 |
| hashPrevBlock | 이전 블록 헤더를 입력값으로 처리한 256비트 크기의 해시 | 새로운 블록이 추가될때 | 32 |
| hashMerkleRoot | 현재 블록의 모든 거래를 입력값으로 처리한 256비트 해시 | 거래가 승인될시에 | 32 |
| Time | 1970-01-01T00:00 UTC 부터 현재까지 지난 초(UTC Timestamp) | 매초마다 | 4 |
| Bits | 현재 목표의 압축된 형태 | 난이도 조정시 | 4 |
| Nonce | 32-bit로 된 0으로 시작하는 숫자 | Hash 시도시마다 증가 | 4 |
※ Bits
Bits는 난이도를 압축된 형태로 표기한 것이다. 가수와 지수로 나눈 형태로 표기된다. 예를 들어 살펴보자.
만약 bits에 0x1b0404cb가 적혀있다고 하자. 여기서 cb 04 04는 가수이고 1b는 지수이기 때문에 아래와 같이 환산 할 수 있다.
1
0x0404cb * 2**(8*(0x1b - 3)) = 0x00000000000404CB000000000000000000000000000000000000000000000000
난이도 1(제일 처음 채굴된 제네시스 블럭의 난이도)는 아래와 같다.
1
0x00ffff * 2**(8*(0x1d - 3)) = 0x00000000FFFF0000000000000000000000000000000000000000000000000000
위와 같이 표기한 값은 current_target으로 난이도가 1일때의 값을 나누면 해당 값이 난이도 1일때보다 몇배나 어려운지 알 수 있다.
1
2
3
4
difficulty = difficulty_1_target / current_target
= 0x00000000FFFF000000000000000000000000000000000000000000000000000000000000000000000000 /
0x000000000000404CB0000000000000000000000000000000000000000000000000000000000000
= 16307.420938523983
c. 트랜잭션
| 필드 | 설명 | 크기 |
| 버전 | 현재는 1, OP_CHECKSEQUENCEVERIFY를 사용하여 시간 잠금을 활성화하는 경우 2로 설정 | 4 bytes |
| Flag | 존재하는 경우 항상 0001이며 증거 데이터가 있음을 나타낸다. | 선택적 2 byte array |
| In-counter | 양의 정수 VI = VarInt | 1 - 9 bytes |
| list of inputs | 첫 번째 거래의 첫 번째 입력은 "코인베이스"(채굴로 발행된 코인을 채굴자에게 전달한 거래)라고도 한다. | "in-counter"로 이루어진많은 입력 |
| Out-counter | 양의 정수 VI = VarInt | 1 - 9 bytes |
| list of outputs | 첫 번째 거래의 출력은 블록에 대해 채굴된 비트코인을 사용한다. | "out-counter"로 이루어진많은 입력 |
| Witnesses | 각 입력에 대해 1개씩 증거 목록이 있으며 위의 플래그가 누락된 경우 생략된다. | 가변적임 |
| lock_time | 어느시간 이후에 해당 거래가 블록체인에 추가될 수 있는지? | 4 bytes |
※ Witnesses
해당 잔액에 대해서 사용할 권리가 있다는 것을 증빙하는 자료이다. 해당 거래를 증빙할때 사용할 서명, 공개키, witnessScript등이 들어간다.
※ lock_time
- lock_time == 0 : 기다림 없이 바로 블록체인에 추가 가능
- lock_time < 5억 : 블록 높이(제네시스 블록에서 현재 블록까지의 갯수, 몇번째 블록인지)가 해당 값까지 왔을 때 추가 가능
- lock_time > 5억 : 해당 UTC time 이후에 추가 가능
3) 거래와 채굴
Transaction이라고 불리는 거래는 다음과 같다. A와 B가 있다고 할때 A가 B에게 3 BTC를 송금하고 싶다고 하자.
그러면 A는 이전 거래 블록의 해시값과 거래 내역, B의 공개키 해시를 포함해서 A의 비밀키로 암호화하여 연결된 코어에게 전파한다. 이렇게 비밀키로 암호화하는 것을 전자서명이라고 하며 A의 공개키로 이를 복호화하여 확인가능하다.
이렇게 이루어진 거래에 대한 내역은 내역을 수취한 코어에서 미확정 거래풀에 보관된다. 이후 이 거래에 대해서 확정(confirmation)을 거치게 된다. 이 과정에서 사용되는 것이 SHA256이라는 함수이다. 이 SHA256이라는 것은 해시 함수이다. 어떤 입력값을 받았을 때 일정한 길이의 무작위처리된 값을 출력하는 함수이다. 거래에 대해서 확정 받기 위해서는 네트워크가 정한 값에 대해서 아래의 연산 결과가 해당 값보다 작거나 같아야한다.
- 거래들의 해시 + 이전 블록 해시 + 난스(임의의 값)
해시 함수는 입력값이 같으면 같은 값을 출력하지만 각 입력 값과 출력 값 사이의 연관점을 찾을 수 없기 때문에 brute force를 통해 모두 체크해봐야한다.
(이 과정은 의존성이 없기 때문에 병렬화 시키기에 매우 요긴한데, 이 때문에 GPU가 채굴하는 과정에서 많이 사용된 것이다. 최근에는 채굴용 전용 주문형 반도체(ASIC)를 이용한다) 만약 해당 조건을 만족하는 난스 값을 찾는다면 거래들의 해시와 이전 블록의 해시와 난스 값을 포함하여 해시해서 네트워크로 연결된 코어에 브로드 캐스팅해서 각 코어의 Blockchain 끝에 달도록 하여 이를 확정을 받는다. 이 과정에서 새로운 block을 체인에 달게 되는 것이다.
이 과정에서 Incentive로 얼마간의 bitcoin(새로운 bitcoin + 거래 수수료)를 받게되는데 이를 채굴이라고 한다.
한 마디로 요약하자면 긴 원장에 다른 이들의 거래를 기재해주면서 수수료와 인센티브를 받는것이다.
4) 거래 수수료
갑자기 거래 수수료는 왜 튀어나오는거지 싶을 수 있다. 먼저 채굴을 위해서는 미확정 거래풀에서 거래들을 모으는 과정이 필요한데 이 과정에서 미확정 거래를 수집하는 기준이 수수료이다. 수수료가 큰 거래를 처리할 수록 채굴 간에 얻는 Bitcoin이 많기 때문에 수수료가 높은 거래일 수록 더 빨리 확정된다.
이러한 거래 수수료가 정해지는 방식은 총 두 가지이다. 수수료로 정해지거나, 수동으로 정하는 법이다. 일반적으로 수동으로 정하는 것은 자동으로 정하는 양보다 더 높게 정하는 것으로 수수료가 높을 수록 더 빨리 확정될 가능성이 높기 때문에 빠른 확정을 위해 지정하는 것이다.
수수료율은 기본적으로 가상 바이트당 사토시라는 단위로 처리되며 (사토시는 비트코인 단위이다. 1억 사토시는 1 비트코인이다) 수수료는 사토시 * 거래의 가상 크기로 정해진다. 이러한 수수료율은 블록의 한정된 공간(블록 가중치) 때문에 수요(혼잡도)에 따라 수수료율이 변동되기 때문에 실시간으로 달라진다.
예를 들어 확정할 트랜잭션의 총 크기가 1000 가상 바이트고 수수료율이 40 사토시/vB인 경우 1000 * 40 = 40,000 사토시이며 이는 0.0004000 BTC와 같다.
5) UTXO(Unspent Transaction Output)
bitcoin은 코어들의 상호작용으로 인해 단일 체인이 유지되며 신뢰성이 보장된다. 그렇다면 비트코인의 거래와 잔고는 어떻게 유지되는 걸까?
답은 간단하다. 각 거래원장에 사용되지 않은 bitcoin 잔량을 포함하는 형태로 기재하는 것이다. 가령 A와 B가 있다고 할때 아래와 같이 송금했다고 하자 (A가 이미 100 BTC를 갖고 있다고 가정)
- A가 B에게 20BTC를 송금
그러면 A는 80 BTC가 있고 B가 BTC가 있음을 명시하는 것이다.
정확하게 말하자면 A가 사용한 BTC가 B로 이동되는 것이 아닌 사용한 만큼 A의 계정에서 BTC는 소멸되고 B에 송금한 만큼 B의 계정에서 BTC가 생성되는 걸로 보면 된다.
아래는 bitcoin 공식 사이트에 올라와있는 UTXO의 예시이다.
비트코인 지갑에서 비트코인 잔고를 조회할 때는 비트코인 코어로 요청을 보낸다. 그러면 코어에서 해당 지갑의 UTXO를 모두 조회해서 반환해주는 식이다.
6) Invoice address
BTC를 거래하려면 적어도 BTC를 받는 이가 누구인지를 알아야한다. 이때 필요한게 Invoice address이다.
숫자 또는 1로 시작하는 26~35자의 영숫자 식별자로, 비트코인 결제의 가능한 목적지를 나타낸다.
대부분 이러한 Invoice address는 다회를 사용할 수 있지만 일회만 사용하기를 권장하며 한 명이 다수의 Invoice address를 가질 수 있고 생성할 수 있다.
7) Orphan chain(Stale chain)
기본적으로 Bitcoin 네트워크는 내 결함성이 강하고 가용성이 높지만 Mesh 구조이기 때문에 Network가 split될수 있다.
그럴 경우 각 네트워크마다 확정되며 이후 네트워크가 연결될 경우 각 체인의 길이를 비교하여 짧은 체인(Orphan chain or Stale chain)이 버려지며 해당 체인에 들어있던 거래들은 다시 미확정 거래로 돌아가게 된다.
이 때문에 bitcoin의 거래를 조작하기 위해서는 전체 체인을 압도하는 양의 컴퓨팅파워가 있어야하므로 전체 코어 개수의 51%를 넘게 점유해야 가능하다.
4. 위협
1) 양자컴퓨터 도입으로 인한 암호화 무력화
원래 RSA 같은 비대칭 암호화의 경우 양자 컴퓨터의 연산에 취약한 형태이다.
이는 공개키 방식의 전자서명은 기본적으로 큰 소수가 소인수 분해하기 힘들다는 특성을 이용해서 RSA가 유지되는 것이다. 때문에 양자 컴퓨터를 사용할 수 있다면 쇼어 알고리즘으로 인해 시도 횟수가 매우 줄어들어서 취약해진다.
비트코인의 경우에는 ECDSA를 사용하는데 이는 타원곡선 위의 이산로그 문제(ECDLP)이다. ECDLP역시 Shor의 알고리즘은 큰(유한체/타원곡선) 이산로그 문제를 다항시간에 풀 수 있어서, 충분히 큰 오류보정된(=fault-tolerant) 양자컴퓨터가 존재하면 ECDSA 비밀키를 효율적으로 찾아낼 수 있다.
때문에 양자 컴퓨터의 상용화 이전에 비트코인 커뮤니티의 개발자들이 양자 내성 암호를 사용하거나 혹은 양자 블록체인을 코어 알고리즘에 도입해야한다. 기본적으로 채굴에 사용되는 해시 함수도 양자 컴퓨터에 위험하나 이는 키의 길이나 결과의 길이를 늘이면 어느정도 대처가 되므로 당장은 문제가 없다. 다만 이 부분 역시 비트코인 알고리즘에 수정되야할 것이다.
2) Y2K38로 인한 Timestamp overflow
기본적으로 비트코인의 Header에는 timestamp가 포함되어있다. 이 timestamp는 이전 block의 이후의 현재 block이 생성되었다는 시간적 증명이기도한데 문제는 이 timestamp는 4Bytes의 크기를 갖고 있다. 이는 컴퓨터공학에서 말하는 int형 정수 타입의 최대 크기와 같은데 기본적으로 1970년 1월 1일 자정 UTC를 기준으로 몇초나 지났는지 표기하는 것이다.
하지만 2038년 1월 19일 03:14:07 UTC이면 4Bytes가 1로 꽉차서 Overflow 현상이 일어난다.
때문에 이 부분 역시 비트코인에서 4bytes를 8bytes로 늘리든 다른 방식을 사용하든 방법을 강구해야한다.
※ 추가 업데이트 및 검증 예정이다.
참고문헌
- Satoshi Nakamoto, “Bitcone : A Peer-to-peer Electronic Cash System”, bitcoin, 2008, https://bitcoin.org/bitcoin.pdf
- 비트코인 공식 사이트
- 사이퍼펑크 - 위키백과
- 김승주의 암호세상 - 양자 컴퓨터로 비트코인을 깰 수 있다?
- 위키백과 - SHA2
- 위키백과 - 공개 키 암호 방식
- 비트코인이란 무엇인가, 레드스톤, 사토시 나카모토 지음, 고피디 번역 · 해설
- 블록체인 공식 위키 - 블록 구조
- NISTIR 8105 - Report on Post-Quantum Cryptography 2 Page
- 비트코인 개발자 사이트 - 트랜잭션
- 비트코인 공식 위키 - Difficulty

