프로그래밍/Blockchain

비트코인(Bitcoin)으로 알아보는 암호화폐의 원리 - 작업증명(Proof of work)

Lou Park 2021. 12. 8. 01:12

신뢰! 신뢰! 신뢰!

비트코인은 그저 데이터에 불과한데 어떻게 화폐로서의 기능을 할 수 있을까?

화폐는 기본적으로 신뢰를 바탕으로 만들어졌다. 통용되는 종이 화폐도 신뢰성있는 기관인 중앙 정부가 인정했기때문에 가치를 가진다. 신뢰 없이는 5만원권 뭉치도 그저 이쁜 종이쪼가리에 불과하다.

 

비트코인은 기존의 화폐처럼 발행과 결제가 중앙 장부나 은행, 카드사 등 특정 기관에 집중되어있지 않고, 개개인에 분산되어있다. 사기꾼 천지인 이 세상에서 어떻게 서로가 서로를 믿게 할까?

 

최초의 암호화폐인 비트코인은 암호화와 블록체인을 통해 이러한 탈중앙화(Decentralized)된 금융거래를 가능케 했다. 유튜브 3Blue1Brown의 <But how does bitcoin actually work?>라는 영상 내용을 바탕으로 비트코인이 했던 고민들을 같이 살펴보자.

 

 

앨리스, 밥, 찰리, 나 4명이서 돈거래를 한다고 가정하자. 

비트코인은 네트워크에 참여한 모든 노드(여기서 앨리스, 밥, 찰리, 나가 해당)가 각각 장부(Ledger)를 가지고 있어서, 그곳에서 일어나는 모든 거래가 각자의 장부에 적히도록 한다. 

 

"앨리스가 밥한테 $20를 줬대!"를 4명이서 똑같이 받아적는거다.

 

세상사람들이 이렇게 착하다면 이것만으로도 충분했겠지만...

당연하게도 장부를 조작하는 일이 발생할 것이다.

 

사기만 막으면 돼! 그것이 신뢰.

"앨리스가 밥한테 $20를 줬대!"라는 거래를 10번 연달아서 적는다면??

둘은 사실 거래도 하지않았는데 제 3의 사람이 그렇게 적어두었다면?!

 

이러한 거짓 거래를 막기 위해서 각 거래에 디지털 서명(Digital signature)을 도입한다. 하지만 디지털 뭐 0과1로 이루어졌는데 뭐든지 똑같이 복제되는 것 아니냐? 싶을 수 있을거다. 

 

 

하지만 공개키(public key)/개인키(private key, secret key라고도 부름) 방식을 이용하면 고유한 디지털 서명이 구현 가능하다. 위 그림에서 pk라고 된 부분이 공개키, sk라고 된 부분이 앨리스, 밥, 찰리의 개인키다. 공개키는 누구나 접근할 수 있지만, 개인키는 이름처럼 오직 자신만 알고있는 키다.  

 

 

어떤 메세지에 비밀키를 더해 시그니쳐를 만들고, 공개키를 가지고 해당 시그니쳐가 제대로 만들어진 것인지 판별을 할 수 있다. 시그니쳐를 만드는 데에는 SHA256 알고리즘을 사용하는데 이것은 어떠한 값을 넣더라도 256bit의 고정된 결과 값을 출력하는 해시함수이다. 단방향 암호화로 다시 복호화를 할 수 없는 암호화이기 때문에 Secret key가 털릴 일도 없다. 이를 때려 맞추려면 2의 256승만큼의 시도를 해야하는데, 이건 절대 절대 때려맞출 수 있는 수준이 아니다.

 

감이 잡히지 않을 것 같으니, 간단히 SHA256 예시를 확인 해 보자.

아래는 각 문자들을 SHA256으로 해싱해본 것인데 영어 철자하나, 숫자 하나 바뀌었을 뿐인데 모든 문자열이 바뀌어서 해시된 결과를 보면 원래 문자열이 도대체 어떤것인지 추측이 불가능하다. 맞추기는 어렵지만 답의 확인은 아주 빠른것이 해시 함수의 핵심이다.

Lou --> 1ce1a033973af916738ca2acad83515b23e04fda92ffcbaffc27a666ce31b3e9
lou --> 6e1a5d40108164ad38168f58271ef4411cb9c75cc001cf7a14a6047eb05192f2
1234 --> 03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4
123 --> a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae3

 

