PSBT는 Partially Signed Bitcoin Transaction의 약자로, 비트코인 거래를 만들고 서명하는 장치가 달라도 필요한 UTXO 정보와 스크립트, 키 파생 정보, 부분 서명을 교환할 수 있게 한 표준 형식입니다. Creator·Updater·Signer·Combiner·Finalizer·Extractor 역할을 분리해 오프라인 서명과 다중서명을 지원합니다. PSBT 자체가 서명 전 안전을 보증하지 않으므로 입력 출처, 모든 출력·수수료·잔돈 주소를 서명 기기에서 확인해야 합니다.
PSBT는 거래와 서명 재료를 한 컨테이너에 담는다
BIP 174는 서로 다른 지갑과 서명기가 상호운용할 수 있도록 PSBT를 정의합니다. unsigned transaction 또는 v2의 개별 거래 필드에 더해 input·output별 key-value map을 둡니다. witness UTXO, redeem script, witness script, BIP32 파생 경로와 부분 서명 같은 정보를 운반합니다.
base64 문자열이나 바이너리 파일 형태로 옮길 수 있지만 그 자체는 네트워크가 처리하는 최종 거래가 아닙니다. 필요한 서명과 스크립트가 완성되고 extractor가 raw transaction을 만든 뒤에야 브로드캐스트합니다. PSBT를 받았다는 사실과 자금 이동이 확정됐다는 사실을 구분합니다.
| 역할 | 하는 일 | 검증 경계 |
|---|---|---|
| Creator | 입력·출력 거래 골격 생성 | 수취·잔돈·locktime |
| Updater | UTXO·스크립트·키 정보 추가 | 정보 출처·파생 경로 |
| Signer | 통제 키의 입력에 부분 서명 | 금액·sighash·모든 출력 |
| Combiner | 같은 거래의 정보를 병합 | 동일 거래 여부 |
| Finalizer/Extractor | 최종 script와 raw tx 생성 | 완성도·최종 txid |
서명자는 입력 금액과 스크립트를 알아야 한다
SegWit 입력을 서명하려면 이전 출력의 amount와 scriptPubKey가 필요하며 PSBT_WITNESS_UTXO가 이를 제공할 수 있습니다. 레거시 입력은 전체 previous transaction이 필요한 경우가 있습니다. 제공된 UTXO 정보가 실제 체인의 outpoint와 일치하는지 검증하지 않으면 수수료와 서명 대상을 속을 수 있습니다.
입력 합계 – 출력 합계가 miner fee입니다. 예를 들어 입력 0.10 BTC, 수취 0.07 BTC, 잔돈 0.0299 BTC라면 fee는 0.0001 BTC입니다. 잔돈으로 보이는 출력이 실제 지갑 파생 경로에 속하는지 확인하지 않으면 공격자 출력을 잔돈으로 오인할 수 있습니다.
오프라인 서명은 네트워크를 끊는 것이지 거래 검증 책임을 없애는 것이 아니다.
JOBCOIN 해설
모든 출력과 sighash 범위를 기기에서 읽는다
서명자는 수취 주소, 금액, 잔돈 주소, fee와 feerate를 확인합니다. 하드웨어 지갑 화면에 전체 출력이 표시되지 않거나 unknown output 경고가 나오면 진행을 멈춥니다. OP_RETURN과 locktime, sequence도 의도한 거래 정책과 맞는지 봅니다.
SIGHASH_ALL은 일반적으로 모든 입력·출력을 커밋하지만 다른 sighash 유형은 서명 범위를 줄일 수 있습니다. ANYONECANPAY나 SINGLE을 사용하는 프로토콜은 의도와 위험을 이해해야 합니다. PSBT 필드의 sighash type을 기본값으로 가정하지 말고 서명기가 실제로 커밋할 범위를 표시해야 합니다.
- 각 input outpoint와 UTXO 금액·스크립트를 확인한다.
- 모든 수취 출력과 잔돈 파생 경로를 대조한다.
- 입력 합계에서 출력 합계를 빼 fee를 계산한다.
- sighash·locktime·sequence와 최종 raw tx를 확인한다.
Combiner는 부분 서명을 합치지만 충돌을 해결하지 않는다
다중서명 참여자는 같은 거래 골격을 가진 PSBT에 각자 부분 서명을 추가할 수 있습니다. Combiner는 여러 PSBT의 key-value 정보를 병합하지만 서로 다른 unsigned transaction을 하나로 합쳐 주지 않습니다. global transaction 식별 정보가 일치해야 합니다.
알 수 없는 proprietary key나 충돌 필드는 지갑마다 처리 방식이 다를 수 있습니다. 결합 전후 input·output 수와 순서, 금액이 바뀌지 않았는지 비교합니다. 서명 하나가 추가됐다는 이유로 다른 참여자의 메타데이터를 무조건 신뢰하지 않습니다.
Finalizer와 Extractor 뒤에도 다시 검토한다
필요한 서명이 모이면 Finalizer가 finalScriptSig나 finalScriptWitness를 만들고 불필요한 부분 필드를 정리합니다. Extractor는 네트워크에 보낼 raw transaction을 생성합니다. 이 과정이 성공했다는 것은 스크립트 구조가 완성됐다는 뜻이며 UTXO가 아직 미사용이라는 보장은 아닙니다.
브로드캐스트 전 raw transaction을 디코딩해 입력·출력·fee를 PSBT 승인 기록과 비교합니다. mempool 거부 시 double spend, fee, locktime, 정책 오류를 구분합니다. 다시 PSBT를 만들 때 기존 서명을 새 거래에 재사용할 수 있다고 가정하지 않습니다.
PSBT v0과 v2 형식을 구분한다
BIP 174의 v0는 전역 unsigned transaction을 중심으로 정보를 붙입니다. BIP 370의 v2는 transaction version, fallback locktime, input count, output count와 input·output별 이전 txid·index·amount·script 등을 분리해 구성과 수정 역할을 명확히 합니다.
모든 지갑이 두 버전을 동일하게 지원하지 않습니다. 내보내기 전에 상대 장치의 지원 버전과 Taproot 필드 지원을 확인합니다. 변환 도구를 쓰면 unknown field와 키 origin이 보존되는지 비교하고, 표준 테스트 벡터로 round-trip을 검증합니다.
자주 묻는 질문
PSBT 파일만 있으면 비트코인을 보낼 수 있나요?
필요한 서명이 모두 있고 최종화돼야 raw transaction을 만들 수 있습니다. 미완성 PSBT만으로는 일반적으로 브로드캐스트할 수 없습니다.
PSBT는 개인키를 포함하나요?
표준 흐름은 파생 정보와 서명을 전달하며 개인키를 공유할 필요가 없습니다. 파일에 비표준 비밀 정보가 없는지도 도구별로 확인하세요.
오프라인 기기면 화면 확인을 생략해도 되나요?
아닙니다. 오프라인 기기도 악성 PSBT에 서명할 수 있으므로 모든 출력·금액·수수료·sighash를 확인해야 합니다.



