2018년 2월 6일 화요일

비트코인

비트코인의 실체

비트코인은 2009년 ‘사토시 나카모토’라고 알려진 개인 또는 다수의 개발자들을 통해 탄생했습니다. 사토시는 일본인이 아니고 가명입니다. 현재, 호주의 암호학 전문가인 크레이그 라이트나 게임이론의 창시자인 경제학자 존 내쉬 등이 사토시라고 추정되고 있지만 각국의 규제와 법률 때문인지 확실하게 밝혀진 사람은 아직 없습니다.
우리가 보통 부른 비트코인이라는 용어의 실체적 개념은 존재하지 않습니다. 누가 얼마를 소유하고 있다는 잔액 개념의 원장 데이터도 없습니다. 비트코인 생태계의 모든 속성과 특징은 사토시가 2009년 발표한 논문을 토대로 구현한 비트코인 코어 Bitcoin Core 프로그램안에 프로그램(코딩)되어 있으며, 이 시스템 하에서 발생하는 거래 내역의 모음이 블록체인이라고 불리는 공개장부에 저장될 뿐입니다. 비트코인 시스템 또는 비트코인 네트워크라고 부르는 것의 실체는 바로 이 네트워크를 의미합니다. 비트코인 코어 프로그램은 Bitcoin.org를 통해 누구나 PC로 다운받을 수 있으며 github라는 온라인 오픈소스 저장소에 모든 소스도 올려져 있어서 지금은 전 세계 개발자들의 공헌에 의해 발전하고 있습니다. 지금까지 나온 1,000개가 넘는 대안화폐(altcoin)나 이더리움(Ethereum) 같은 블록체인 플랫품 역시 최초의 비트코인코어 프로그램의 소스를 모방해서 발전했습니다. 거래내역의 모음인 DB역할을 하는 공개장부 역시 비트코인코어 프로그램을 다운 받은 사람들은 누구나 내려받을 수 있습니다. 비트코인이 출시된 이후 지금까지 전 세계 모든 거래의 공개장부는 약 수십 기가바이트 용량의 파일로 구성되어 있습니다. 다운 받으려면 며칠은 걸리겠지만 전 세계 모든 거래의 장부를 가질수 있게 되는것이죠.
이제 비트코인의 거래가 어떠헤 이뤄지는지 사례를 통해 살펴보겠습니다.

비트코인 거래 예시

  • 앨리스 : 난생 처음 비트코인을 사고 싶어 하는 여자
  • 조 : 앨리스에게 비트코인을 팔아줄 남자
