Skip to main content
For the complete documentation index, see llms.txt

UTXO model

UTXO 모델은 디지털 가치에 대한 근본적으로 다른 사고방식입니다. Account 모델이 전통적인 은행 업무를 반영하여 익숙하게 느껴졌다면, UTXO 모델은 처음에는 낯설 수 있습니다. 이를 이해하면 설계상의 trade-off가 분명해지며, Midnight가 왜 프라이버시와 병렬 처리를 위한 기반으로 UTXO를 선택했는지 알 수 있습니다.

UTXO는 "Unspent Transaction Output"의 약자입니다. 각 UTXO는 지갑 속 물리적 현금처럼 개별적인 디지털 코인입니다. 각각 특정 값이 있고, 특정 소유자에게 속하며, 반드시 전체가 소비되어야 합니다. 이 제약이 UTXO 모델의 가장 유용한 속성을 뒷받침합니다.

The digital cash metaphor

현금 비유는 단순한 교육 도구가 아니라, UTXO의 실제 작동 방식에 대한 정확한 설명입니다:

커피숍에서 $3.50짜리 라테를 주문했다고 상상해 보세요. 지갑을 열어보니 다음이 있습니다.

  • $20 지폐 한 장
  • $5 지폐 한 장
  • $1 지폐 두 장

$5 지폐를 찢어서 $3.50만 추출할 수는 없습니다. $5 지폐 전체를 건네고 $1.50의 거스름돈을 받아야 합니다. 원래 $5 지폐는 영원히 당신의 손을 떠나며 - transaction에서 "소비"된 것입니다 - 거스름돈으로 새 지폐를 받게 됩니다.

UTXO 모델은 이 정확한 패턴을 디지털로 구현합니다.

// 지갑에 개별 UTXO(지폐처럼)가 있음:
AliceWallet = [
UTXO_1: { value: 100 NIGHT, id: "abc123..." },
UTXO_2: { value: 50 NIGHT, id: "def456..." },
UTXO_3: { value: 25 NIGHT, id: "ghi789..." }
]

// 60 NIGHT를 보내려면, UTXO 전체를 소비해야 함:
Transaction {
inputs: [UTXO_1], // 100 NIGHT UTXO 전체 소비
outputs: [
{ value: 60, recipient: Bob }, // 지불
{ value: 40, recipient: Alice } // 거스름돈
]
}

Core UTXO concepts

다음 원칙들은 UTXO 모델이 Midnight에서 어떻게 작동하는지 설명합니다.

UTXOs are indivisible

이것은 단순한 설계 선택이 아니라 모델의 핵심 속성입니다. 각 UTXO는 완전한 단위로 처리됩니다:

// UTXO 시스템에서 이것은 불가능:
❌ UTXO_100.spend(30) // UTXO의 일부만 소비할 수 없음

// 대신 이렇게 해야 함:
✅ Transaction {
inputs: [UTXO_100], // 전체 소비
outputs: [
{ value: 30, owner: recipient },
{ value: 70, owner: self } // 거스름돈
]
}

이 분할 불가능성은 원자적 transaction, 병렬 처리, 그리고 Midnight의 shielded token 지원을 가능하게 합니다.

The nullifier set in Midnight

Midnight는 사용된 출력을 추적하는 방식에서 Bitcoin과 다릅니다. UTXO를 단순히 "사용됨"으로 표시하는 대신, Midnight은 nullifier 집합을 사용합니다:

// Midnight에서 UTXO가 사용될 때:
1. UTXO_abc123이 트랜잭션에서 소비됨
2. nullifier 계산: nullifier = Hash(UTXO_abc123, ownerSecret)
3. 이 nullifier가 전역 nullifier 집합에 추가됨
4. 이후 트랜잭션이 수락 전에 isNullified(UTXO)를 확인

// nullifier 집합은 시간이 지남에 따라 증가:
NullifierSet = {
"0xn1a2b3c4...", // 사용된 UTXO_1에서
"0xn5d6e7f8...", // 사용된 UTXO_2에서
"0xn9g0h1i2...", // 사용된 UTXO_3에서
// ... 수백만 개 더
}

이 접근 방식이 중요한 이유:

  • 가지치기 불필요: Bitcoin과 달리, Midnight은 사용된 출력을 이력에서 제거하지 않음
  • 프라이버시 호환: nullifier는 사용된 UTXO에 공개적으로 연결하지 않고도 검증 가능
  • 이중 소비 방지: nullifier가 집합에 포함되면, 해당 소비는 다시 수락되지 않음
  • 효율적인 검증: 노드가 검증 중 소속 여부를 효율적으로 확인 가능

Transaction atomicity through output creation

Every UTXO transaction is atomic: all inputs are consumed and all outputs are created together, or nothing happens.

// 원자성을 보여주는 다자간 결제:
Transaction {
inputs: [
UTXO_A: 100 NIGHT, // Alice로부터
UTXO_B: 50 NIGHT // 또한 Alice로부터
],
outputs: [
{ value: 40, owner: Bob },
{ value: 30, owner: Carol },
{ value: 20, owner: Dave },
{ value: 60, owner: Alice } // 거스름돈
]
}
// 전부 실행되거나, 전혀 실행되지 않음

The UTXO lifecycle in Midnight

