본문으로 건너뛰기
buybitcoinsmart

용어집 / 트랜잭션과 수수료

SIGHASH_SINGLE

SIGHASH_SINGLE란 무엇입니까?
SIGHASH_SINGLE는 서명을, 목록에서 서명 대상 입력과 같은 위치에 있는 출력 하나에만 묶는 플래그입니다.

입력 0은 출력 0과, 입력 1은 출력 1과 짝을 이루며, 트랜잭션의 나머지 모든 부분은 서명되지 않은 채 남습니다. 이 설계를 통해 여러 당사자가 하나의 공유 트랜잭션 안에서 각자의 지급액을 보장할 수 있습니다. 또한 이 플래그는 레거시 입력에 여전히 남아 있는, 비트코인에서 가장 악명 높은 서명 버그를 함께 지니고 있습니다.

작동 방식

다이제스트는 서명 대상 입력, 트랜잭션 버전, 록타임, 그리고 정확히 하나의 출력, 즉 인덱스가 해당 입력의 인덱스와 일치하는 출력을 유지합니다.

그 인덱스보다 뒤에 있는 출력은 해싱 전에 사본에서 제거됩니다. 그보다 앞에 있는 출력은 자리표시자로 유지되지만 비워지며, 값은 -1로, 스크립트는 빈 스크립트로 설정되므로 그 실제 내용 역시 포함되지 않습니다. 다른 모든 입력의 시퀀스 번호는 출력 없음 플래그에서와 마찬가지로 0으로 설정됩니다.

그다음에 버그가 나옵니다. 원래 알고리즘에서는 서명 대상 입력의 인덱스가 출력 개수보다 크거나 같으면 해싱할 일치하는 출력이 없습니다. 이때 코드는 실패하는 대신 고정된 다이제스트를 반환합니다. 바로 32바이트 값 1입니다. 이 위치에 놓이는 모든 서명자는 동일한 다이제스트에 대한 서명을 생성하므로, 그 서명은 특정 트랜잭션에 묶이지 않으며 같은 인덱스에 입력을 배치할 수 있는 사람은 누구나 이를 들어내어 재사용할 수 있습니다. 이 분기는 이미 체인에 있는 코인의 유효성을 바꾸게 되므로 삭제할 수 없어, Bitcoin Core에 오늘날까지 남아 있습니다.

서명 해시 알고리즘의 두 차례 재작성이 이 문제를 닫았습니다. BIP143은 일치하는 출력이 없는 segwit 버전 0 입력의 경우 다이제스트의 출력 부분이 32바이트 0이 되며, 다이제스트의 나머지 부분은 여전히 그 특정 입력에 결속되므로 재사용할 수 있는 것이 없다고 규정합니다. BIP341은 더 나아갑니다. Taproot 입력에서 출력 개수를 넘는 인덱스를 가진 이 유형의 서명은 그냥 검증에 실패합니다.

나타나는 곳

이 플래그는 서명 끝에 붙는 03으로 나타나며, 일반 결제보다는 거의 전적으로 미리 서명된 제안 안에서 발견됩니다.

그 패턴은 초대장처럼 공개된 반쪽짜리 트랜잭션입니다. 판매자는 "내 이 입력이 들어가고, 일치하는 인덱스의 출력이 내가 요구하는 가격을 나에게 지급한다"는 진술에 서명한 뒤, 트랜잭션의 나머지는 구매자가 채울 수 있도록 비워 둡니다. 판매자의 서명이 다른 모든 입력과 출력을 무시하기 때문에, 구매자는 자신의 자금과 자신의 잔돈, 그리고 멤풀이 요구하는 수준의 수수료를 얼마든지 추가할 수 있으며 판매자의 보장은 그대로 유지됩니다. 오디널스와 룬 마켓플레이스는 정확히 이 원리로 만들어져 PSBT 형태로 배포되며, 이는 비트코인이 제3자 없이 지원하는, 진정으로 신뢰가 필요 없는 거래 중 하나입니다.

이 플래그는 거의 항상 ANYONECANPAY와 함께 쓰입니다. 그 자체로는 여전히 전체 입력 목록에 결속되므로, 다른 누군가가 완성하도록 트랜잭션을 열어 두려는 목적이 무산되기 때문입니다.

SIGHASH_SINGLE vs SIGHASH_ANYONECANPAY

SIGHASH_SINGLE는 기본 모드이고 SIGHASH_ANYONECANPAY는 수정자이므로, 둘은 서로 다른 질문에 답합니다. 기본 모드는 서명이 출력 쪽을 얼마나 포함하는지를 정합니다. 전부, 전무, 또는 일치하는 하나의 출력입니다. 수정자는 입력 쪽을 얼마나 포함하는지를 정합니다. 모든 입력, 또는 서명 대상 입력 하나뿐입니다. 기본 모드를 하나 고른 뒤 수정자를 추가할지를 따로 정하며, 그래서 실제 서명의 플래그 바이트는 보통 둘 중 하나가 아니라 둘의 합입니다.

혼동하기 쉬운 용어

자주 묻는 질문

SIGHASH_SINGLE 버그란 무엇입니까?

원래 서명 알고리즘에서는 일치하는 출력이 없는 입력 인덱스가 오류 대신 값 1의 고정된 다이제스트를 생성합니다. 그 다이제스트에 대한 서명은 어떤 트랜잭션에도 묶이지 않으며 다른 누군가가 재사용할 수 있으므로, 지갑은 결코 그 위치에서 서명해서는 안 됩니다.

이 버그는 아직도 악용할 수 있습니까?

원래 알고리즘을 여전히 실행하는 레거시 입력에서만 가능합니다. SegWit 입력은 BIP143을 따르며 대신 0바이트를 해싱하고, Taproot 입력은 BIP341에 따라 해당 경우를 아예 거부하므로, bc1 주소에 보관된 코인은 영향을 받지 않습니다.

관련 용어

트랜잭션과 수수료 분야의 다른 용어

이 페이지를 영어로 읽기