앨리스는 스마트폰으로 비트코인 지갑 어플리케이션을 다운받았습니다. 지갑 어플리케이션은 임의로 개인키와 그에 대응하는 비트코인 주소를 발행합니다. 계좌번호나 이메일주소가 부여된다고 생각하면 됩니다. 이 주소는 개인키에 대응되는 일련의 숫자에 불과하며 아직 비트코인 네트워크상에 공개되거나 등록되지 않습니다. 비트코인 주소가 거래와 연관되어 네트워크상에서 주소가 공개되면 앨리스는 공개장부를 통해 해당 주소의 잔액을 확인할 수 있다.
여기서 비트코인 네트워크, 또는 네트워크 노드(node) 란, 비트코인 시스템의 기능과 요소들을 포함하고 있는 클라이언트를 말합니다. 이를 테면, bitcoin.org의 기본 클라이언트이자 사토시가 만든 비트코인코어 클라이언트가 설치된 PC를 의미합니다. 이 클라이언트들은 지갑, 거래장부 복사본, 검증엔진, P2P네트워크 전송 기능 등을 가지고 있으며, 좀 더 Lite한 기능들로만 구성된 클라이언트도 많이 개발되어 있습니다. 이 글을 쓰는 저 역시 이 세계에서 하나의 노드가 될 수 있습니다.
이제 앨리스는 비트코인을 얻기 위해 현금 10달러와 비트코인 주소를(QR코드) 조에게 주었고 조는 자신의 모바일 지갑을 열어 QR코드를 스캔하고 시세에 해당하는 0.1비트코인을 주었습니다. 거래가 성사되면서 조는 개인키로 해당 거래에 대해 서명합니다. 마치 우리가 인터넷뱅킹으로 이체할 때 공인인증서로 전자서명을 하듯이 말입니다. 이 과정이 끝나면 조의 비트코인 주소 중 한 곳에서 앨리스의 새 비트코인 주소로 송금이 허가되었다고 비트코인 네트워크에 알립니다. 네트워크에 연결된 모든 노드들은 거래내역을 받고 처음으로 앨리스의 주소를 보게 됩니다.
이 거래는 전송은 되었지만 아직 비트코인 공개장부(=거래장부=블록체인)에는 포함되지 않았습니다. 거래가 공개장부에 포함되려면 채굴자들이 채굴을 해야 하는데요(이 부분은 뒤에 가서 설명합니다.) 하나의 블록은 여러 개의 거래를 담을 수 있는데, 새로운 블록이 약 10분 주기로 형성되면 그 블록 내에 있는 거래내역들은 네트워크상에서 “승인”되며 그 후 소비가 가능합니다. 정리하자면, 거래는 발생하자마자 모두가 “볼” 수 있지만 새롭게 채굴된 블록에 포함되는 경우에만 모두가 “신뢰”하게 됩니다.
참고로 비트코인의 무서운 점은 화폐를 데이터 구조로 전환했기 때문에, 어떤 형태로든 전송이 가능합니다. 웹, 와이파이, 블루투스는 물론이거니와 라디오, 위성중계, 이모티콘, SMS등 해당 거래를 전파하게될 노드에 도달할 수만 있다면 어떤 네트워크를 사용해도 무방합니다. 극단적으로는 거래 자체는 오프라인상태에서도 가능하며 거래가 기록될 때만 네트워크로 전송하면 됩니다.미국에서 수표를 먼저 발행하고 나중에 봉투에 넣어 은행으로 우편 발송하듯이 말이죠. 스타벅스에서 신용카드 결제를 할 때, 3만원 이하는 무서명 거래를 하듯이 비트코인 시장에서도 소액이체나 결제는 비트코인 네트워크의 별도 승인이나 신뢰 없이도 인정할 수 있게 되어 있습니다.
앨리스는 이제 비트코인으로 재화를 구매하고자 합니다. 어려워서 머리가 아프니 커피를 사서 마시겠습니다. 비트코인을 받아주는 커피숍에서 0.015 비트코인(BTC)짜리 커피를 주문하니 밥(Bob)이라는 사람이 관리하는 POS시스템이 payment request가 들어있는 QR코드를 보여줍니다. 여기에는 송금할 비트코인의 목적지 주소, 지불금액 등 지불과 관련된 기본내용이 담겨있습니다. 일종의 청구서 같은 겁니다. 앨리스는 지갑 어플리케이션을 열어 QR코드를 스캔후 전송 버튼을 눌러 지불을 승인합니다. 즉, 비트코인을 소비합니다. 이처럼 소비란 이전 거래에서 송금되었던 돈이 비트코인 주소에 의해 확인된 새로운 소유주에게로 전송되는 거래에 서명을 함으로써 이루어지는 작업을 말합니다.
블록체인 거래원리
다시 정리하면, 비트코인의 거래는 비트코인을 많이 보유한 소유주가 그 일부를 다른 사람에게 전송하는 것이고, 각 거래가 체인을 형성하게 됩니다. 이때 가장 최근 거래에서 생성된 입력값은 그 이전 거래에서 발생한 출력값과 대응합니다. 위 그림의 두번째 거래와 같이 거래를 한 뒤, 잔액이 발생하는 경우도 마찬가지입니다. 그림에서는 출력값이 밥에게 지불된 금액만 나왔지만, 앨리스의 남은 잔액이 또 다른 거래의 입력값이 될 수 있습니다. 앨리스는 돌려받은 잔액 결과값을 이용해 다른 거래에서 해당 금액을 소비할 수 있는 것입니다. 한편, 입력의 합과 출력의 합은 반드시 서로 동일하지는 않은데, 그 이유는 거래 속에 포함된 “거래 수수료”때문입니다. 나중에 다시 설명하겠지만 이 거래 수수료는 해당 거래를 블록에 포함시키고 공개장부(블록체인)에 올리는 것에 대해 채굴자가 수거하는 수고비, 수수료 개념입니다.
지금까지 거래가 일어날 때 발생하는 현상을 살펴봤는데, 그럼 이 거래내역이 어떻게 블록의 부분이 되며, 공개장부에 추가되는지를 살펴보겠습니다.

검증, 채굴과 합의

이 거래는 이제 전세계 공개장부의 일부가 되기 위해 비트코인 네트워크로 전송되어야 합니다. 앨리스의 지갑 어플리케이션이 인터넷만 연결되어 있다면 여러 비트코인 고객들에게 새로운 거래를 전송할 수 있습니다. 비트코인 네트워크의 노드들은 자신이 이전에 가지고 있지 않은 거래를 전송받게 되면, 즉시 연결된 다른 노드로 해당 거래를 전달합니다. (이 부분은 우리가 흔히 사용하는 토렌트, P2P 방식과 비슷하다고 보면 됩니다.) 이런 과정은 불과 몇 초만에 비트코인 네트워크 내에 있는 노드 대부분에게 도달합니다
이제 거래가 비트코인 네트워크에 전파되었습니다. 하지만 이 거래가 검증되고, 채굴(mining)을 거쳐, 블록에 포함되는 과정이 남아있습니다.
검증하다니, 뭘 어떻게 검증하는걸까요? 답을 얻기 위해 이런 질문을 하나 해보겠습니다.
중앙신뢰기관(이를테면 은행)이 없는 상태에서, 공개장부안에 있는 내용, 즉 결국 누가 무엇을 얼마나 소유하고 있는지에 대한 단 하나의 보편적 “진실”에 어떻게 전 세계 모든 사용자가 동의할 수 있을까요? 답은 간단합니다. 모두가 같은 장부를 가지고 있기 때문입니다. 그럼 어떻게 모두가 동일한 장부를 가지게 된걸까요? 조작을 해서 나만 몇 억을 더 가지고 있는 거래내역을 만들어 모두에게 전달할 수는 없을까요? 예, 불가능합니다. 바로 사토시의 중요한 발명품인 합의도출(emergent consensus) 프로세스 때문입니다. 이 합의는 독립적인 비트코인 네트워크의 노드들이 모두 동일한 규칙을 따르면서 만든 비동기적이고, 상호작용적인 결과물입니다.
Computer Science 분야에서는 분산 컴퓨팅에서 발생할 수 있는 신뢰와 합의의 문제를 함축하는 비잔티움 장군의 딜레마라는 문제가 있습니다. 비잔틴 군대의 여러 사단이 적군의 도시 바끝에 진을 치고 있는데, 각 사단이 오로지 전령을 통해서만 서로 연락할 수 있다고 할 때, 배신자들을 배제한 상태로 언제 어떻게 동시적인 공격을 할지에 대한 고민입니다. 다수의 노드(PC)가 참여하는 분산네트워크에서 합의와 의사결정은 아주 핵심적인 문제인데, 사토시가 이 부분에 대해 중요한 솔루션을 발견한 것이죠. 결론부터 얘기하면 배신자는 다수의 충직한 장군들에 의해 폐기된다는 원칙입니다. 그리고 이 충직성을 작업증명(Proof of Work)라는 방법으로 입증 하는 것입니다. 이 발견은 단순히 통화 뿐 아니라 자산, 선거, 계약 등 공정성을 입증해야 하는 분산 네트워크 환경에서 아래 중요한 해결책이 될 수 있다는데서 큰 의미가 있습니다.
다시 사토시의 합의로 돌아와서 살펴보면 이 합의 프로세스는 크게 네 가지가 있습니다.
  1. 모든 노드가 각 거래마다 독립된 검증 실시
  2. 어떤 채굴자가 작업증명에 성공하면 다른 채굴자들이 검증하여 검증된 거래들을 새로운 블록에 독립적으로 추가
  3. 모든 노드들이 새 블록을 독립적으로 검증한 다음 체인에 블록을 연결
  4. 모든 노드가 작업증명을 통해 나온 최고 누적 연산 체인을 독립적으로 선택
