Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,14 @@ When updating documentation values that include GitHub source links:
- Update the line anchor (`#L`) to match the correct line **in the branch the link points to**
- When available, use the local platform repository checkout to verify line numbers against the correct branch

## Adding a new doc page

A new page is only visible in the rendered site if it appears in a Sphinx toctree. Sphinx will emit a `document isn't included in any toctree` warning at build time for any orphaned page, and the page won't show up in the sidebar.

Top-level toctrees live in [docs/index.md](docs/index.md), grouped by section caption (`Tutorials`, `Explanations`, `Reference`, `Platform Protocol Reference`, `Resources`). When you add a new page under `docs/<section>/`, add its path (without the `.md` extension) to the matching toctree in `docs/index.md`. After editing the toctree, run `python scripts/sync_sidebar.py` so the custom sidebar template picks up the new entry.

Tutorials and the TUI section use nested `index.md` files with their own toctrees — check the parent `index.md` of the directory you're adding to.

## DAPI endpoint reference

The DAPI endpoint reference is split between an overview page (`docs/reference/dapi-endpoints.md`) and per-section detail pages (`docs/reference/dapi-endpoints-*.md`). The authoritative list of endpoints lives in the platform proto at `https://github.com/dashpay/platform/tree/<branch>/packages/dapi-grpc/protos` — check the proto when adding or modifying entries.
Expand Down
10 changes: 10 additions & 0 deletions _templates/sidebar-main.html
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,11 @@
DashPay
</a>
</li>
<li class="toctree-l1">
<a class="reference internal" href="docs/explanations/shielded-pool.html">
Shielded Pool
</a>
</li>
<li class="toctree-l1">
<a class="reference internal" href="docs/explanations/fees.html">
Fees
Expand Down Expand Up @@ -484,6 +489,11 @@
Platform Address System
</a>
</li>
<li class="toctree-l1">
<a class="reference internal" href="docs/protocol-ref/shielded-pool.html">
Shielded Pool
</a>
</li>
<li class="toctree-l1">
<a class="reference internal" href="docs/protocol-ref/protocol-constants.html">
Protocol Constants
Expand Down
73 changes: 73 additions & 0 deletions docs/explanations/shielded-pool.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
```{eval-rst}
.. _explanations-shielded-pool:
```

# Shielded Pool

## Overview

The shielded pool is an optional privacy layer on Dash Platform that lets users hold and move credits without revealing balances, sender, or recipient on-chain. Funds move *into* the pool through a shield transition, move *within* the pool privately, and exit through an unshield or shielded withdrawal. While funds remain inside the pool, only their owner can see them.

