Segregated Witness에 관한 몇 가지 Tech Info

1. Segregated Witness 란?
Segregated Witness는 최근 bitcoin 프로그램에 추가된 기능중 가장 중요한 기능으로 이야기되고 있다. 그동안 이 난해한 이름 때문에(우리말로 옮겨보자면 "격리된 증거" 정도가 되겠다) 이것에 대해 자세히 알아볼 엄두가 나지 않았는데 라이트닝 네트워크에서도 계속 언급이 되고 있어서 좀더 찾아봤다.
스펙문서는 난해하고 어떻게 soft fork가 가능한지 설명이 제대로 안되어 있어서 soft fork 관련해서는 upgrade guide 및 그 블로그의 몇몇 관련 글을 찾아볼 필요가 있다. 구글링으로는 Segregated Witness에 대한 개념적인 소개 외에 상세한 설명을 찾기 어렵고, 오해하고 있는 글들도 꽤 보인다.

2. TXID 란?
우선 비트코인 트랜젝션의 아이디인 txid가 뭔지부터 시작해보자. 비트코인에서 모든 종류의 id는 해시를 통해 생성하는데 txid 역시 트랜젝션 데이타를 해시해서 생성한다. 트랜젝션 데이타에는 버전, input, output, nLockTime 이 포함되므로 txid = SHA256(SHA256(version|input|output|nLockTime)) 으로 계산된다. input은 coin의 출처, output은 coin을 받을 주소다. coin의 출처는 항상 다른 트랜젝션의 output이 되야 하므로 input은 다른 트랜젝션의 txid를 포함하고 있다. 즉 txid는 지불할 돈의 근거를 나타낼때 쓰이므로 중요하다.

그런데 여기서 한가지 문제가 생긴다. input에는 이전 트랜젝션의 txid 뿐만 아니라 그 트랜젝션에 있는 돈의 주인임을 증명하는 서명(signature)이 함께 포함되어 있다. 이 서명은 자신(이 트랜젝션을 생성하는 사람)이 주인이라는 걸 증명하면서 동시에 서명된 트랜젝션의 변경을 방지하는 두 가지 효과가 있다. (이게 전자서명의 기본 동작이다). 비트코인에서 이 서명은 실제 서명과 함께 일련의 OP code들로 이루어져 있어서 다양한 형태의 계약을 작성할 수 있다. 이 서명과 일련의 OP code들을 signature script라고 부른다. 좀 복잡하지만 포함관계를 보면 transaction은 input을 포함하고 있고, input은 signature script를 포함하고 있고, 이 signature script에는 이 전체 transaction에 대한 서명이 포함된다. 그런데 먼저 transaction data가 fix되야 이걸 서명할 수 있을테니 signature script를 제외한 transaction data를 기준으로 서명을 생성하고 이걸 transaction에 포함시킨다. 

복잡하지만 위 포함관계는 몰라도 상관없다. 중요한건 signature script가 서명되지 않기때문에 signature script는 변조의 가능성이 생긴다는 것이다. 예를들어, signature script 안에 있어도 그만 없어도 그만인 OP code를 하나 추가한다고 해도 여전히 이 transaction은 valid 할 것이다. signature script는 변조됐지만 다른 내용은 그대로이니 돈은 원래 의도했던 대로 지불이 될 것이다. 유일하게 달라지는건 이 전체 transaction data의 해시값인 txid 뿐이다.

3. Transaction malleability 해결 방안
앞에 설명한 문제를 transaction malleability 라고 부른다. txid가 바뀐다고 해서 거래내용이 달라지는건 아니지만 이 값이 바뀔 가능성이 있다는 것 때문에 몇 가지 골치아픈 문제가 생길 수 있다. 예를들어, 해당 거래가 승인이 되었는지 트래킹하려면 txid를 기준으로 모니터링이 필요한데 txid가 바뀌어버리면 트래킹이 안된다. 그리고 이  txid를 기준으로 새로운 transaction을 만들고 싶은 경우에도 txid가 바뀌어버리면 이걸 참조하는 transaction이 invalid 해지는 문제가 생긴다. 이 문제가 존재하면 몇 개의 transaction을 엮어서 smart한 계약을 작성하는 기법을 사용하는 라이트닝 네트워크는 불가능해진다.

