비트코인 세그윗: WHY
지난 포스팅에서 비트코인이 업그레이드 하는 방식에 대해 다뤘습니다. 이번 글부터는 세그윗에 대해서 알아보려고 합니다.
세그윗 업그레이드
세그윗은 Segregated과 Witness의 앞부분을 딴 표현으로 "분리된 증인"이라는 뜻입니다. 2015년 Pieter Wuille과 비트코인 개발자에 의해 제안되었으며, 일반적으로는 다음과 같이 알려져있습니다.
서명 데이터를 트랜잭션 데이터에 분리시켜 '증인' 데이터로 구분하며, 이를 통해 확장성과 보안성을 개선한 업그레이드.
다만 그냥 넘어가기엔 상당히 모호한 표현이라 생각됩니다. 구분한 게 어떻게 확장성과 보안성을 개선하는걸까? 이걸 통해서 우리는 정확히 어떤 이득을 보고 있을까?
블록체인을 포함한 소프트웨어 업그레이드는 크게 세 가지 포인트를 살펴볼 수 있습니다.
- 이유(Why): 왜 했는가?
- 방법(How & What): 어떻게 했는가? 무엇이 바뀌었나?
- 과정(Process): 어떤 과정을 통해 합의에 이루었나?
세그윗이 해결하고자 한 문제는 무엇이었을까요?
거래 가변성(Transaction Malleability)
우선 가장 근본적인 문제로 거래 가변성에 대해서 알아야 합니다. 거래 가변성은 비트코인 트랜잭션의 ID(TXID)가 트랜잭션이 블록에 포함되기 전에 변경될 수 있는 성질을 의미합니다. 트랜잭션의 순서와 트랜잭션의 형태에 대해서 더 알면 더 직관적으로 알 수 있습니다. 비트코인 트랜잭션은 다음 순서로 동작합니다.
- 트랜잭션 생성: 사용자가 트랜잭션을 생성하고 서명합니다.
- 브로드캐스트(broadcast): 서명된 트랜잭션이 비트코인 네트워크에 브로드캐스트됩니다.
- 검증 및 전파(propagation): 네트워크의 노드들이 트랜잭션을 받아 검증하고, 다른 노드들에게 전파합니다.
- 블록 생성: 마이너가 트랜잭션을 블록에 포함시키고, 블록을 생성합니다.
문제는 3에서 발생합니다. 서명은 되어있으나 블록에 포함되기 전 데이터를 조작할 수 있습니다. 정확히는 조작된 새로운 트랜잭션을 만들 수 있습니다.
- 무의미한 연산 추가: 서명 스크립트의 기본 형태가
<signature> <pubkey>
라고 할 때,<signature> <pubkey> OP_NOP
라는 트랜잭션을 추가로 만들 수 있습니다. (여기서OP_NOP
은 거래 자체에는 아무 영향도 주지 않는 연산) - 같은 의미지만 다른 표현: 또는 서명을 넣는 방식에 대해 의미는 같지만 형태는 다
OP_PUSHDATA2 <len> <signature> <pubkey>
와 같은 형태로 트랜잭션을 만들 수 도 있습니다. - 신규 트랜잭션: 수신자는 다른 노드에 브로드캐스팅함으로 수신자가 다른 트랜잭션을 보낼 수도 있습니다.
이렇게 되면 같은 입력에 대해 서로 다른 해시값 ID를 가지는 2개의 트랜잭션이 만들어집니다.
이중 지불 문제 (Double Spending)
제목만 보고 자산 2배 이벤트를 상상하셨다면, 아쉽게도 그것은 불가능합니다. UTXO 구조에서 같은 인풋에서 나온 트랜잭션은 하나만 포함되게 됩니다. 그리고 나머지 하나의 트랜잭션은 이중 지불로 인해 실패하게 됩니다. 그럼 우선 두 가지 케이스를 분리해서 살펴보겠습니다.
- 트랜잭션의 수신자와 트랜잭션 ID가 모두 다른 케이스 (서로 다른 노드를 통해 브로드캐스트)
- 트랜잭션의 수신자는 같지만, 트랜잭션 ID가 다른 케이스
1의 케이스는 특정 재화나 서비스를 제공하는 수신자가 피해볼 수 있는 상황입니다. 수신자는 브로드캐스트된 트랜잭션의 형태를 통해 블록 포함 이전(zero-confirmation)에 빠르게 확인하고 서비스를 제공할 수 있습니다. 그러나 위 공격을 통해 이중 지불 문제로 해당 트랜잭션은 취소되고, 다른 트랜잭션이 블록에 포함될 수 있습니다. (수수료 등을 통해 의도적인 공격 가능하며, 이를 막기 위해 Replace-by-Fee 방법 등이 제안되었음) 즉, 수신자는 트랜잭션 ID를 확인하고 이에 대해 서비스를 제공했는데, 그 트랜잭션은 취소되고 수신자는 바뀌는 사례가 나올 수 있습니다.
그렇다면 블록에 포함된 이후에 서비스를 제공하면 되는거 아닐까요? 맞습니다. 블록에 완전하게 컨펌되고 서비스를 제공하면 되긴 합니다. 다만 비트코인의 트랜잭션은 포함된 첫 번째 블록에서 거래의 유효성이 바로 검증되는 것이 아닌 통상 6개의 블록 이후에 확정(Confirmation)됩니다. 대략 1블록에 10분 정도이니 약 1시간의 시간이 소모됩니다. 한 서비스를 제공하는 데 1시간이나 걸린다면 실제로 사용하기에는 무리가 있습니다.
라이트닝 네트워크(Lightening Network)
그렇다면 2번의 케이스는 어떤 것이 문제일까요? 대표적인 문제 중 하나는 트랜잭션 ID를 서로 참조하여 사용하는 라이트닝 네트워크 등의 솔루션에서 문제가 됩니다. 라이트닝 네트워크는 비트코인의 확장성 문제를 해결하기 위해 제안된 오프체인 솔루션입니다. 참가자들 간에 별도의 지불 채널을 열고, 이 채널 내에서 트랜잭션을 주고 받습니다. 채널을 닫을 때 최종 상태가 비트코인에 기록됩니다.
여기서 핵심적인 트랜잭션은 2가지입니다.
- 커밋먼트 트랜잭션(commitment transaction): 각 참가자가 채널의 현재 상태를 기록하기 위한 트랜잭션
- 패널티 트랜잭션(penalty transaction): 상대방이 오래된 커밋먼트 트랜잭션을 블록체인에 제출하는 경우, 이에 대한 대응으로 생성되는 트랜잭션
문제는 이 두 트랜잭션은 서로의 트랜잭션 ID를 참조합니다. 패널티 트랜잭션은 커밋먼트 트랜잭션 ID를 사용하여, 해당 커밋먼트 트랜잭션의 출력을 입력으로 사용합니다. 하지만 위의 트랜잭션 가변성으로 인해 커밋먼트 트랜잭션 ID를 바꿀 수 있다면? 패널티 트랜잭션은 유효하지 않게 되고 이는 라이트닝 네트워크 보안을 크게 위협할 수 있습니다.
이런 트랜잭션 ID에 대한 안정성, 즉 거래 가변성을 해결해야만 블록체인의 사용성과 L2 등의 솔루션을 만들 수 있게됩니다.