앨리스의 사례에서 보았듯이, 거래가 끝나면 그 거래는 모든 비트코인 네트워크에 전파가 됩니다. 여기서 각 네트워크의 노드들은 받은걸 이웃 노드들에게 다시 전송을 하기 이전에, 1차적으로 스스로 검증을 합니다. 합의 프로세스의 첫 번째 단계이니다. 거래가 이미 소비되어 있으면 안되고, 거래크기는 MAX_BLOCK_SIZE보다 작아야 하고, 입력값이 출력값 총액보다 커야 하고, 해시가 0이면 안되고…등등…사토시와 오픈소스 커뮤니티가 발전시킨 수 많은 체크리스트들을 통해 유효한 거래들만 솎아 내고 다른 노드에게 전송을 합니다. bitcoin/src/consensus/tx_verify.cpp 참조 - CheckTransaction, CheckTxInputs 등
두번째 단계를 가려면 채굴이라는 것을 이해해야 합니다. 채굴은 뭘까요? 가끔 인터넷에 보면 어떤 중국인 채굴자가 알파고나 가지고 있을 법한 수 천대의 GPU로 무장한 장비를 구축하고 한 달 전기세를 몇 억 씩 내가며 채굴을 하는 사진을 보셨을 수도 있습니다. (실제 채굴자들은 중국인들이 다수를 차지합니다.) 흔히들 채굴이란 많은 컴퓨팅 파워를 가지고 수학적 계산을 통해 솔루션을 찾는 것이라는데, 그 무식한 돈 낭비를 왜 하는지, 어떻게 하는지 한번 살펴보겠습니다.
본래 채굴 과정은 2가지 목적을 가지고 있습니다.
  1. 거래를 담고 있는 블록이 충분한 계산력을 사용하여 확인될 때만 블록이 장부에 등재되고 신뢰를 형성한다.
  2. 각 블록 내에서 새 비트코인을 생성한다. 즉, 화폐를 발행하는 역할을 한다.
무슨 소린가 싶습니다. 하나씩 살펴보지요.
채굴의 기술적 목표는 블록 헤더 안에 있는 난이도 목표(target value) 보다 낮은 블록 해시값 이 나올수 있게 하는 난스(nonce) 값을 찾는 것입니다. 이 요건에 맞는 난스를 찾기 위해 초당 수천 조에 달하는 테스트를 합니다. 좀 더 쉽게 설명하면 채굴은 블록 헤더를 반복적으로 해싱해서, 해시 결과값이 특정 목표치와 일치할 때까지(=목표보다 낮아질때까지) 하나의 매개변수, 즉 난스 값을 변화시키는 과정입니다.
프알못을 위해…해시란(hash)?
해싱은 임의의 길이의 데이터를 고정된 길이 의 데이터로 매핑하는 암호화 함수입니다. SHA256이라는 알고리즘을 통해 어떤 텍스트들도 16진수의 64개 고정된 문자로 변경해버립니다. 어떤 특정 입력에 대한 해시 결과는 늘 동일하지만, 해싱의 결과값으로 입력값을 찾아내는 것은 불가능합니다. 목표하는 해시 결과가 우연히 나타나기 위해선 입력값을 하나씩 바꿔가며(ex:입력값의 일부인 난스를 1씩 증가시켜보며) 무한히 테스트 해보는 수밖에 없습니다. 특정한 값을 얻기 위해 가능한 모든 값을 대입해 보는것이죠.(Brute Force)
간단한 파이썬 예시입니다.
# Python 2.7.1
>>> import hashlib
>>> print hashlib.sha256("I am Satoshi Nakamoto").hexdigest()
5d7c7ba21cbbcd75d14800b100252d5b428e5b1213d27c385bc141ca6b47989e