txid가 변경되는 문제를 해결하는 가장 명확한 방법은 txid 생성의 대상이 되는 transaction data에 signature script를 포함시키지 않는 것이다. transaction data에는 얼마의 돈을 어디서 어디로 보내는지 하는 내용만 포함하고, 이 transaction data의 validity를 체크하기 위한 signature script는 별도로 관리하겠다는 것이 Segregated Witness의 기본적인 발상이다. signature script를 모아서 witness 라는 구조를 따로 만들고 이걸 아예 블록에서 제외시켰다. 트랜젝션 검증을 안하는 스마트폰 월릿 같은 SPV client는 witness 블록이 필요없으니 더 적은 양의 데이타만 받으면 되고 full node 들은 일반 블록 외에 witness 블록을 추가로 전달받는 방식이다. 

4. Block size 문제
일반 블록에서 signature script가 제외되니 기존의 1MB 공간에 더 많은 transaction을 담을 수 있게 되어서 자연스럽게 block size 이슈도 어느 정도 해결이 된다. 블록 크기를 늘리는 문제는 꽤 민감한 사안이었기 때문에 Segregated Witness로 이 문제를 해결하겠다는 발상은 큰 반발을 불렀지만 여기선 언급하지 않겠다.

5. Soft fork 기법
블록의 구조가 변경되는 사항이므로 기존 프로그램과는 호환이 안될 것이라 hard fork가 필요한 변경이고 처음에는 hard fork로 추진이 되었는데, 기발한(?) 꼼수 덕분에 soft fork로도 가능하게 구현이 되었다. 덕분에 Segregated Witness 스펙이 더 복잡하고 이해하기 어려운 것이 되긴 했다. 그럼 어떻게 기존 노드들과 호환이 되도록 블록구조 변경이 가능했는지 알아보자.

우선 기존 노드들에게 서명 없이도 transaction 검증을 통과시키기 위해서 트랜젝션의 signature script를 any-one-can-pay 형태로 변경시킨다. 기존 노드들은 검증이 필요없는 트랜젝션이라 판단하고 그냥 통과시킨다. 신규 노드는 이게 any-one-can-pay  script가 아니라 Segregated Witness 전용 script라는걸 파악하고 witness data를 참조해서 기존처럼 검증한다. 기존 노드는 검증을 안하는데 그럼 문제가 되는것 아닐까? 당연히 문제가 된다. 그래서 이 soft fork는 Segregated Witness를 지원하는 노드가 전체 노드의 95% 이상 될때까지 activation되지 않는다. 즉, 신규 노드들도 예전 노드와 동일한 방식으로 블록을 생성하다가 95% 이상 되는 시점에 일시에 블록 생성 방식을 바꾸는 것이다. 그럼 5% 노드는 트랜젝션 검증을 안하지만 나머지 95%가 검증하니까 문제가 되지 않는다.

또 한가지. 기존 블록에는 witness data를 연결시킬 고리가 없다. 블록 해더에는 transaction들의 merkle root가 포함되어 있어서 트랜젝션과 블록을 연결시킨다. witness와 블록을 연결시키려면 witness들의 merkle root를 블록 해더에 포함하는 것이 일관된 방식일 것이나 이렇게 바꾸면 기존 노드와 호환이 되지 않는다. 따라서 witness의 merkle root는 coinbase transaction의 signature script에 포함시켰다. coinbase transaction은 검증이 필요없는 transaction이므로 아무거나 포함시킬 수 있으니.

덧글

댓글 입력 영역



통계정보