> ## Documentation Index
> Fetch the complete documentation index at: https://www.helius.dev/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# 비공개 상태 및 UTXO

> UTXO가 토큰과 비공개 상태를 저장하는 방식을 알아보세요.

<a id="private-solana-token-accounts" />

비공개 잔액은 UTXO(미사용 트랜잭션 출력)에 저장됩니다.
UTXO는 다음 두 가지 핵심 차이점이 있는 비공개 SPL 토큰 계정으로 생각할 수 있습니다.

1. UTXO는 Solana 계정이 아니므로 임대료 면제가 필요하지 않습니다.
2. 잔액은 온체인에서 암호화됩니다.

UTXO 데이터 레이아웃은 SPL 토큰 계정과 유사합니다.

* **소유자** – Solana 키 쌍, PDA 또는 P-256 키입니다.
* **자산** – 민트(SOL, SPL 또는 Token-2022)입니다.
* **금액** – 최소 단위로 표시한 `asset`의 단위 수입니다.
* **데이터** – UTXO는 에스크로된 토큰의 소유자와 같은 임의의 데이터를 저장할 수 있습니다.
* **프로그램 및 정책 데이터** – 선택적으로 구성하는 Ring 규정 준수 데이터입니다.

<Tabs>
  <Tab title="Diagram">
    <img src="https://mintcdn.com/helius/ITnDOhn5GRfQ1FQW/images/privacy/account-comparison-private.svg?fit=max&auto=format&n=ITnDOhn5GRfQ1FQW&q=85&s=4143bb77db4e5ff44225882d571b8830" alt="비공개 Solana 토큰 계정입니다. Solana Privacy Program이 비공개 토큰 계정을 소유하며, 이 계정은 소유자, 자산, 금액, 데이터, 정책 데이터, 정책 프로그램 ID로 구성된 UTXO 필드로 확장됩니다." width="1080" height="590" data-path="images/privacy/account-comparison-private.svg" />
  </Tab>

  <Tab title="Code">
    각 비공개 Solana 토큰 계정에 저장되는 전체 레코드는 플랫 UTXO입니다.

    ```rust theme={"system"}
    struct Utxo {
        /// Constant separating UTXOs from other Poseidon-hashed data.
        domain: u16,
        /// Recipient's `owner_hash` from their Shielded Address.
        /// Senders write this value directly; the spender supplies the preimage
        /// components as proof witness.
        owner: [u8; 32],
        /// Asset mint. SOL is Address::default().
        asset: Address,
        /// Amount in the smallest unit of `asset`.
        amount: u64,
        /// Random bytes ensuring distinct UTXO hashes for equal
        /// `(owner, asset, amount)` triples.
        blinding: [u8; 31],
        /// Arbitrary program data.
        program_data: Option<Vec<u8>>,
        /// Arbitrary policy data.
        policy_data: Option<Vec<u8>>,
        /// The policy program that authorizes spends of this UTXO.
        policy_program_id: Option<Address>,
    }
    ```
  </Tab>
</Tabs>