# 문장에 숫자만 추가해도 해시값은 완전히 달라집니다
>>> print hashlib.sha256("I am Satoshi Nakamoto1").hexdigest()
f7bc9a6304a4647bb41241a677b5345fe3cd30db882c8281cf24fbb7645b6240

>>> print hashlib.sha256("I am Satoshi Nakamoto2").hexdigest()
ea758a8134b115298a1583ffb80ae62939a2d086273ef5a7b14fbfe7fb8a799e
이제 해시가 뭔지를 감을 잡았습니다. 그럼 이제 변수로 사용되는 난스를 1씩 증가시켜보며 해시값이 어떻게 변하는지 살펴보겠습니다. 참고로 해시값은 모두 16진수입니다.(각 자리수가 0~f까지만 나올수 있다는 말.)
I am Satoshi Nakamoto0  => a80a81401765c8eddee25df36728d73...
I am Satoshi Nakamoto1  => f7bc9a6304a4647bb41241a677b5345...
I am Satoshi Nakamoto2  => ea758a8134b115298a1583ffb80ae62...
I am Satoshi Nakamoto3  => bfa9779618ff072c903d773de30c99b...
I am Satoshi Nakamoto4  => bce8564de9a83c18c31944a66bde992...
I am Satoshi Nakamoto5  => eb362c3cf3479be0a97a20163589038...
I am Satoshi Nakamoto6  => 4a2fd48e3be420d0d28e202360cfbab...
I am Satoshi Nakamoto7  => 790b5a1349a5f2b909bf74d0d166b17...
I am Satoshi Nakamoto8  => 702c45e5b15aa54b625d68dd947f159...
I am Satoshi Nakamoto9  => 7007cf7dd40f5e933cd89fff5b791ff...
I am Satoshi Nakamoto10 => c2f38c81992f4614206a21537bd634a...
I am Satoshi Nakamoto11 => 7045da6ed8a914690f087690e1e8d66...
I am Satoshi Nakamoto12 => 60f01db30c1a0d4cbce2b4b22e88b9b...
I am Satoshi Nakamoto13 => 0ebc56d59a34f5082aaef3d66b37a66...
I am Satoshi Nakamoto14 => 27ead1ca85da66981fd9da01a8c6816...
I am Satoshi Nakamoto15 => 394809fb809c5f83ce97ab554a2812c...
I am Satoshi Nakamoto16 => 8fa4992219df33f50834465d3047429...
I am Satoshi Nakamoto17 => dca9b8b4f8d8e1521fa4eaa46f4f0cd...
I am Satoshi Nakamoto18 => 9989a401b2a3a318b01e9ca9a22b0f3...
I am Satoshi Nakamoto19 => cda56022ecb5b67b2bc93a2d764e75f...
만약 난이도 목표 가 1000000000000000000000000000000000000000000000000000000000000000 라는 16진수라고 가정해봅니다. 맨 앞이 1로 시작한다는게 중요합니다. 내가 어떤 입력값을 해싱해서 이 난이도 목표값보다 낮은 해시값을 찾으려 합니다. 근데 해싱의 특성상 입력값을 유추하는건 불가능합니다. 위의 해싱 리스트에서 맨 앞자리가 1보다 작은 해시값은 뭔가요? 바로 I am Satoshi Nakamoto13 뿐입니다.(해시 결과값이 0으로 시작하니 1보단 작은게 확실합니다) 답을 찾았습니다. 여기서 찾은 난스는 13입니다. 바로 이 것을 작업증명(Proof of Work) 계산이라고 합니다. 16진수의 하나인 0이 나오는 것은 확률적으로 16번이면 나오는데 물론 13번만에 나왔으니 운이 좋긴 했지만 위의 결과가 보여주듯 요건을 만족하는 nonce를 찾는건 쉬운건 아닙니다. 맨 앞자리만 비교해서 13번만 연산한거지, 수치적으로 더 많은 자리수를 비교하려면 엄청난 연산이 필요한겁니다. 게다가 비트코인 시스템은 컴퓨팅 파워의 발전과 함께 더 경쟁이 치열해졌고, 그에 따라 난이도도 어려워지도록 설계되었습니다. 채굴이 어떤 건지 대충 감이 오시나요? 딴거 없습니다. 그냥 수학적 계산일 뿐이죠. 어떻게 보면 블록체인과는 아무 상관도 없고, 블록 안에 포함된 앨리스의 거래와는 아무 상관도 없는, 단순 노가다 계산일 뿐입니다.
어떤 채굴자가 채굴에 성공(=난이도 목표보다 낮은 해시값을 찾는데 성공=작업증명에 성공)했다면 그 블록을 다른 네트워크 노드에 전달하게 됩니다. 당연히 블록 안에 있는 채굴자가 찾은 난스(여기서는 13이라는 숫자)도 전달됩니다. 그럼 다른 노드들은 그걸 검증하고 검증에 통과하면 각자 독립적으로 해당 블록을 거래장부에 추가합니다. 위에서 말한 합의 프로세스의 일부입니다. 근데 어떻게 검증을 할까요? 다른 채굴자들은 답을 못찾았는데 말입니다. 정답은, 그냥 정답을 찾은 채굴자에게 받은 난스를 가지고 자기도 해싱을 한 뒤, 그 결과값이 이전 블록의 난이도 목표보다 작다는 사실만 확인하면 됩니다. 이웃이 문제의 정답을 알려줬으니 쓰기만 하면 되는겁니다. 참 간단하죠. 작업을 검증하기 위해서는 단 1회의 해싱만 필요하지만, 유효한 난스를 찾는데는 13회, 아니 실제로는 수천 조, 수십 경이 넘는 해싱이 실행되야 합니다. 이게 바로 채굴과 합의입니다.
이 글을 쓸 시점에는 블록 헤더의 해시가 0000000000000000013eeb173c0b78a79dcdc606f0ef50fc3a025610bf433f38 인 블록의 난이도 목표보다 작은 블록에 대한 검색을 하고 있었습니다. 앞에 0이 엄청 있는것으로 보아 유효한 해시를 찾는게 엄청 어렵다는 걸 알 수 있습니다.
또 의문이 생깁니다. 컴퓨팅 파워는 시간이 흐를수록 나날이 발전하고, 난스 찾는건 갈수록 어려워지는데, 어떻게 채굴 인터벌은 늘 평균적으로 10분을 유지하는 것일까요? 정답은 블록의 헤더 안에 있는 난이도 값 때문입니다. 비트코인 시스템은 사토시가 처음 만들 때부터 블록이 10분 단위로만 만들어지도록 설계되었습니다. 근데 해싱이란 것은 암호화된 값이기 때문에 우리가 볼 때는 복불복입니다. 억세게 운이 좋으면 원하는 결과 값이 빨리 나올 수 있고 운이 나쁘면 아무리 해도 원하는 값이 안나오겠죠. 비트코인 시스템은 이 난이도 값을 조정하며 블록이 평균적으로 10분마다 생성되도록 유지합니다. 근데 유지를 하다니, 누가유지를 하는 것인가요? 그것 역시 시스템 안에 설계되어 있습니다. 사토시는 2,016개의 블록이 10분 간격으로 만들어지는데 필요한 시간인 2주(2,016블록*10분)마다 난이도를 조절하도록 설계했습니다. 2주만에 만들어져야 할 2,016개의 블록이 1주만에 만들어졌다면 난이도는 올라가고, 한 3주걸렸다면 난이도는 줄어들도록 말이죠. 이에 따라 난이도 목표값도 재설정되는데, 블록을 찾는데 걸리는 시간을 측정, 계산하여 매번 난이도 목표값을 재설정합니다.
// 작업증명 난이도 재설정 (bitcoin/src/pow.cpp 참조)
unsigned int CalculateNextWorkRequired(const CBlockIndex* pindexLast, int64_t nFirstBlockTime, const Consensus::Params& params)
{
    if (params.fPowNoRetargeting)
        return pindexLast->nBits;

    // Limit adjustment step
    int64_t nActualTimespan = pindexLast->GetBlockTime() - nFirstBlockTime;
    if (nActualTimespan < params.nPowTargetTimespan/4)
        nActualTimespan = params.nPowTargetTimespan/4;
    if (nActualTimespan > params.nPowTargetTimespan*4)
        nActualTimespan = params.nPowTargetTimespan*4;

    // Retarget
    const arith_uint256 bnPowLimit = UintToArith256(params.powLimit);
    arith_uint256 bnNew;
    bnNew.SetCompact(pindexLast->nBits);
    bnNew = bnNew * nActualTimespan;
    bnNew /= params.nPowTargetTimespan;

    if (bnNew > bnPowLimit)
        bnNew = bnPowLimit;

    return bnNew.GetCompact();
}
혹시 채굴할때 계산 방법이 ‘난이도 목표’보다 낮은 해시값을 찾는것인지, 그냥 ‘이전 블록의 해시값’보다 낮은 해시값을 찾는 것인지 헷갈릴 수 있습니다. 그 이유는 난이도 목표값이라는 항목 자체가 계수/지수 포맷으로 된 8자리 16진수 값이기 때문인데 이를 지수계산과 10진수 변환을 거친 후 다시 긴 16진수로 바꿔보면 결국 ‘이전 블록의 해시값’과 비스~읏 하게 나옵니다. 사실은 ‘난이도 목표’ 보다 낮은 해시값을 찾는게 맞습니다.
채굴의 목적을 설명하느라 길어졌네요. 그럼 위에서 언급한 채굴과정의 두 번째 목적, 화폐 발행 기능은 무슨 얘기일까요?
비트코인 발행계획
출처 : 피넥터
가상화폐인 비트코인의 총 발행량은 사토시가 처음 만들 때부터 2,100만 BTC로 정해져있는데, 2017년 현재 1600만 BTC 정도 발행이 된 상태입니다. 하나의 블록당 발행되는 비트코인은 현재 기준으로 약 12.5 BTC이며, 4년마다 반감기를 거쳐 2140년 정도 되면 발행이 끝나게 됩니다. 그 때가 되면 비트코인 발행 단위가 0.00000001 BTC(1사토시)가 될 만큼 줄어들기 떄문이죠.
여하튼 누군가는 발행을 한다는건데, 이걸 누구에게, 어떤 방식으로 주는걸까요? 비트코인은 탈중앙화된 환경이라는데 한국은행 역할은 누가 하는 것이죠? 바로 10분마다 채굴되는 블록을 통해 발행하게 되어 있습니다. 블록이 하나 체인에 쌓일 때마다 비트코인의 일부가 발행이 되는 것이죠.
앞서 얘기한 것처럼, 합의도출을 위한 분산화된 매커니즘을 갖고 있는 비트코인 생태계에선 누군가 계속 거래 장부를 만들어 나가는 노력을 해야 하는데, 이를 위한 방식으로는 작업증명 계산 프로세스를 사용하고 있습니다. 근데 채굴자들이 이걸 천문학적인 H/W 투자비용, 비싼 전기세 등을 바쳐가며 하는 이유는 뭘까요? 그 이유는 바로 10분마다 발행되는 이 따끈따끈한 신생 화폐를 얻기 위해서입니다. 비트코인 생태계는 이 화폐발행 기능을 통해서 채굴자들이 작업증명 계산을 하도록 유인합니다. 채굴에 성공한(=작업증명에 1등으로 성공한) 채굴자에게는 새롭게 발행한 비트코인을 보상(Reward)으로 주는 것이죠. 현재 비트코인 기준 발행량이 12.5BTC이고 시세가 1BTC당 USD 3천불 정도 하니까 한 번 성공하면 대략 원화 4천만원이 넘는 돈을 얻을 수 있네요. 10분에 4천만원이면 할만하지 않나요? PC사양이 별로 좋지 않은 개인 채굴자들은 채굴 풀(Pool)이라는 공동채굴단에 참여해서 마치 펀드처럼 본인이 투자한 컴퓨팅 파워만큼(PC사양) 분배받을 수도 있습니다.
어라? 이상하다. 비트코인은 중앙통제기구가 없는 생태계라는데 그럼 보상을 수여하는 주체는 누구일까요? 이 보상을 받는 방법은 의외로 간단한데, 채굴자가 자신이 만드려는 블록 안에, 보상으로 받을 새로운 비트코인이 “생성”되는 거래를 하나의 거래로써 포함시키는 것입니다. 일종의 셀프 보상인 셈이죠. 하지만 그냥 거래를 블록에 포함시켰을 뿐, 아직 승인된 것은 아닙니다. 채굴에 성공해야 받게 됩니다. 그리고 엄밀히 얘기하면 보상금만 있는 것은 아니고, 보상금과 함께 자신의 블록 안에 있는 모든 거래들, 즉 10분동안 전 세계 각지에서 접수된 거래들의 거래수수료까지 포함을 해서 합친 금액을 생성합니다. 2140년이 되어 더 이상 채굴할 비트코인이 없어지는 시대가 오면, 거래수수료만 생성하게 될 것입니다. 이런 생성거래는 채굴자의 비트코인 주소로 전송하는 하나의 출력값을 가지고 있기 때문에, 나중에 채굴에 성공하면 결국 채굴자에게 돌아갑니다. 물론 채굴에 실패하면 아무것도 못 얻습니다.
여기서 또 질문. 채굴하는 동안 쌓이는 거래는 어떻게 보관하고 있을까요? 네트워크로 전송된 거래는 블록체인에 올라가기 전까지는 검증되지 않습니다. 10분마다 새 블록이 생성될 때, 비트코인 네트워크 노드들은 이 상황을 지켜보다가 각 노드가 유지하고 있는 임시 풀(temporary pool)에 새로운 거래들을 추가시켜놓습니다. 물론 여기에는 미검증 거래들이 들어있겠죠. 거래들이 새 블록에 추가될 때는 거래의 age나(발생한지 얼마나 오래됐는지), 거래 수수료가 가장 높은 거래부터 우선적으로 추가되어(다른 기준도 있지만) 새로운 블록에 대한 작업증명 계산을 시작합니다. 만약 한창 계산하고 있는데, 억세게 운 좋은 다른 채굴자가 1분 만에 솔루션을 찾아서, 그 채굴자으로부터 새로운 블록을 받게 되면, ‘이번 라운드에서는 내가 실패했구나’ 깨닫고 재빨리 새 블록을 채굴하는 과정을 다시 시작합니다. 과거 따위는 신경쓰지 않아
다시 사토시의 합의 프로세스로 돌아오겠습니다.
비트코인 합의 매커니즘의 세 번째 단계는 모든 노드들이 받은 새 블록을 독립적으로 검증하는 것입니다. 왜 채굴자들은 블록 안에 무수히 많은 비트코인을 자신에게 전송하는 거래를 만들지 않을까요? 그것은 모든 노드가 동일한 규칙에 따라 블록들을 검증하기 때문입니다. 블록의 데이터 구조가 문법적으로 유효한지, 블록의 크기는 제대로인지, 머클트리 해시값은 맞는지, 거래 전부는 다 유효한지… (bitcoin/src/validation.cpp 참조) 때문에 채굴자들은 사실 여부를 속일 수 없는 것이죠. 비싼 전기세 내고 조작했다간 아까운 기회비용만 날리는 것입니다. 채굴자들은 모든 노드가 따르고 있는 공유 규칙에 따라 완벽한 블록을 구성해야 하고 그 블록을 채굴하기 위해 노력해야 합니다.
합의 프로세스의 마지막은 체인을 선택하는 일입니다. 체인은 왜 선택하는 걸까요? 블록체인은 분산화된 데이터 구조이므로 노드들이 각자 가지고 있는 복사본들이 서로 항상 동일한 상태를 유지하는 것은 아닙니다. 두 개의 블록이 각자 짧은 시간 내에 채굴되어 반대의 순서로 도착하거나, 여러가지 네트워크 환경에 따라 서로가 가지고 있는 블록체인이 불일치할 수 있습니다. 이 현상을 해결 하기 위해 각 노드는 여러 노드 중에서, 항상 작업증명을 가장 많이 시행한 노드의 블록체인을 선택해서 새로운 블록을 추가하려고 합니다. 이것을 최장 체인 혹은 최고 누적 난이도 체인(greatest cumulative difficulty chain) 이라고 합니다. 모든 노드가 이 최장 누적난이도 체인을 선택하는 한, 전 세계 비트코인 네트워크는 결국 일관된 상태로 수렴합니다.
한편, 이 합의도출 매커니즘을 기반으로 하는 비트코인 생태계는 사리사욕을 추구하지 않고 정직하게 작업하는 채굴자들이 다수를 차지한다는 신뢰를 바탕으로 하고 있습니다. 만약 특정 채굴자 집단이 채굴 파워 중 많은 부분을 획득하여 비트코인 네트워크의 보안을 위협하기 위해 합의 매커니즘을 공격한다면, 비트코인 생태계의 신뢰도는 크게 하락할 것이라는 비판이 있는 것도 사실입니다. 하지만 이에 대해 비트코인의 창시자인 사토시는 그의 논문에서 이렇게 설명합니다.
“If a greedy attacker is able to assemble more CPU power than all the honest nodes, he would have to choose between using it to defraud people by stealing back his payments, or using it to generate new coins. He ought to find it more profitable to play by the rules, such rules that favour him with more new coins than everyone else combined, than to undermine the system and the validity of his own wealth.”
“어느 탐욕스러운 공격자가 다른 모든 정직한 마이너들의 컴퓨팅 파워를 능가하게 된다면, 그는 가지고 있는 힘을 다른 이들의 비트코인을 훔치는 데에 사용할 지, 아니면 새로운 블록을 생성하여 코인을 획득하는 데 사용할 지를 선택해야 할 것이다. 그는 전체 시스템을 약화시킴으로써 자신이 보유한 비트코인의 가치를 떨어뜨리는 것 보다, 정해진 규칙에 따라 다른 모든 마이너들이 채굴할 수 있는 비트코인의 양보다 더 많은 코인을 확보함으로써 얻는 이익이 더 크다는 것을 알게 될 것이다.“
블록체인 거래장부
위의 그림을 살펴보면, 앨리스의 거래가 들어 있는 블록 #277316을 볼 수 있습니다. 최초 블록이 #0부터니까 앨리스의 거래 블록까지 277,316개의 블록이 존재한다고 볼 수 있으며 모두가 체인으로 연결되어 있습니다. 시간이 흘러 블록이 많아지면서 거래들의 신뢰도가 더 높아지고, 거래를 철회하기도 기하급수적으로 어려워집니다(관례상 6개의 블록 이전까지의 거래는 철회할 수 없다고 알려져 있음)

