# 트랜잭션 가변성 (Transaction Malleability)

트랜잭션 가변성은 트랜잭션의 효력(누가 누구에게 얼마를 보내는지)은 바꾸지 않으면서 데이터 일부를 바꿔 트랜잭션 ID(TXID)만 달라지게 할 수 있는 성질입니다. 원래 TXID를 참조하던 자식 트랜잭션이 무효가 되는 문제가 생깁니다.

## 자세히 알아보기

비트코인의 기존(레거시) 트랜잭션에서 TXID는 서명을 포함한 전체 트랜잭션의 해시입니다. 그런데 서명 자체는 TXID 계산 대상 데이터를 완전히 고정하지 못합니다. 예를 들어 ECDSA 서명 (r, s)는 (r, n−s)로 바꿔도 유효하고, 서명 스크립트에 불필요한 데이터를 끼워 넣을 수도 있었습니다. 제3자가 미확인 트랜잭션을 이렇게 살짝 바꿔 다시 퍼뜨리면, 송금 내용은 같지만 TXID가 다른 트랜잭션이 블록에 들어갈 수 있습니다.

돈을 훔칠 수는 없지만 문제는 생깁니다.

- TXID로 입출금을 추적하는 거래소나 지갑이 "출금이 실패했다"고 잘못 판단해 다시 보낼 수 있습니다.
- 아직 확정되지 않은 트랜잭션의 TXID를 미리 참조해 만든 자식 트랜잭션(예: 결제 채널의 환불 트랜잭션)이 무효가 됩니다.

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

비트코인은 BIP66(엄격한 DER 서명 인코딩) 소프트 포크와 low-S 정책 규칙 같은 조치로 일부 경로를 막았고, 2017년 활성화된 세그윗(SegWit)이 서명 데이터(위트니스)를 TXID 계산에서 제외해 서명으로 인한 가변성을 근본적으로 해결했습니다. 덕분에 미확인 트랜잭션에 의존하는 라이트닝 네트워크가 안전하게 동작할 수 있게 되었습니다. 2014년 Mt.Gox는 출금 문제의 원인으로 트랜잭션 가변성을 지목했지만, 이후 분석에서 손실의 주된 원인으로 보기 어렵다는 의견이 많았습니다.

### 어떻게 바뀌었나: 예시

레거시 트랜잭션 A가 네트워크에 퍼졌다고 해 봅시다. 중계 노드 하나가 A의 서명 s 값을 n−s로 바꾼 A′를 만들어 퍼뜨립니다. 두 트랜잭션은 같은 입력을 같은 출력으로 보내므로 하나만 블록에 들어갈 수 있습니다. A′가 먼저 채굴되면 A는 이중 지불로 거부되고, TXID(A)를 기다리던 지갑은 "트랜잭션이 사라졌다"고 표시합니다. 하지만 자금은 실제로 목적지에 도착했습니다.

### 세그윗이 해결한 방식

세그윗 트랜잭션에서는 서명이 위트니스라는 별도 영역에 들어가고, TXID는 위트니스를 뺀 데이터로 계산합니다. 서명 인코딩을 아무리 바꿔도 TXID는 그대로입니다(위트니스까지 포함한 해시는 wtxid라고 따로 부릅니다). 다만 이 보호는 세그윗 입력에만 적용되므로, 레거시 입력이 섞인 트랜잭션은 여전히 가변성이 있을 수 있습니다.

### 서비스 운영 시 교훈

입출금 시스템은 TXID 하나만으로 상태를 판단하지 말고, 실제로 어떤 출력(주소와 금액)이 확정되었는지 확인해야 합니다. 이는 가변성뿐 아니라 수수료 대체(RBF)로 트랜잭션이 교체되는 경우에도 똑같이 필요한 원칙입니다.

## 쉽게 말하면

수표 금액과 받는 사람은 그대로인데 일련번호만 바뀌어서, 번호로 관리하던 장부가 엉키는 문제입니다.

---
출처: https://achivx.kr/glossary/transaction-malleability-%EA%B1%B0%EB%9E%98-%EB%B3%80%EC%A1%B0/ · ACHIVX 용어 사전 · 수정일 2026-10-20
