용어집 / 프로토콜과 업그레이드
스크립트 경로 지출
- 스크립트 경로 지출이란 무엇입니까?
- 스크립트 경로 지출은 리프 스크립트 1개와 이를 충족하는 입력값, 그리고 그 리프가 주소에 커밋되었음을 증명하는 제어 블록을 공개하여 Taproot 출력을 사용하는 방식입니다.
BIP-341에 명시되어 있습니다.
스크립트 경로 지출은 Taproot 출력에서 빠져나가는 대체 경로이며, 모두가 기대했던 협력 서명이 끝내 도착하지 않았을 때 사용합니다. 증명은 33바이트의 제어 블록에 실리고, 트리의 각 레벨마다 32바이트가 더해지며, BIP-341은 그 트리의 깊이를 128레벨로 제한합니다. 이 경로를 택하면 사용한 분기가 공개되므로, 실제로 의존했던 그 조건은 더 이상 비공개가 아닙니다.
작동 방식
스크립트 경로 지출을 검증하는 노드는 위트니스 스택을 뒤에서부터 읽습니다. 마지막 요소가 작업의 대부분을 하기 때문입니다.
그 마지막 요소가 제어 블록이며, 길이는 무엇보다 먼저 검사합니다. 0에서 128 사이의 정수 m에 대해 정확히 33 + 32m바이트여야 하고, 다른 길이는 곧바로 실패합니다. BIP-341이 상한을 128로 두는 이유는, 최적으로 채운 트리에서 더 깊은 곳까지 가는 경우는 사용될 확률이 2^128분의 1 미만인 리프뿐이기 때문입니다.
첫 번째 바이트는 서로 무관한 두 가지를 담습니다. 0xfe로 마스킹하면 리프 버전이 나오며, tapscript 규칙에서는 0xc0입니다. 마스킹으로 지운 비트는 출력 키의 Y 좌표 패리티이며, 지출을 일괄 검증할 수 있도록 존재합니다. 다음 32바이트는 내부 공개 키로, 협력 지출에 서명했을 키입니다. 그 뒤의 모든 것은 머클 경로이며 레벨마다 32바이트입니다.
그 다음 노드는 커밋을 재구성합니다. 리프 버전과 공개된 스크립트를 해시하여 탭리프 해시를 만들고, 경로의 각 요소를 차례로 접어 넣습니다. 방향은 전송되지 않습니다. 각 단계의 32바이트 값 두 개를 해싱 전에 사전순으로 정렬하므로 그 비교가 순서를 정하고, 방향 비트는 보내지 않습니다. 루트와 내부 키가 트윅을 만들고, 트윅된 키가 패리티 비트를 포함해 주소에 들어 있는 32바이트와 일치해야 스크립트 실행이 허용됩니다.
바이트 하나가 그 앞의 모든 것을 바꿀 수 있습니다. 위트니스가 최소 두 요소를 담고 마지막 요소가 0x50으로 시작하면, 그 요소는 검증이 시작되기 전에 액넥스로 제거됩니다. BIP-341은 이에 어떤 의미도 정의하지 않으며, 액넥스를 포함하면 "PERMANENT FUND LOSS"(영구적 자금 손실)로 이어질 수 있다고 경고합니다.
확인할 수 있는 곳
스크립트 경로 지출은 블록 탐색기에서 액넥스를 제외한 위트니스가 두 개 이상의 요소를 담은 Taproot 입력으로 식별됩니다.
BIP-341의 예시는 A부터 E까지 다섯 스크립트로 된 트리입니다. 스크립트 D로 지출하면 D가 공개되고, 내부 키와 세 개의 해시, 즉 C, E, 그리고 A와 B의 결합 해시를 담은 제어 블록이 함께 공개됩니다. 그 제어 블록은 다섯 조건 계약에 대해 129바이트이며, 나머지 네 스크립트는 공개되지 않습니다.
그 증명은 또한 무언가를 드러냅니다. BIP-341의 보안 섹션은 공개된 리프의 깊이가 트리의 최소 깊이를 누설한다고 지적하며, 이것이 "suggests specific wallet software that created the output and helps clustering"(출력을 만든 특정 지갑 소프트웨어를 암시하고 클러스터링을 돕는다)라는 뜻이라고 밝힙니다. BIP-341이 제안하는 방어책은 리프 확률이 최적으로 만들었을 트리에서 벗어나는 것입니다.
같은 섹션은 키 재사용에 대해 단호합니다. 키는 지출한 리프만이 아니라 모든 리프에서 새로워야 합니다. 반복된 분기는 이후 증명에서 반복된 해시로 다시 나타나고, 키를 공유하는 리프는 공개되지 않은 스크립트를 무차별 대입하기 쉽게 만들기 때문입니다.
스크립트 경로 지출 vs tapscript
스크립트 경로 지출은 경로이고, tapscript는 그 끝에서 쓰이는 언어입니다. BIP-341은 실행이 시작되는 순간까지의 모든 것, 즉 제어 블록, 정렬된 머클 접기, 트윅 검사, 패리티 비트를 정의합니다. 그 뒤에 실행되는 것은 리프 버전이 정합니다.
현재 0xc0만이 tapscript를 뜻합니다. 다른 버전을 담은 리프도 오류가 아닙니다. BIP-341은 알 수 없는 리프 버전에 대해서도 실행이 성공해야 한다고 요구하기 때문입니다. 이것이 이후 소프트 포크가 같은 bc1p 주소 형식 안에서 다른 스크립트 언어를 정의할 수 있게 하는 연결 고리이며, 스크립트 경로 지출을 이 쌍의 오래 남는 절반으로 만듭니다.