UTXO(Unspent Transaction Output): 비트코인이 잔액을 계산하는 방식
UTXO 모델의 구조와 스크립트 잠금/해제, 코인 선택·수수료 계산, 계정 모델과의 비교를 정리하고 Bitcoin Core CLI로 UTXO 기반 전송을 실행하는 절차를 다룬다.
2026-08-12 · 최초 발행 2025-12-06
안 쓴 출력값의 집합이 잔액이다
UTXO(Unspent Transaction Output)는 이전 트랜잭션의 출력 중 아직 소비되지 않은 상태 객체의 집합이다. 각 UTXO는 고유 식별자(outpoint: txid:vout), 금액, 잠금 스크립트(scriptPubKey)로 구성된다. 새 트랜잭션은 하나 이상의 UTXO를 입력으로 완전히 소비하고 하나 이상의 신규 UTXO를 출력으로 만드는 방식으로 상태를 전이시킨다. 부분 소비는 불가능하고, 남는 잔액은 별도의 체인지(change) UTXO로 분리해 생성한다.
검증 규칙의 핵심은 모든 입력이 실제로 존재하고 아직 소비되지 않았는지, 서명·스크립트가 유효한지, 입력 총합이 출력 총합과 수수료를 합친 값 이상인지, 형식·크기·컨센서스 제한을 지키는지를 확인하는 것이다. 노드는 UTXO Set 인덱스를 기반으로 O(k) 수준에서 입력을 검증한다.
잠그고 푸는 조건, 그리고 소비 방식
UTXO Set은 노드가 유지하는 현재 미사용 출력의 키-값 스토어(chainstate)다. 키는 outpoint(txid:vout), 값은 amount·scriptPubKey·height 같은 메타데이터로 구성된다. 한 번 생성된 UTXO는 내용이 바뀌지 않고 소비될 때 원자적으로 소멸하기 때문에 더블스펜드를 막고 병렬 검증이 쉬워진다.
지출 조건은 잠금 스크립트(scriptPubKey)가 정의한다. P2PKH, P2WPKH, P2WSH, P2TR(Taproot) 등 유형이 있고, 이 조건을 충족하는 서명·키·증명 데이터가 해제 데이터(scriptSig/witness)다. SegWit 도입 이후 서명이 분리되면서 서명 위·변조(malleability) 문제가 줄었다.
코인 선택 알고리즘은 Largest-First, Knapsack·Branch-and-Bound, Random-Improve 등이 있고 수수료 최소화, UTXO 파편화 억제, 프라이버시 균형이라는 세 목표를 함께 고려한다. 수수료는 feerate(sat/vB) × 트랜잭션 가상크기(vB)로 계산되며, 입력 유형·개수, 출력 개수, 스크립트 유형에 따라 크기가 달라진다.
단일 UTXO는 부분 지출이 안 되므로 지출액과 수수료를 넘는 입력이 있으면 체인지 출력이 생긴다. 이때 너무 작은 체인지(더스트)는 만들지 않는 게 중요한데, 더스트는 수수료 부담만 키우고 재사용하기에도 비경제적이기 때문이다.
병렬 검증은 UTXO 모델의 강점이다. 입력을 독립적으로 검증할 수 있어 샤딩 없이도 높은 병렬성을 확보하지만, 그만큼 상태 크기 관리가 과제로 남는다. 프라이버시 측면에서는 다중 입력을 함께 쓰면 소유자 연결성이 드러날 수 있어서, 주소 재사용 금지·입력 균형화·배치 결제·코인조인 같은 보완이 필요하다.
실무에서 UTXO를 다루는 자리
거래소·커스터디 지갑은 대량 출금을 배치로 묶어 수수료를 아끼고 UTXO 파편화를 억제하며, 저수수료 구간에 UTXO를 통합(consolidation)하는 코인 컨트롤 정책을 운영한다. 결제 게이트웨이·상점은 일회성 주소를 발급하고 체인지 라우팅과 더스트 방지 규칙을 적용하며, RBF(Replace-By-Fee)·CPFP(Child-Pays-For-Parent)로 수수료를 재조정한다. L2·스마트 컨트랙트 영역에서는 라이트닝 채널 펀딩(2-of-2), 멀티시그 에스크로, 단방향 지급 채널, DLC(Discreet Log Contract) 구성에 UTXO가 쓰인다. 규정 준수·감사·분석에서는 UTXO Set 스냅샷으로 잔액을 증명하고 내부 회계를 대사하며 리스크를 모니터링한다.
지갑에서 블록 확정까지
UTXO 모델과 계정 모델, 어디서 갈리나
| 구분 | UTXO 모델 | 계정 모델 |
|---|---|---|
| 성능 | 입력 독립 검증으로 병렬성 우수. 입력 수 증가 시 크기·검증비용 증가 | 상태 접근 O(1) 경향, 단건 이체 효율적 |
| 확장성 | 상태는 UTXO Set 크기 의존. 파편화 관리 중요 | 글로벌 상태 단일화로 샤딩·파트리샤 트리 등 별도 확장 필요 |
| 일관성 | 소비 원자성·이중지불 방지 명확 | nonce·순서 의존, 재진입·동시성 관리 필요 |
| 안정성 | 스크립트 단순, 검증 경로 예측 용이 | 스마트컨트랙트 복잡성에 따른 리스크 증가 가능 |
| 운영 편의 | 코인 선택·체인지·더스트 정책 필요 | 잔액 단일 상태 관리 용이, 수수료 예측 용이성 상 |
수수료는 결국 크기의 함수다
입력·출력 유형에 따라 트랜잭션 크기가 달라진다. P2WPKH 입력은 약 68 vB, P2WPKH 출력은 약 31 vB, 오버헤드는 약 10 vB로 잡는다(네트워크·스크립트 유형에 따라 상이하므로 최신 지갑 규격 확인이 필요하다). 2입력·2출력 트랜잭션이라면 vbytes ≈ 10 + (2 × 68) + (2 × 31) = 208 vB가 되고, feerate를 30 sat/vB로 가정하면 수수료는 208 × 30 = 6,240 sat이 나온다. 같은 금액을 보내더라도 입력 수를 줄이면 vbytes가 줄어 수수료가 낮아지고, 저수수료 시기(예: 1~5 sat/vB 구간)에 소액 UTXO를 통합해두면 장기적인 수수료 절감 효과가 커진다.
지갑 위생과 노드 운영에서 지켜야 할 것들
주소는 HD 지갑(BIP32/39/84/86) 규격으로 매번 새로 발급받는 게 원칙이고, 다중 입력을 묶는 건 최소화해야 한다. 배치 결제는 그룹화 힌트를 노출할 수 있어서 코인조인이나 수취 라벨링 같은 보완이 필요하다. 수수료·전파 안정성 측면에서는 RBF를 활성화하고 CPFP에 대비해 소액 출력을 설계해두며, 네트워크가 혼잡할 때를 대비해 동적 feerate 소스를 여러 개 확보해둔다. UTXO 더스트 생성은 억제하고 통합(consolidation) 윈도우를 운영하되, 과도한 통합은 주소 연결성을 높인다는 트레이드오프가 있다. 노드·지갑 인프라 쪽에서는 풀노드(chainstate)를 직접 운용해 독립 검증을 확보하고, 디스크 I/O와 UTXO 캐시를 튜닝해야 한다. AssumeUTXO·스냅샷·프루닝 같은 가속 기능은 네트워크·버전에 따라 달라지므로 최신 정보를 확인하는 게 좋다.
Bitcoin Core로 UTXO 기반 전송을 실행하는 절차
전제조건은 Bitcoin Core v26+ 풀노드가 동기화를 마쳤고 wallet이 생성·로드된 상태여야 하며, 테스트넷이나 시그넷에서 먼저 시도하는 걸 권장한다. CLI 접근이 가능한 환경이면 아래 순서로 진행한다.
먼저 사용 가능한 UTXO를 조회한다.
bitcoin-cli -chain=signet listunspent 1 9999999
입력을 명시해 원시 트랜잭션 초안을 만든다(더스트 방지). 입력 예는 [{"txid":"<TXID>","vout":0}], 출력 예는 {"<DEST_ADDR>":0.01000000}다.
bitcoin-cli -chain=signet createrawtransaction '[{"txid":"<TXID>","vout":0}]' '{"<DEST_ADDR>":0.01000000}'
수수료와 체인지를 자동으로 보정한다.
bitcoin-cli -chain=signet fundrawtransaction '<RAW_TX_HEX>' '{"changeAddress":"<CHANGE_ADDR>","subtractFeeFromOutputs":[0]}'
서명한다.
bitcoin-cli -chain=signet signrawtransactionwithwallet '<FUNDED_RAW_TX_HEX>'
브로드캐스트한다.
bitcoin-cli -chain=signet sendrawtransaction '<SIGNED_TX_HEX>'
coin control이 필요하면 send API의 add_inputs, include_unsafe, change_type 같은 파라미터를 활용할 수 있다. RBF는 fundrawtransaction에서 replaceable=true를 설정하거나 지갑 기본 정책을 쓰면 활성화된다.