여기까지 대략적인 비트코인 작동원리에 대해 살펴보았습니다. 비트코인은 이론이 아니고 이미 현실화된 화폐시장입니다. 블록체인 탐색기를 이용하면 어떤 거래든, 블록이든, 해시든, 다 검색이 가능하니 직접 사용해 보면 이해가 더 쉽게 가능합니다. 비트코인 코어 클라이언트를 설치할 줄 안다면 json-rpc 인터페이스를 이용해서 원하는 정보를 데이터 형태로 조회할 수 있습니다.
비트코인, 더 나아가 블록체인의 미래는 누구도 확신할 수 없습니다. 비트코인은 현대 암호학과 IT기술, 계량경제학 등의 집약체이지만 아직도 많은 논의가 필요해보입니다. 한 쪽에서는 블록체인 거버넌스를 얘기하지만 다른 한 쪽에서는 비트코인 버블론, 종말론을 이야기합니다. 비트코인의 발행총량이 서서히 끝나가는 이 시점에, 과연 본격적인 디플레이션이 올지, 앞으로 디지털 현물자산의 법적 보증은 누가 할지, 스마트 컨트랙트를 탑재한 이더리움은 법률적 효력이 있을지 아직 아무도 알 수 없습니다. 계좌동결이나 강제인도 같은 현실 금융시장에서 필요한 기능이 비트코인 생태계에서 지원되지 않는 점도 큰 문제입니다. 하지만 그럼에도 불구하고 비트코인은 수 많은 집단지성에 의해 발전하고 있습니다.