전체 라이프사이클을 이해하면 이 모델이 효과적인 이유를 파악하는 데 도움이 됩니다:

// 1. 생성: 트랜잭션에서 UTXO 생성
NewUTXO = {
value: 100 NIGHT,
owner: AlicePublicKey,
id: Hash(transaction, outputIndex),
commitment: PedersenCommit(value, randomness) // 프라이버시용
}

// 2. 생존: UTXO가 미사용 집합에 존재
UnspentSet.add(NewUTXO)
// 조회, 증명 가능하지만 수정 불가

// 3. 소비: 트랜잭션에서 UTXO 소비
Transaction.consume(NewUTXO)
nullifier = ComputeNullifier(NewUTXO, AlicePrivateKey)
NullifierSet.add(nullifier)

// 4. 소비 후: nullifier가 재사용을 방지
if (NullifierSet.contains(nullifier)) {
reject("UTXO가 이미 사용되었습니다!")
}

Why this system

Account 잔액이 언뜻 더 단순해 보일 수 있습니다. 실제로 UTXO 모델은 프라이버시, 동시성, 증명 가능성을 구축할 때 분명해지는 장점을 제공합니다.

Parallelism as a model property

UTXO 모델은 병렬성을 자연스럽게 가능하게 합니다:

// Account 모델: 강제 순차 처리
// 이 트랜잭션들은 반드시 순서대로 처리해야 함:
Tx1: Alice.balance -= 50 // 먼저 완료되어야 함
Tx2: Alice.balance -= 30 // Tx1을 기다려야 함
// 이유? 둘 다 동일한 전역 상태를 수정

// UTXO 모델: 자연스러운 병렬 처리
// 이 트랜잭션들은 동시에 처리 가능:
Tx1: UTXO_A (50 NIGHT) 소비 → Bob에게 전송
Tx2: UTXO_B (30 NIGHT) 소비 → Carol에게 전송
// 이유? 완전히 독립적인 객체에 접근

이것은 사소한 최적화가 아닙니다. 고처리량 시나리오에서 이 아키텍처 차이는 처리량을 실질적으로 향상시킬 수 있습니다.

Privacy built into the foundation

UTXO 모델은 account 기반 시스템에서는 구현하기 어려운 프라이버시 기능을 자연스럽게 지원합니다:

// Account 모델: 모든 것이 하나의 주소에 연결
AliceAccount: {
balance: 1000,
history: [지금까지의 모든 트랜잭션]
}
// 프라이버시를 위해 복잡한 우회가 필요

// UTXO 모델: 자연스러운 격리
UTXO_1: { value: 100, owner: AddressA } // 급여 수령용
UTXO_2: { value: 50, owner: AddressB } // 온라인 쇼핑용
UTXO_3: { value: 25, owner: AddressC } // 기부용
// 차폐 및 비차폐 token UTXO를 필요에 따라 사용 가능

Midnight에서 token UTXO는 차폐 또는 비차폐가 될 수 있어, account별이 아닌 transaction별로 프라이버시를 선택할 수 있습니다.

State management and efficiency

UTXO의 상태 관리 방식은 account 모델과 다릅니다:

// 노드가 추적해야 하는 것:
ActiveState = {
// Account 모델: 존재하는 모든 account
accounts: Map<Address, Balance>, // 영원히 증가

// UTXO 모델: 미사용 출력만
utxos: Set<UTXO>, // 자연스럽게 제한됨
nullifiers: Set<Hash> // 이중 소비 방지
}

// 핵심: UTXO에서 사용된 이력은 보관 가능
// account에서는 모든 이력이 현재 상태에 영향

Deep comparison

이 비교는 실제적인 영향을 요약합니다:

측면Account 모델UTXO 모델Midnight에서 중요한 이유
가치 저장단일 변경 가능 잔액불변 개별 코인shielded token 구현 가능
Transaction 모델상태 업데이트상태 전환자연스러운 감사 추적 및 증명 가능성
동시성잠금 → 처리 → 해제잠금 불필요대규모 처리량 잠재력
프라이버시 접근전체 잔액 혼합shielded token UTXO세밀한 프라이버시 제어
이중 소비 방지잔액 산술 확인nullifier 집합 소속숨겨진 값에서도 작동
상태 증가무제한 (모든 account)제한됨 (활성 UTXO만)장기 지속 가능성
결정론실행 순서에 의존순서 무관예측 가능한 결과

Key insights: the UTXO paradigm shift

UTXO 모델은 단순히 잔액을 추적하는 다른 방식이 아니라, 가치 흐름을 모델링하는 방식 자체를 바꿉니다:

  • 변경 가능에서 불변으로: 잔액을 수정하는 대신 개별 값을 생성하고 소비합니다. 이를 통해 강력한 감사 가능성과 proof 시스템을 지원합니다.
  • 순차에서 병렬로: 공유 잔액 업데이트를 피하여 독립적인 UTXO 간 자연스러운 동시성을 확보합니다.
  • 단일에서 세분화로: 각 UTXO가 독립적이어서 프라이버시, 소비, 소유권에 대한 세밀한 제어가 가능합니다.
  • Account에서 기능으로: UTXO는 가치, 권리, 또는 기타 개별 디지털 자산을 나타낼 수 있습니다.