<Info>
  소스 코드 보기: [사양](https://github.com/helius-labs/zolana/blob/680667f27cf9ba4203a0b69284f4c304b874092f/docs/spec.md#utxo) · [sdk-libs/transaction/src/utxo/note.rs](https://github.com/helius-labs/zolana/blob/680667f27cf9ba4203a0b69284f4c304b874092f/sdk-libs/transaction/src/utxo/note.rs#L16)
</Info>

<Accordion title="View Solana token account">
  <Tabs>
    <Tab title="Diagram">
      <img src="https://mintcdn.com/helius/KNGZoSuCXDUVm6yU/images/privacy/account-comparison-solana.svg?fit=max&auto=format&n=KNGZoSuCXDUVm6yU&q=85&s=89ff901091255f2038972208fcb5d538" alt="Solana 토큰 계정입니다." width="1080" height="462" data-path="images/privacy/account-comparison-solana.svg" />
    </Tab>

    <Tab title="Code">
      ```rust theme={"system"}
      pub struct Account {
          /// The mint associated with this account
          pub mint: Pubkey,
          /// The owner of this account.
          pub owner: Pubkey,
          /// The amount of tokens this account holds.
          pub amount: u64,
          /// If `delegate` is `Some` then `delegated_amount` represents
          /// the amount authorized by the delegate
          pub delegate: COption<Pubkey>,
          /// The account's state
          pub state: AccountState,
          /// If is_native.is_some, this is a native token, and the value logs the
          /// rent-exempt reserve. An Account is required to be rent-exempt, so
          /// the value is used by the Processor to ensure that wrapped SOL
          /// accounts do not drop below this threshold.
          pub is_native: COption<u64>,
          /// The amount delegated
          pub delegated_amount: u64,
          /// Optional authority to close the account.
          pub close_authority: COption<Pubkey>,
      }
      ```
    </Tab>
  </Tabs>
</Accordion>

<a id="private-wallet-balance" />

## 비공개 잔액

비공개 잔액은 비공개 지갑이 소유한 한 자산의 모든 UTXO를 합한 값입니다.
비공개 잔액이 하나 또는 여러 UTXO로 구성되어 있는지와 관계없이
지갑에는 하나의 잔액이 표시됩니다.
비공개 전송에서는 여러 UTXO를 한 번에 사용할 수 있습니다.

<img src="https://mintcdn.com/helius/ITnDOhn5GRfQ1FQW/images/privacy/utxo-set-to-wallet.svg?fit=max&auto=format&n=ITnDOhn5GRfQ1FQW&q=85&s=398e39f96fc52325c895e512a9b09dc7" alt="점선으로 여러 UTXO에 연결된 비공개 지갑입니다. 각 UTXO에는 한 자산의 특정 금액이 보관됩니다. 지갑 잔액은 UTXO의 합계입니다." width="700" height="276" data-path="images/privacy/utxo-set-to-wallet.svg" />

## 비공개 전송

UTXO를 사용하는 비공개 전송은 SPL 토큰 계정을 사용하는 공개 전송과 다르게 작동합니다.

* SPL 토큰 계정에서 전송하면 `amount`이 업데이트됩니다.
* UTXO를 사용하는 비공개 전송은 UTXO의 `amount`을 업데이트하지 않습니다.
  대신 비공개 전송은 기존 UTXO를 사용하고
  수신자와 발신자의 남은 잔액을 위한 새 UTXO를 생성합니다.

하지만 사용자가 체감하는 Solana 토큰 계정의 공개 전송과
UTXO의 비공개 전송 방식은 비슷합니다.

예를 들어 Alice가 50 USDC를 보유하고 있으며 Bob에게 35 USDC를 보냅니다.

* SPL 토큰 계정을 사용하면 Alice의 `amount`은 50에서 15로 감소하고 Bob의 잔액은 35만큼 증가합니다.
* UTXO를 사용하면 Alice는 50 USDC가 든 UTXO 하나를 보유합니다. 트랜잭션은 기존 UTXO를 사용하고 새로운 UTXO 두 개를 생성합니다. 하나에는 Bob의 35 USDC가, 다른 하나에는 Alice의 15 USDC가 들어갑니다.

<Tabs>
  <Tab title="Transfer with one UTXO">
    <img src="https://mintcdn.com/helius/ITnDOhn5GRfQ1FQW/images/privacy/spend-comparison.svg?fit=max&auto=format&n=ITnDOhn5GRfQ1FQW&q=85&s=c25d35501ca9fcff9b4c0c7c8654dd73" alt="UTXO 하나 사용" width="1016" height="240" data-path="images/privacy/spend-comparison.svg" />
  </Tab>

  <Tab title="Transfer with multiple UTXOs">
    <img src="https://mintcdn.com/helius/ITnDOhn5GRfQ1FQW/images/privacy/spend-comparison-multi.svg?fit=max&auto=format&n=ITnDOhn5GRfQ1FQW&q=85&s=c35ec9ab7c87c8d3cdb9e3d1caaf7742" alt="여러 UTXO 사용" width="1016" height="240" data-path="images/privacy/spend-comparison-multi.svg" />
  </Tab>
</Tabs>

| | Solana 토큰 계정 | 비공개 Solana 토큰 계정(UTXO) |
| - | - | - |
| 잔액 | 계정의 `amount` | 각각 한 자산의 고정 금액을 보유하는 모든 미사용 UTXO의 합계 |
| 사용 | `amount` 필드 업데이트 | 사용한 UTXO를 무효화하고 새 UTXO 생성 |
| 공개 여부 | 온체인에서 공개 | 온체인에서 암호화 |

### UTXO 선택

비공개 전송 시 SDK는 전송하려는 금액을 충당하는 미사용 UTXO를 선택합니다.

UTXO 선택 알고리즘은 전송당 가능한 한 적은 수의 UTXO를 사용합니다.

1. SDK가 전송할 자산을 기준으로 UTXO를 필터링하고 금액순으로 정렬합니다.
2. SDK가 전송 금액을 충당하는 데 필요한 만큼 UTXO를 선택합니다.
   전송 금액이 충당될 때까지 가장 큰 UTXO부터 선택합니다.

예를 들어 Alice가 Bob에게 80 USDC를 보냅니다. Alice가 보유한 가장 큰 UTXO 세 개로 전송 금액을 충당할 수 있습니다.

<img src="https://mintcdn.com/helius/ITnDOhn5GRfQ1FQW/images/privacy/utxo-selection.svg?fit=max&auto=format&n=ITnDOhn5GRfQ1FQW&q=85&s=07ed7a4483eee5a3605ceb08291d5e02" alt="Alice가 80 USDC를 보냅니다. Alice의 UTXO는 40, 25, 20, 10, 5 USDC 순으로 큰 금액부터 정렬됩니다. SDK는 80 USDC를 충당하는 40, 25, 20 USDC를 선택하고 10, 5 USDC는 선택하지 않습니다." width="770" height="140" data-path="images/privacy/utxo-selection.svg" />

UTXO 수가 적을수록 트랜잭션 크기가 작아집니다.
사용된 각 UTXO는 해당 UTXO가 사용되었음을 표시하는 무효화 계정에 66바이트를 추가합니다.
이 계정은 UTXO가 <Tooltip tip="The nullifier account is temporary. Asynchronously, the Forester inserts the nullifier into the nullifier Merkle tree, which records the UTXO as spent permanently. The Forester then closes the account and reclaims the rent-exemption.">다시 사용되는 것을</Tooltip> 방지합니다.

추가 데이터나 다른 명령이 없는 비공개 전송의 예는 다음과 같습니다.

| 사용된 UTXO | 트랜잭션 크기 | 계정 수 |
| - | - | - |
| 2 | 927바이트 | 6 |
| 5 | 1,125바이트 | 9 |
| 36 | 3,055바이트 | 40 |

### 트랜잭션 변형

모든 비공개 전송은 트랜잭션 변형을 사용합니다. 트랜잭션 변형에는 사용할 UTXO와 생성할 새 UTXO를 위한 고정된 수의 슬롯이 있습니다.

변형은 사용되는 UTXO가 1개에서 36개인 범위이며, 각 변형에는 자체 ZK 회로가 있습니다.
이 회로는 사용된 UTXO가 유효하고 새 UTXO가 동일한 총액을 보유한다는 것을 증명합니다.
전송에 36개가 넘는 UTXO가 필요하면 [먼저 병합하세요](#utxo-병합).

SDK는 전송에 맞는 변형을 선택하고 사용하지 않는 슬롯을 더미 UTXO로 채웁니다.
더미 UTXO에는 가치가 없으며 온체인에서는 실제 UTXO처럼 보입니다.

<Tabs>
  <Tab title="1 spent, 2 new">
    Alice가 Bob에게 30 USDC를 보냅니다. Alice의 가장 큰 UTXO로 전송 금액을 충당할 수 있습니다.

    <img src="https://mintcdn.com/helius/ITnDOhn5GRfQ1FQW/images/privacy/utxo-variant-1-2.svg?fit=max&auto=format&n=ITnDOhn5GRfQ1FQW&q=85&s=728d31824165d27d6fd5f98704431f5e" alt="Alice의 40 USDC UTXO가 사용되고 25, 20, 10, 5 USDC UTXO는 미사용 상태로 유지됩니다. 트랜잭션은 Bob에게 30 USDC, Alice에게 10 USDC가 든 UTXO를 생성합니다." width="520" height="286" data-path="images/privacy/utxo-variant-1-2.svg" />
  </Tab>

  <Tab title="2 spent, 2 new">
    Alice가 Bob에게 60 USDC를 보냅니다. Alice의 가장 큰 UTXO 두 개로 전송 금액을 충당할 수 있습니다.

    <img src="https://mintcdn.com/helius/ITnDOhn5GRfQ1FQW/images/privacy/utxo-variant-2-2.svg?fit=max&auto=format&n=ITnDOhn5GRfQ1FQW&q=85&s=75d3804ee8a731e2b213dcbda9f3edbc" alt="Alice의 40, 25 USDC UTXO가 사용되고 20, 10, 5 USDC UTXO는 미사용 상태로 유지됩니다. 트랜잭션은 Bob에게 60 USDC, Alice에게 5 USDC가 든 UTXO를 생성합니다." width="520" height="286" data-path="images/privacy/utxo-variant-2-2.svg" />
  </Tab>

  <Tab title="3 spent, 3 new">
    Alice가 Bob에게 80 USDC를 보냅니다. Alice의 가장 큰 UTXO 세 개로 전송 금액을 충당할 수 있습니다. SDK는 사용하지 않는 슬롯을 더미 UTXO로 채웁니다.

    <img src="https://mintcdn.com/helius/ITnDOhn5GRfQ1FQW/images/privacy/utxo-variant-3-3.svg?fit=max&auto=format&n=ITnDOhn5GRfQ1FQW&q=85&s=7cb4508367f8caaa674bd419719aec0b" alt="Alice의 40, 25, 20 USDC UTXO가 사용되고 10, 5 USDC UTXO는 미사용 상태로 유지됩니다. 트랜잭션은 Bob에게 80 USDC, Alice에게 5 USDC가 든 UTXO와 사용하지 않는 슬롯에 0 USDC 더미 UTXO 하나를 생성합니다." width="520" height="286" data-path="images/privacy/utxo-variant-3-3.svg" />
  </Tab>

  <Tab title="4 spent, 3 new">
    Alice가 Bob에게 95 USDC를 보냅니다. Alice의 가장 큰 UTXO 네 개로 전송 금액을 충당할 수 있습니다. SDK는 사용하지 않는 슬롯 두 개를 더미 UTXO로 채웁니다.

    <img src="https://mintcdn.com/helius/ITnDOhn5GRfQ1FQW/images/privacy/utxo-variant-4-3.svg?fit=max&auto=format&n=ITnDOhn5GRfQ1FQW&q=85&s=cf9bdd94965b8861ca25247bbe078c1c" alt="Alice의 40, 25, 20, 10 USDC UTXO가 사용되고 5 USDC UTXO는 미사용 상태로 유지됩니다. 트랜잭션은 Bob에게 95 USDC가 든 UTXO와 사용하지 않는 슬롯에 0 USDC 더미 UTXO 두 개를 생성합니다." width="520" height="286" data-path="images/privacy/utxo-variant-4-3.svg" />
  </Tab>
</Tabs>

<Accordion title="Supported transaction variants">
  | 사용된 UTXO | 새 UTXO |
  | - | - |
  | 1 | 1, 2 또는 8 |
  | 2 | 2 또는 3 |
  | 3 | 3 |
  | 4 | 3 또는 4 |
  | 5 | 3 또는 4 |
  | 36 | 2 |

  <Info>
    소스 코드 보기: [사양](https://github.com/helius-labs/zolana/blob/a3ddedda42b40d4951ae8fcdde2500374c4f2125/docs/spec.md#circuit-variants) · [지원되는 변형](https://github.com/helius-labs/zolana/blob/a3ddedda42b40d4951ae8fcdde2500374c4f2125/program-libs/interface/src/shape.rs)
  </Info>
</Accordion>

## UTXO 병합

잔액을 사용하지 않고 여러 전송을 받으면 비공개 잔액이 여러 UTXO로 분할될 수 있습니다.

전송에 36개가 넘는 UTXO가 필요하면 먼저 병합하여 사용자가 전체 잔액을 한 번에 전송할 수 있게 하세요.
한 번의 전송에서 최대 36개의 UTXO를 사용할 수 있으므로 대부분의 사용자는 잔액 분할을 거의 경험하지 않습니다.

* 병합은 소유자와 자산이 같은 UTXO를 총액이 동일한 UTXO 하나로 결합합니다.
* 병합으로 자금을 사용하거나 소유자를 변경할 수 없습니다.
* 최종 사용자 UX에 영향을 주지 않고 내부적으로 병합할 수 있습니다.

<img src="https://mintcdn.com/helius/ITnDOhn5GRfQ1FQW/images/privacy/utxo-merge.svg?fit=max&auto=format&n=ITnDOhn5GRfQ1FQW&q=85&s=2fb4f8d2bad662806127ff1c4fb7687f" alt="병합은 Alice가 보유한 각각 1 USDC가 든 UTXO 다섯 개를 사용하고 Alice를 위해 5 USDC가 든 새 UTXO 하나를 생성합니다." width="520" height="270" data-path="images/privacy/utxo-merge.svg" />

한 번의 전송으로 전체 잔액을 사용하기 위해 필요한 병합 횟수는 잔액을 보유한 UTXO 수에 따라 달라집니다.

| 잔액의 UTXO 수 | 전송 전 병합 | 전송 |
| - | - | - |
| 1\~36 | 없음 | 한 번의 전송으로 모든 UTXO 사용 |
| 37 | UTXO 2개를 한 번 병합 | UTXO 36개로 한 번 전송 |
| 100 | UTXO 36개를 두 번 병렬로 병합 | UTXO 30개로 한 번 전송 |
| 1,296 | UTXO 36개를 36번 병렬로 병합 | UTXO 36개로 한 번 전송 |

각 병합은 ZK 증명이 포함된 하나의 Solana 트랜잭션이며 최대 36개의 UTXO를 하나로 합칩니다.
병합 결과는 결정적이므로 병합 증명과 전송 증명이 병렬로 생성됩니다.

### 병합 명령 사용 예시

애플리케이션은 다음 두 시점에 병합할 수 있습니다.

* **비공개 잔액을 동기화할 때:** 지갑 잠금 해제, 비공개 지갑 열기, 앱 재개, 네트워크 재연결, 스트림 누락 또는 지갑 복원 시입니다.
* **전송 전:** 전송에 36개가 넘는 UTXO가 필요할 때입니다.

<Info>
  병합은 사용자 서명 없이 실행됩니다. 사용자 지정 Ring은 자체 병합 권한을 설정합니다.
  내장 비공개 지갑을 사용하면 내부적으로 병합이 자동으로 수행됩니다.
</Info>

<Accordion title="Example for Merge">
  예를 들어 비공개 지갑이 각각 1 USDC인 비공개 전송을 1,296번 받은 후 1,296개의 UTXO에 1,296 USDC를 보유하고 있다고 가정해 보겠습니다.
  한 번의 전송으로 최대 36개의 UTXO를 사용할 수 있으므로 지갑은 다음 두 단계로 잔액을 사용합니다.

  1. 36개의 병합 트랜잭션을 병렬로 실행하여 각각 36 USDC가 든 UTXO 36개를 생성합니다.
  2. 입력이 36개인 한 번의 전송으로 1,296 USDC 전체 잔액을 사용합니다.

  <Info>
    예제 코드 보기: [sdk-tests/client/rust/optimized\_merge\_transfer.rs](https://github.com/helius-labs/zolana/blob/1be5fe5c8865badd2852617d18a8f5ca06b592f1/sdk-tests/client/rust/optimized_merge_transfer.rs) · [sdk-tests/client/typescript/optimized-merge-transfer.test.ts](https://github.com/helius-labs/zolana/blob/1be5fe5c8865badd2852617d18a8f5ca06b592f1/sdk-tests/client/typescript/optimized-merge-transfer.test.ts)
  </Info>
</Accordion>

<a id="latency-and-concurrency" />

## UTXO 동시성

사용자는 트랜잭션이 최종 확정되는 즉시 비공개 잔액을 사용할 수 있습니다.

비공개 잔액이 여러 UTXO로 분할되어 있으면 동시에 사용할 수 있습니다. 각 UTXO는 별도의 트랜잭션에서 동시에 사용할 수 있습니다. 예를 들어 각각 100 USDC인 UTXO 세 개로 구성된 잔액은 한 번에 최대 100 USDC인 전송 세 건에 자금을 제공할 수 있습니다. 지갑은 사용할 UTXO를 선택합니다.

<img src="https://mintcdn.com/helius/ITnDOhn5GRfQ1FQW/images/privacy/utxo-concurrency.svg?fit=max&auto=format&n=ITnDOhn5GRfQ1FQW&q=85&s=5888bf355ed8aef63ea7cb43c63f0bcd" alt="각각 100 USDC인 Alice의 UTXO 세 개가 동시에 세 건의 전송에 자금을 제공하며, 전송마다 UTXO 하나를 사용합니다." width="420" height="200" data-path="images/privacy/utxo-concurrency.svg" />

단일 UTXO는 한 번만 사용할 수 있습니다.

프로토콜의 처리량 한도는 [상태 Merkle 트리 및 Forester](/docs/ko/privacy/concepts/architecture#상태-머클-트리와-forester)를 참조하세요.

## 자세히 알아보기

<CardGroup cols={2}>
  <Card title="Overview" icon="book" href="/docs/ko/privacy/concepts/overview">
    Ring, 개인정보 보호 보장 및 트랜잭션 흐름을 알아보세요.
  </Card>

  <Card title="Architecture" icon="diagram-project" href="/docs/ko/privacy/concepts/architecture">
    지갑, RPC 서비스 및 Solana 프로그램이 상호 작용하는 방식을 알아보세요.
  </Card>

  <Card title="Encryption and Privacy Guarantees" icon="key" href="/docs/ko/privacy/concepts/encryption">
    자산이 암호화되는 방식과 보호된 키 쌍의 역할을 알아보세요.
  </Card>

  <Card title="Custom Enterprise Rings" icon="building" href="/docs/ko/privacy/integration/enterprise">
    사용자 지정 Ring을 구성하는 방법을 알아보세요.
  </Card>
</CardGroup>

## 원하는 정보를 찾지 못하셨나요?

<Callout type="info">
  문의하세요! [Telegram](https://t.me/tilo_light) | [이메일](mailto:sales@helius.xyz) | [Typeform](https://form.typeform.com/to/LPFASU8a)
</Callout>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.