용어집 / 트랜잭션과 수수료
SIGHASH_ALL
- SIGHASH_ALL이란 무엇입니까?
- SIGHASH_ALL은 서명이 트랜잭션의 모든 입력과 모든 출력에 대해 확정되도록 하는 플래그로, 서명한 뒤에는 결제에 관한 어떤 것도 변경할 수 없습니다.
이것은 여러분의 지갑이 사용하는 플래그이며, 하드웨어 지갑 화면에서 트랜잭션을 승인하는 일이 의미를 갖는 이유이기도 합니다. 값은 1이며, 블록 탐색기에서 거의 모든 서명의 마지막 바이트로 확인할 수 있습니다. Taproot는 기본값의 이름을 SIGHASH_DEFAULT로 바꾸고 그 바이트를 아예 쓰지 않게 되어 서명마다 1바이트를 절약합니다.
작동 방식
SIGHASH_ALL에서는 다이제스트가 트랜잭션 버전, 지출되는 모든 아웃포인트, 모든 시퀀스 번호, 모든 출력 금액, 모든 출력 스크립트, 그리고 록타임을 포함합니다.
출력 하나의 사토시 하나만 바꿔도 트랜잭션의 모든 서명이 무효가 됩니다. 입력을 추가하거나, 출력을 삭제하거나, 순서를 바꾸거나, 록타임을 조금 옮겨도 결과는 같습니다. 서명된 비트코인 트랜잭션은 브로드캐스트되기 전부터 내용 면에서 확정적이라고 말할 때 뜻하는 것이 바로 이것입니다. 누구에게나 남은 결정은 그것을 보낼지 여부뿐입니다.
의도적으로 제외되는 것이 하나 있습니다: 다른 입력의 잠금 해제 스크립트입니다. 다이제스트가 그것들을 포함한다면 서명자가 둘인 트랜잭션에서 각 서명은 다른 서명이 이루어진 뒤에 만들어져야 하며, 이는 순환적이고 불가능합니다. 그것들을 빼두기 때문에 독립적인 당사자들이 같은 트랜잭션에 원하는 순서로 서명할 수 있습니다.
인코딩은 입력 유형에 따라 다릅니다. 레거시 또는 버전 0 세그윗 입력에서는 DER로 인코딩된 서명 뒤에 바이트 01이 붙으며, 익숙한 71 또는 72바이트라는 총길이가 여기서 나옵니다. Taproot 키 경로 지출에서는 BIP341이 값 0을 SIGHASH_DEFAULT로 정의하는데, 이는 바이트를 전혀 쓰지 않고 동일한 범위를 뜻하므로 서명은 정확히 64바이트입니다. Taproot 입력에 01을 명시적으로 쓰는 것도 여전히 유효하며 같은 다이제스트를 만들어 내지만, 아무 이득 없이 1바이트를 더 쓰는 것일 뿐입니다.
확인할 수 있는 곳
SIGHASH_ALL은 거의 어디에서나 사용됩니다: Bitcoin Core, Electrum, Sparrow, 모든 하드웨어 지갑, 그리고 모든 거래소의 출금 엔진이 기본적으로 이 방식으로 서명하며, 그중 어느 것도 이를 바꾸는 설정을 제공하지 않습니다.
실질적인 결과는 결제가 막혔을 때 체감하게 됩니다. 수수료는 입력과 출력 사이에 남는 금액이고 출력은 모두 서명되어 있으므로, 수수료를 올리려고 출력에서 수천 사토시를 깎아낼 수는 없습니다. 트랜잭션을 처음부터 다시 만들고 다시 서명해야 하며, 이는 키를 보유한 지갑만 할 수 있습니다. 그래서 replace-by-fee가 보내는 지갑의 기능이며 거래소나 블록 탐색기가 여러분을 대신해 수행할 수 있는 일이 아닌 것입니다. 또한 보내는 사람과 연락이 닿지 않을 때 child-pays-for-parent가 탈출구로 존재하는 이유이기도 합니다.
또한 이것이 하드웨어 지갑 화면을 제안이 아니라 계약으로 만듭니다. 기기는 목적지, 금액, 수수료를 보여 주며, 그다음 생성하는 서명이 이 셋 모두를 포함하므로 이후의 어떤 소프트웨어도 그 서명을 버리지 않고는 이들 중 어느 것도 바꿀 수 없습니다. 화면에 표시된 것을 승인하면 그 밖의 일은 일어날 수 없습니다.
SIGHASH_ALL vs SIGHASH_NONE
SIGHASH_ALL은 전체 출력 목록에 커밋합니다. SIGHASH_NONE는 그 어느 것에도 커밋하지 않습니다. 둘 사이의 간격은 결제와, 코인을 특정되지 않은 곳으로 옮기라는 순수한 권한 사이의 간격입니다. 두 플래그는 값 하나만큼 떨어져 있으므로, 플래그를 정수 매개변수로 받아들이는 서명 라이브러리는 오타 하나로 고객의 출금을 멤풀을 지켜보는 누구나 방향을 바꿀 수 있는 코인으로 만들어 버릴 수 있습니다. 운영 환경의 서명 코드는 값을 입력으로 받지 말고 하드코딩해야 합니다.