2018년 1월 11일 목요일

tomcat sessionCookieName

<Context docBase="test" path="/" reloadable="true" source="org.eclipse.jst.jee.server:test sessionCookieName="test_egov_JSESSIONID" />

2018년 1월 10일 수요일

토탈커맨더_기능


ALT 조합
Alt + F1 왼쪽 패널 드라이브 바꾸기
Alt + F2 오른쪽 패널 드라이브 바꾸기
Alt + left/right : 작업한 폴더 간에 앞으로뒤로 이동하기
Alt + BackSpace : 한 단계 상위 폴더로 이동하기
Alt + down 작업했던 폴더 리스트 보여주기
Alt + Shift + Enter : 현재 폴더 안의 모든 하부 폴더의 용량을 <DIR> 표시 대신에 보여줍니다대신 ‘full’ 보기 모드일 때만 가능
Alt + ENTER : 파일 속성 보기단축 메뉴의 속성과 동일한 기능
Alt + F4 토탈 커맨더 종료

CTRL 조합
Ctrl + F1 'brief' 형식으로 리스트 보기 
Ctrl + F2 'full' 형식으로 리스트 보기 
Ctrl + Shift + F2 파일 주석 보기, Ctrl + Z로 주석을 달 수도 있음
Ctrl + F3 이름으로 리스트 정렬그냥 리스트 위에 Name 탭을 클릭하면 된다
Ctrl + F4 확장자로 리스트 정렬그냥 리스트 위에 Ext 탭을 클릭하면 된다
Ctrl + F5 날짜/시간으로 정렬
Ctrl + F6 파일 크기로 정렬
Ctrl + F7 정렬 않기
Ctrl + F8 반대쪽 패널에 탐색기 형식으로 폴더 구조 보여주기
Ctrl + F9 현재 커서 아래 파일을 연결 프로그램을 이용해 프린트하기
Ctrl + F10 모든 파일 보여주기
Ctrl + F11 실행파일만 보여주기
Ctrl + F12 정의된 파일만 보여주기

