블록체인은 왜 필요했을까: 서명이 못 막는 이중 지불
디지털 서명은 남의 돈을 내가 보내지 못하게 막습니다. 그럼 내 돈을 두 번 보내면 어떨까요? 영희가 같은 1만 원을 가게 A 와 가게 B 에 보냅니다. 은행이 없다면 무엇이 막을까요?
서명이 맞는 거래 두 개
돈은 하나인데 거래는 둘입니다(그림 1). 이것을 이중 지불이라고 합니다 [S2].
두 거래 모두 영희가 자기 개인 키로 서명합니다. 가게는 영희의 공개 키로 그 서명을 검증합니다. 직접 보내 보세요.
영희의 공개 키
가게 A 가 받은 거래
아직 보내지 않음
가게 B 가 받은 거래
아직 보내지 않음
서명과 검증에는 브라우저의 서명 기능(Web Crypto, ECDSA)을 씁니다. 곡선은 P-256 입니다. 비트코인은 secp256k1 곡선을 쓰지만 [S4], Web Crypto 표준에는 그 곡선이 없습니다 [S5]. 거래의 모양은 이 글이 정한 교육용입니다.
둘 다 ✓ 입니다. 서명 검증은 거래를 하나씩 봅니다. «영희가 이 거래에 서명했는가» 는 알려 주지만, 같은 돈으로 다른 거래에도 서명했는지는 알려 주지 않습니다. 비트코인 백서도 받는 쪽은 앞 주인이 그 돈을 이중 지불하지 않았는지 검증할 수 없다고 짚습니다 [S1].
은행은 어떻게 막나, 은행이 없으면
가운데에 한 곳을 두면 쉽습니다. 모든 거래가 그곳을 지나면, 그곳에서 어느 거래가 먼저 왔는지 정합니다. 먼저 온 거래만 인정하면 됩니다 [S1]. 은행이 하는 일입니다. 대신 돈 전체가 그 한 곳에 달려 있습니다 [S1].
그 한 곳 없이 하려면 두 가지가 필요합니다. 거래를 모두에게 공개하고, 참여자들이 거래의 차례를 하나로 합의해야 합니다 [S1]. 풀어야 할 것은 서명이 아니라 차례였습니다.
블록이 차례를 정한다
블록체인은 그 차례를 적는 방법입니다. 네트워크의 컴퓨터들이 거래 여러 개를 블록 하나로 묶습니다. 각 블록에 앞 블록의 해시 값을 넣어 한 줄로 잇습니다(그림 2) [S1]. 이 사슬이 거래의 차례를 적은 장부가 됩니다 [S3]. 새 블록은 네트워크의 모든 컴퓨터에 전해지고 [S1], 저마다 검사해 자기 사슬에 잇습니다. 그래서 보통은 모두 같은 사슬을 갖습니다 [S3].
규칙은 은행과 같습니다. 블록에 든 거래가 이미 쓴 돈을 또 쓰면, 네트워크의 컴퓨터들은 그 블록을 받지 않습니다 [S1]. 같은 돈은 블록체인에서 한 번만 쓸 수 있습니다 [S3]. 먼저 든 것만 인정합니다.
두 거래가 동시에 다른 블록에 들어가면
블록을 만드는 곳은 여럿입니다. 두 곳이 거의 같은 때에 블록을 만들면 사슬이 잠깐 둘로 갈라집니다 [S3]. 한쪽 블록에는 가게 A 로 가는 거래가, 다른 쪽에는 가게 B 로 가는 거래가 들었다고 합시다. 어느 쪽이 남을까요?
다음 블록이 어느 쪽에 붙을지는 난수로 흉내 냅니다(양쪽 계산력이 같다고 두어 반반). 실제 작업 증명 계산이 아닙니다. 블록의 해시 값은 실제 SHA-256 으로 계산합니다.
네트워크의 컴퓨터들은 가장 긴 사슬을 옳은 것으로 봅니다. 여기서는 블록마다 드는 작업이 같다고 둡니다. 다음 블록이 한쪽에 붙어 그쪽이 길어지면 모두 그쪽으로 옮깁니다 [S1]. 짧은 쪽 블록은 버려집니다 [S3]. 그 블록에 있던 가게 B 로 가는 거래는, 남은 사슬에서는 이미 쓴 돈을 또 쓰는 거래라 다시 들어가지 못합니다. 앞 장의 «먼저 든 것만» 규칙 그대로입니다. 같은 돈을 쓰지 않는 다른 거래라면 대기 줄로 돌아가 뒤 블록에 들어갈 수 있습니다 [S2].
어느 쪽이 남을지는 다음 블록이 나오기 전에는 알 수 없습니다. 쌓인 블록도 더 긴 사슬에 덮일 수 있습니다. 그래서 받는 쪽은 보통 자기 거래가 든 블록 위에 블록이 몇 개 더 쌓일 때까지 기다립니다 [S2].
그 차례를 못 고치게
남은 걱정은 영희가 지난 차례를 고쳐 쓰는 것입니다. 가게 A 에서 물건을 받은 뒤 그 거래가 없는 사슬을 따로 더 길게 만들어 내놓으면 돈을 되찾으려 할 수 있습니다 [S1]. 이것을 어렵게 하는 것이 작업 증명입니다. 블록을 만들려면 조건에 맞는 해시 값을 찾는 계산(작업)을 해야 합니다 [S1].
뒤 블록이 앞 블록에 이어져 있습니다. 지난 블록 하나를 고치려면 그 뒤 모든 블록의 작업도 다시 해야 합니다 [S1]. 블록이 어떻게 이어져 있는지, 그 작업이 왜 비싼지는 다음 글부터 차례로 다룹니다.
한계도 있습니다. 백서의 조건은 정직한 쪽이 계산력의 과반을 쥐고 있는 것입니다 [S1]. 그래서 블록체인은 «절대 못 고치는 장부» 가 아닙니다. 고치면 드러나고, 고치기 어려운 장부입니다 [S2].
이 글의 계산과 확인
시뮬레이터 ① 은 서명·검증에 브라우저의 Web Crypto ECDSA(P-256 곡선, SHA-256)를 씁니다. 키는 페이지를 열 때마다 새로 만들고, 어디에도 보내지 않습니다. 비트코인이 쓰는 secp256k1 곡선 [S4] 은 Web Crypto 표준이 정한 곡선(P-256·P-384·P-521)에 없어 [S5] 곡선만 바꿨습니다. «서명이 두 거래를 구별하는가» 는 곡선과 상관없습니다.
거래와 블록의 모양, «같은 돈을 쓰는 거래는 먼저 든 것만 유효» · «더 긴 사슬이 남는다» 를 판정하는 코드는 이 글이 직접 짠 교육용입니다 (실제로 쓰지 말 것). 실제 비트코인의 거래·블록 형식이 아니고, 시뮬레이터 ② 는 작업 증명을 하지 않습니다. 시뮬레이터의 블록은 만드는 데 드는 작업이 모두 같다고 둡니다. 그래서 «가장 긴 사슬» 이 곧 «다시 만들기 가장 어려운 사슬» [S3] 입니다.
같은 계산을 Node 의 crypto(OpenSSL)로 교차 확인했습니다. Node 는 같은 돈을 쓰는 두 거래의 서명을 모두 검증했습니다. Node 가 만든 서명도 이 글의 검증을 통과했습니다. 받는 이·금액·서명 한 비트를 고치거나 다른 키를 쓰면 검증에 실패합니다. 사슬에 먼저 든 거래만 유효로 판정하고, 갈라진 사슬에서 긴 쪽을 고르며, 버려진 블록의 거래가 남은 사슬에 다시 들어가지 못하는 것도 시험했습니다 (verify.mjs 47개 통과).
출처
- [S1] Nakamoto, Bitcoin: A Peer-to-Peer Electronic Cash System (2008) — §2, §3, §4, §5, §11
- [S2] NIST IR 8202, Blockchain Technology Overview (2018) — §4.7, §7.1, 용어집
- [S3] Bitcoin Developer Guide — Block Chain
- [S4] Bitcoin Developer Guide — Transactions
- [S5] W3C, Web Cryptography API — Named Curve