SIGHASH_SINGLE (Signature Hash Type)

고급블록체인수정일

SIGHASH_SINGLE은 비트코인 트랜잭션 서명에 쓰는 서명 해시(sighash) 유형의 하나입니다. 서명하는 입력과 같은 인덱스 번호를 가진 출력 하나와 모든 입력을 서명 대상에 넣고, 다른 출력과 다른 입력의 시퀀스 번호는 서명에서 제외합니다.

자세히 알아보기

비트코인 서명은 트랜잭션 전체가 아니라 sighash 유형이 정한 부분만 서명합니다. 주요 유형은 다음과 같습니다.

  • SIGHASH_ALL(0x01): 모든 입력과 모든 출력을 서명합니다. 기본값입니다.
  • SIGHASH_NONE(0x02): 출력을 하나도 서명하지 않습니다.
  • SIGHASH_SINGLE(0x03): 같은 인덱스의 출력 하나만 서명합니다.

SIGHASH_SINGLE로 입력 0에 서명하면 "이 입력의 코인은 출력 0의 조건(금액과 받는 스크립트)으로 보낸다"는 것만 확정됩니다. 다른 참여자는 입력과 출력을 더 붙이거나 다른 출력을 바꿀 수 있지만, 출력 0을 바꾸면 서명이 무효가 됩니다. 여러 사람이 각자 입력과 대응 출력을 책임지고 하나의 트랜잭션을 조립할 때 유용합니다.

SIGHASH_ANYONECANPAY(0x80) 플래그와 함께 쓰면(SINGLE|ANYONECANPAY, 0x83) 자기 입력 하나와 출력 하나만 서명하므로, 다른 사람이 입력도 자유롭게 추가할 수 있습니다.

블록체인·암호화폐에서는

레거시 서명 방식에는 유명한 버그가 있습니다. 입력 인덱스에 대응하는 출력이 없을 때(입력 수가 출력 수보다 많을 때) 서명 해시가 오류 대신 상수 1로 계산되어, 그 서명이 사실상 아무 트랜잭션에나 재사용될 수 있었습니다. 세그윗 v0 서명 방식(BIP143)은 이 경우를 다르게 처리하고, 탭루트 서명(BIP341)에서는 대응 출력이 없는 SIGHASH_SINGLE 서명을 무효로 처리합니다. 실무에서는 부분 서명 트랜잭션(PSBT)을 이용한 거래 제안이나 일부 순서 거래 프로토콜에서 SINGLE|ANYONECANPAY 조합이 쓰입니다. 일반 지갑 송금은 거의 항상 SIGHASH_ALL을 씁니다.

서명 해시 계산에서 빠지는 것

SIGHASH_SINGLE로 입력 i에 서명할 때 레거시 방식은 서명할 트랜잭션 사본을 이렇게 만듭니다.

  • 출력 목록을 i+1개로 자르고, i보다 앞선 출력은 금액을 −1, 스크립트를 빈 값으로 바꿉니다.
  • 다른 입력의 시퀀스 번호를 0으로 만듭니다.
  • 이 사본에 sighash 유형 값을 붙여 이중 SHA-256으로 해시한 결과에 서명합니다.

따라서 앞쪽 출력의 '자리'는 남지만 내용은 서명되지 않고, 뒤쪽 출력은 아예 서명 대상에서 빠집니다. 세그윗 v0(BIP143)은 이 계산을 다시 정리해, SINGLE일 때 같은 인덱스 출력 하나만 해시에 넣습니다.

예시

앨리스가 자신의 입력 0과 '출력 0: 밥에게 0.1 BTC'를 SINGLE|ANYONECANPAY로 서명해 넘겨주면, 이 조각은 "누구든 이 입력과 이 출력을 트랜잭션 맨 앞에 넣으면 유효하다"는 제안이 됩니다. 다른 사람은 자기 입력과 출력을 뒤에 덧붙여 하나의 트랜잭션을 완성할 수 있습니다. 반대로 입력이 3개인데 출력이 2개뿐인 트랜잭션에서 입력 2에 SINGLE로 서명하면 대응 출력이 없어 앞서 말한 버그 조건이 됩니다. 지갑 개발자는 이런 서명을 만들지 않도록 주의해야 합니다.

쉽게 말하면

공동 구매 영수증에서 "내 돈은 이 줄에 적힌 물건값으로만 쓴다"는 한 줄에만 도장을 찍고, 나머지 줄은 다른 사람이 채우게 두는 것입니다.

이 글은 학습을 위한 일반 정보이며 투자 권유나 법률 자문이 아닙니다. 가상자산은 가격 변동이 크고 원금 손실 위험이 있습니다.