공개키, 개인키, 주소

암호화폐에서의 개인키(비밀키)는 256bit 길이의 랜덤 생성된 숫자를 16진수로 표현한 것이다. 

[개인키]
7b1d3294d57b86a454df7b5e66cb628f761929c3440e166f7bf7bc86f041375c

 

만들어진 개인키를 바탕으로 공개키를 만들 수 있다. 개인키에 타원 곡선 암호(ECC, Elliptic Curve Cryptography)을 적용시키면 공개키를 생성 할 수 있다. 타원곡선 암호는 TLS나 공인인증서 구현에 사용되는 RSA보다 bit 수 대비 보안 수준이 우수하며 (ECC 224bit로 RSA 2048bit와 동일한 암호화 강도), 키 생성 시간도 훨씬 빠르다. 타원곡선 암호화 방식 역시 SHA256처럼 한 방향으로는 계산하기 쉽지만 반대로는 계산하기 힘든 비가역성을 가진다.

 

타원곡선위의 점 A와 B를 정해 직선으로 연결하면 나타나는 연장선이 타원곡선과 만나는 지점에서 X축 대칭하여 나타나는 C 좌표가 나타나게 되는데, 이 식은 A + B = C로 표현이 된다. 이것을 포인트 덧셈(Point addition) 연산이라고 한다. 그러면 2A는 무엇일까? 2A는 Point doubling 연산으로,  A + A로 표현할 수 있다. 개인키를 k, 공개키를 K, 타원곡선의 시작 지점 G라고 할때 K = k * G로 표현하며, 즉 K = G + ... + G이다.

 

출처 Pixabay 무지성 당구 사진...머리 식히세요

 

공개키 K는 타원곡선 상의 G에서 개인키 k번 만큼의 덧셈 연산을 수행한 결과가 되는데 사칙연산으로 표현해서 그렇지...K와 G를알때 k를 유추하기란 아주 어렵다. 당구를 생각해보면 결과적으로 위치해 있는 공(K)이 어떤 방향으로 몇 번(k)을 튕겨가서 처음의 위치(G)에 갈 수 있었냐를 추측해낸다는 것인데, G에서 직접 쳐보는 것이 그러고 앉아있는 것보다 훨 빠르다.

[공개키]
042da9486e4f3cd3d0bc8020f8ac47719fbebdf232909a3a194b36e665125373e5757f59ff0759fbc1136ca784acd6d610292f50489c8c996030d68fb90758817b

아무튼 이렇게 만들어진 공개키에 SHA256과 RIPEMD160 해시를 거치면 비트코인 지갑 주소가 나온다. RIPEMD160은 입력값을 160bit로 압축하는 암호화 해시함수다. 이렇게 되면 긴 공개키를가지고 비교적 길이가 짧은 지갑주소가 만들어진다!

[지갑주소]
13pgJQEfAcGLbbAExnwh351s1wRCW4z4T2

 

하지만 앨리스가 서명한 "앨리스가 밥에게 $20을 지불했대!"라는 거래가 여러개 발생되었을때는 어떨까? 올바르게 서명되었지만...내용이 같은게 여러개라!

 

 

이를 위해서 모든 거래에는 고유 숫자를 붙여서 함께 해싱을 한다. 앞서 Python으로 구현한 부분에서 메세지 앞에 고유한 거래 번호를 붙여주면 중복 거래 방지가 손쉽게 가능해진다.

 

매직넘버, 블록 체인

이제 또 다른 문제가 생긴다. 거래가 일어나고, 거래 내용을 네트워크상의 모든 장부에 브로드캐스팅한다고 했다. 거래는 전 세계에서 동시 다발적으로 일어날테고, 어느 장부에서는 잘못기록 되기도 할 것이다. 어느 장부를 믿어야할까? 비트코인은 바로, 가장 많은 계산을 한 장부가 가장 신뢰할만한 장부라고 판단한다.

 

 

일정한 거래 내역이있는 장부에 어떤 특정 숫자를 추가하여 SHA256로 해시하였을때 결과값의 첫 N번째까지의 bit가 모두 0일때 그 특정 숫자를 매직 넘버(Magic number)라고 한다. 아래 그림에서는 장부내용에 1073765433을 추가하여 해시했을때 첫 30자리의 bit가 모두 0이니, 1073765433이 이 장부 블록의 매직 넘버가 된다. 이것이 몇자리 bit로 0으로 끝나야하는지는 비트코인 규약에 따르며, 해시값을 계산해내는데에 대략 10분이 걸리도록 주기적으로 관리된다.

 

 