Ctrl + B 현재 패널에 하부 폴더의 리스트를 포함한 모든 파일 리스트 보여주기
Ctrl+Q : 파일 내용 빠르게 보기텍스트 문서나 이미지 파일 등을 반대쪽 패널에서 볼 수 있다


Ctrl + T 새 폴더 탭 열기 (활성화)
Ctrl + Shift + T 새 폴더 탭 열기 (활성화 하지 않음)
Ctrl + U 패널끼리 리스트 서로 바꾸기
Ctrl + Shift + U 패널끼리 리스트도 바꾸기 탭도 바꾸기
Ctrl + W 현재 활성화된 탭 닫기
Ctrl + Shift + W 모든 탭 닫기

Ctrl + D 디렉토리 핫리스트 열기자주 가는 폴더 등록시켜놓고 바로 가기


Ctrl + P : 현재 폴더 경로를 커맨드 라인에 붙여넣기
Ctrl + Enter : 현재 커서의 파일명을 커맨드 라인에 붙여넣기
Ctrl + Shift + Enter : 현재 커서의 파일명을 폴더명 포함해서 커맨드 라인에 붙여넣기
Ctrl + \ : 루트 폴더로 이동하기
Ctrl + PageUp : 루트 폴더로 이동하기 (위와 동일 기능)
Ctrl + left/right : 현재 커서가 위치한 폴더나 압축 파일의 내용을 반대편 패널에서 열기
Ctrl + L : 선택한 파일과 폴더의 총 용량 보여주기
Ctrl + UP 현재 커서의 폴더를 새 탭으로 열기
Ctrl + Shift + UP 현재 커서의 폴더를 다른 패널에 새 탭으로 열기
Ctrl + TAB 다음 탭으로 이동
Ctrl + Shift + TAB 이전 탭으로 이동