The pool uses the [Orchard](https://zips.z.cash/protocol/protocol.pdf) shielded protocol — the same zk-SNARK-based design used by Zcash for its current shielded pool. Transactions inside the pool prove their own validity without disclosing the amounts or parties involved.

## When to use the shielded pool

Shielded transitions cost more than transparent ones — they carry a zero-knowledge proof and produce permanent on-chain artifacts (note commitments, nullifiers, and encrypted note ciphertexts). Use the pool when you need confidentiality for a specific payment, transfer, or balance. Use transparent transitions for everyday activity where privacy is not a requirement.

The pool is well-suited to:

- Payments where the amount or counterparty should not be public.
- Holding balances privately before unshielding to spend transparently.
- Moving credits between identities or addresses you control without linking them.

## Core concepts

### Notes, commitments, and the note tree

Each unit of value in the pool is held as a **note** — an off-chain record describing an owner, an amount, and a unique randomness value. When a note is created, the platform records only its **commitment** (a hash of the note) into an append-only Merkle tree called the **note commitment tree**. The note itself is never published; only its commitment is, and the commitment reveals nothing about the note's contents.

The root of the note commitment tree is called an **anchor**. Anchors serve as snapshots that shielded transitions reference to prove "the note I am spending was added to the tree by some earlier transition." Spenders prove membership against an anchor without revealing *which* note they are spending.

### Nullifiers

When a note is spent, the spender publishes a unique **nullifier** derived from the note. The platform tracks all nullifiers ever published; spending the same note twice would produce the same nullifier and be rejected as a double-spend.

Nullifiers are unlinkable to their notes' commitments. An observer can see that *some* note was spent but cannot tell which one. This is how the pool prevents double-spends while preserving privacy.

### Encrypted notes

When a note is created for a recipient, the platform stores an **encrypted note payload** alongside the commitment. The recipient scans new encrypted notes, attempts trial decryption with their viewing key, and learns about notes addressed to them. Other observers see only opaque ciphertext.

### Actions and the action-count limit

A shielded transition is composed of one or more **actions**. Each action structurally pairs one spend (consuming a prior note) with one output (creating a new note), bundled together so observers cannot tell which spend funded which output. A single shielded transition is limited to **16 actions** to keep transitions within the platform's 20 KB state-transition size budget.

## Transition types

Five state transition types interact with the shielded pool. The wire-level structure of each — including field-by-field tables and source links — is documented in the [Shielded Pool protocol reference](../protocol-ref/shielded-pool.md).

### Shield

Moves credits *into* the pool from one or more [Platform addresses](../protocol-ref/address-system.md#platform-address) the sender controls. The total contributed across address inputs must cover the value being shielded plus the transition fee. Excess credits remain in the source addresses.

### Shield from asset lock

Moves credits *into* the pool directly from a Dash Core (L1) asset-lock transaction. This avoids first funding a Platform address and lets users enter the pool in a single Platform transition tied to an L1 lock proof.

### Shielded transfer

Moves credits *within* the pool — between notes — without any transparent surface. To an outside observer, only the actions, anchor, proof, and binding signature are visible; the sender, recipient, and amount remain private.

### Unshield

Moves credits *out of* the pool to a [Platform address](../protocol-ref/address-system.md#platform-address) the sender designates. The unshielded amount becomes spendable through normal address-based transitions.

### Shielded withdrawal

Moves credits *out of* the pool back to Dash Core (L1) via the platform's withdrawal mechanism. Like an unshield, it reveals an amount and an L1 destination, but the funds leave Platform entirely rather than landing in a Platform address.

## What the pool does not provide

- **Anonymity sets**: The privacy guarantee depends on how many other notes exist in the pool. A pool with a single user offers limited cover; privacy improves as more users participate.
- **L1 transaction privacy**: Funds entering or leaving the pool traverse transparent transitions or L1 transactions on either side. Only activity *inside* the pool is shielded.
- **Hiding the act of using the pool**: Observers can see that a transition is a shield, unshield, or transfer — they just cannot see who or how much is involved on the shielded side.
2 changes: 2 additions & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ explanations/dpns
explanations/drive
explanations/platform-consensus
explanations/dashpay
explanations/shielded-pool
explanations/fees
explanations/tokens
explanations/nft
Expand Down Expand Up @@ -164,6 +165,7 @@ protocol-ref/document
protocol-ref/token
protocol-ref/data-trigger
protocol-ref/address-system
protocol-ref/shielded-pool
protocol-ref/protocol-constants
protocol-ref/errors
```
Expand Down
3 changes: 2 additions & 1 deletion docs/protocol-ref/protocol-constants.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ Maximum sizes and limits for various platform components.
| Max withdrawal amount | 50,000,000,000,000 credits | 500 Dash maximum per withdrawal | [rs-platform-version](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-platform-version/src/version/system_limits/v1.rs#L10) |
| Max contract group size | 256 | Maximum members per group | [rs-platform-version](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-platform-version/src/version/system_limits/v1.rs#L11) |
| Max token redemption cycles | 128 | Maximum redemption cycles | [rs-platform-version](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-platform-version/src/version/system_limits/v1.rs#L12) |
| Max shielded transition actions | 100 | Maximum shielded transitions per batch | [rs-platform-version](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-platform-version/src/version/system_limits/v1.rs#L13) |
| Max shielded transition actions | 16 | Maximum [actions](shielded-pool.md#actions) per shielded transition | [rs-platform-version](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-platform-version/src/version/system_limits/v1.rs#L27) |
| Max CBOR encoded length | 16,384 bytes (16 KiB) | Maximum CBOR encoding size | [rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/util/cbor_serializer.rs#L8) |
| Contract deserialization limit | 15,000 | Maximum contract deserialization | [rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/data_contract/serialized_version/mod.rs#L38) |

Expand Down Expand Up @@ -268,6 +268,7 @@ These limits apply to token perpetual distribution function parameters.
| Max fee strategies | 4 | Maximum fee strategy steps | [rs-platform-version](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-platform-version/src/version/dpp_versions/dpp_state_transition_versions/v3.rs#L45) |
| Max address inputs | 16 | Maximum input addresses per address-based transition | [rs-platform-version](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-platform-version/src/version/dpp_versions/dpp_state_transition_versions/v3.rs#L43) |
| Max address outputs | 128 | Maximum output addresses per address-based transition | [rs-platform-version](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-platform-version/src/version/dpp_versions/dpp_state_transition_versions/v3.rs#L44) |
| Max asset lock transaction inputs | 100 | Maximum L1 transaction inputs in an asset lock proof | [rs-platform-version](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-platform-version/src/version/dpp_versions/dpp_state_transition_versions/v3.rs#L25) |

## Epoch and Time Constants

Expand Down
Loading
Loading