이 매직 넘버를 알아내기 위해서 0부터 시작해서...하나하나 대입하여 해시하는 방법으로 꽤나 많은 시간을 들여 계산했을 것이다. 하지만 반대로 1073765433이라는 숫자가 매직 넘버임을 확인하는 작업은 한번의 해시로 쉽게 끝나게된다. 이를 작업 증명(Proof of Work, PoW)이라고 한다. 

 

블록체인에서 이 장부는 "블록"이라고 부른다. 장부를 조작하기 위해 블록내의 내용의 하나라도 수정하게 되면, 결과 해시값도 완전히 바뀌게 될 것이고 매직넘버도 처음부터 다시 연산하여 찾아내어야 한다. 

 

하지만 만약 이 블록의 순서는 어떻게 보장할까? 태초의 블록이 아니라면, 이전에 검증된 블록이 있을 것이다. 이전에 검증된 블록 다음에 오는 블록임을 증명하기 위해서 이전 블록의 해시값을 추가하여 계산하게된다. 즉, 현재 블록의 매직넘버는 [이전 블록의 해시값] + [현재 블록 거래 내역]을 통해 도출해내게 된다. 이렇게 검증된 블록들을 연결하면 체인처럼 되는데...그래서 블록 체인이라고 부르게 되었다. 이전 블록의 해시값이 들어감으로서 중간에 거래조작이 매우 힘들어지게 된다.

 

 

매직넘버를 가장 먼저 알아내는 작업을 채굴(Mining)한다고 하는데, 채굴자가 매직넘버를 찾아내어 블록을 브로드캐스팅하게 되면 일정 수량의 비트코인 보상(Block reward)을 지급받는다. 채굴이아닌 그냥 거래만 하는 사람들은 채굴자들이 브로드캐스팅한 블록읠 각자의 블록체인 복사본에 추가하기만 하면 된다. 

 

하지만 만약에 누군가가 체인을 조작하여 추가할 체인이 2개 이상이있을때는 어떻게 할까? 앞서 가장 많이 계산한 장부가 가장 믿을만한 장부라고 했다. 가장 많은 계산을 한 장부 = 가장 긴 블록체인이므로, 모든 옵션 중에 가장 긴 블록체인을 선택하면된다. 어떤 사람이 정말 운 좋게  연속적으로  매직넘버를 척척 때려 맞춰서 여러 블록을 조작하여 조작된 블록이 블록체인에 등록된다해도, 전 세계의 채굴자들이 만들어낸 블록체인의 속도를 따라잡는 것은 "거의" 불가능 할 것이다. 거의...라는 이유는 이론상으로는 51% 공격이 가능하기 때문이다. 51% 공격이란 전체 노드중 50%를 초과하는 컴퓨팅 파워로 거래정보를 조작하는 해킹 공격이다. 따라서 신뢰할만하다고 판단되는 블록이 들어오더라도, 해당 블록 뒤에 몇개의 블록이 더 추가될때까지 기다린 후에 신뢰하게 된다.

 

이처럼 작업증명(PoW) 방식은 컴퓨팅 파워를 많이 필요로하고 (환경 문제), 거래 처리 속도도 현저하게 느리다는 문제가 있다. 이를 극복하기 위해 작업증명 대신 더 많은 양의 코인을 가진 경우 블록을 기록할 권한이 부여되는 지분증명(Proof of Stake, PoS)방식을 도입한 코인들이 등장하게 되었다. 하지만 지분증명마저도 거래 처리속도가 기존 결제 시스템에 비해 뒤쳐지고, 이중 결제등의 문제가 있어 계속해서 좋은 방법을 찾아가는 중이라고한다!

 

 


 

참고자료

https://www.youtube.com/watch?v=bBC-nXj3Ng4 

http://wiki.hash.kr/index.php/SHA256

https://steemit.com/dclick/@eaglekeeneye/-5-bitcoin-2-1544235909120

https://asecuritysite.com/encryption/bitcoin02

http://wiki.hash.kr/index.php/RIPEMD-160

https://www.mk.co.kr/news/economy/view/2019/03/168095/

http://wiki.hash.kr/index.php/%EC%A7%80%EB%B6%84%EC%A6%9D%EB%AA%85