Function Key 조합
F3 : 텍스트 문서 보기이미지 파일 보기사운드 파일 듣기 등을 할 수 있는 종합 뷰어.
Alt + F3 다른 파일 뷰어(외부 뷰어사용하기이건 옵션에서 지정
Shift + F3 여러 개의 파일이 범위로 선택되어 있을 경우현재 커서가 위치한 파일만 본다

F4 기본은 텍스트 파일 편집하기
Shift + F4 텍스트 문서 하나 생성하기

F5 : 파일 복사하기압축 파일 내에서 필요한 파일만 압축을 해제하는 데에도 유용
Shift + F5 같은 폴더 아래 파일 이름만 바꿔서 복사하기.
Ctrl + Shift + F5 선택한 파일의 링크 파일 만들기
Alt+ F5 : 선택한 파일들로 압축 파일 만들기 (나중에 다시)
Alt + Shift + F5 파일 압축하기


F6 : 선택한 파일들을 반대쪽으로 이동
Shift + F6 : 선택한 파일 이름을 그 자리에서 직접 바꾸기
Ctrl + M : 파일명 일괄적으로 바꾸기

F7 : 새 폴더 만들기

F8 : 파일 삭제하기휴지통으로 이동
Shift + F8 : 파일 완전 삭제
Alt + F8 커맨드 라인의 히스토리를 보여주기

Alt + F7 : 파일 검색원하는 파일명으로 찾기폴더-파일 크기-날짜-속성 등으로 고급 검색하기파일 내에 있는 문자열로 찾기 등 다양한 검색 기능을 제공


Alt + F9 : 압축 파일 풀기,

Alt + F10: 더 트리 구조로 열기,


Shift 조합
Shift + F2 : 두 패널간에 파일 리스트 비교하기.

Shift + F10 : 단축 메뉴 보여주기즉 마우스 오른쪽 버튼을 누르면 나오는 팝업 메뉴

NUM 조합
NUM + : 특정 파일만 일괄 선택하기
NUM - : 특정 파일만 일괄 선택 해제하기
NUM * 파일 선택 반전시키기
NUM / 선택 복구
Ctrl+ NUM + : 모두 선택하기
Ctrl+ NUM - : 모두 선택 해제하기
Alt + NUM + 현재 커서가 위치한 파일과 동일한 확장자의 모든 파일 선택하기

FTP 관련
Ctrl + F : FTP 접속
Ctrl + Shift + F : FTP 접속 해제
Ctrl + Shift + M FTP 전송 모드 바꾸기
Ctrl + N 새로운 FTP 연결

2018년 1월 5일 금요일

was jeus7





xshell 에서 콘솔창 로그인
jues/>jeusadmin -u Jeustmax -p xxx



ms list
[DAS]jeus_domain.adminServer/>si


ms stop
[DAS]jeus_domain.adminServer/>stop-server server1

ms start
[DAS]jeus_domain.adminServer/>start-server server1