From a07df375e9789340f051e0b4124509cb010b55cb Mon Sep 17 00:00:00 2001 From: thephez Date: Thu, 21 May 2026 12:40:46 -0400 Subject: [PATCH 1/8] docs: v3.1 minor cleanup (Proofs page, address encoding, constants) (#148) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs(protocol-ref): update for v3.1 PlatformAddress encoding and remove feature-flags contract PR #3059 renamed the PlatformAddress HRPs (evo/tevo → dash/tdash) and introduced two distinct byte encodings (user-facing bech32m vs. internal GroveDB storage). PR #3522 removed the feature-flags system contract. Refresh source-line anchors against current rs-dpp line numbers. Co-Authored-By: Claude Opus 4.7 (1M context) * docs(explanations): add Proofs explanation page Cover the two-layer proof model (GroveDB Merkle proofs + Tenderdash consensus signatures), what can be proven, the v3.1 aggregate proof primitives (count/sum/average), and asset lock proofs. Wire it into the explanations toctree. Co-Authored-By: Claude Opus 4.7 (1M context) * docs(protocol-ref): document max_asset_lock_transaction_inputs constant Introduced in protocol v3 (#3491) to prevent stuck funds; v1 and v2 had no effective limit. Co-Authored-By: Claude Opus 4.7 (1M context) * chore: sync sidebar * docs: clarify hrp --------- Co-authored-by: Claude Opus 4.7 (1M context) --- _templates/sidebar-main.html | 25 +++ .../platform-protocol-data-trigger.md | 1 - docs/explanations/proofs.md | 168 ++++++++++++++++++ docs/index.md | 1 + docs/protocol-ref/address-system.md | 19 +- docs/protocol-ref/protocol-constants.md | 9 +- .../connect-to-a-network-dash-masternode.md | 6 - 7 files changed, 207 insertions(+), 22 deletions(-) create mode 100644 docs/explanations/proofs.md diff --git a/_templates/sidebar-main.html b/_templates/sidebar-main.html index 8a3287e4c..56fa79b72 100644 --- a/_templates/sidebar-main.html +++ b/_templates/sidebar-main.html @@ -180,6 +180,26 @@ DashMint Lab — NFT marketplace +
  • + + Dashnote + +
  • +
  • + + DashMint Lite + +
  • +
  • + + Dashnote Lite + +
  • +
  • + + DashProof Lite + +
  • @@ -330,6 +350,11 @@ Non-Fungible Tokens (NFTs) +
  • + + Proofs + +
  • Query Capabilities diff --git a/docs/explanations/platform-protocol-data-trigger.md b/docs/explanations/platform-protocol-data-trigger.md index cbb02be66..b3ac7d9b2 100644 --- a/docs/explanations/platform-protocol-data-trigger.md +++ b/docs/explanations/platform-protocol-data-trigger.md @@ -41,6 +41,5 @@ In addition to DPNS, DPP ships data triggers for a small set of other system con | DashPay | `contactRequest` | [`CREATE`](https://github.com/dashpay/platform/tree/master/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/dashpay) | Enforces DashPay-specific rules on outgoing contact requests | | ---- | ---- | ---- | ---- | | Withdrawals | `withdrawal` | [`CREATE`/`REPLACE`/`DELETE`](https://github.com/dashpay/platform/tree/master/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/withdrawals) | Enforces withdrawal status transitions and prevents direct external mutation of withdrawal documents | -| Feature flags | (various) | [Protocol-version updates](https://github.com/dashpay/platform/tree/master/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/feature_flags) | Restricts feature flag changes to the authorized feature-flag identity | When document state transitions are received, DPP checks if there is a trigger associated with the document type and action. If a trigger is found, DPP executes the trigger logic. Successful execution of the trigger logic is necessary for the document to be accepted and applied to the [platform state](../explanations/drive-platform-state.md). diff --git a/docs/explanations/proofs.md b/docs/explanations/proofs.md new file mode 100644 index 000000000..531cdf524 --- /dev/null +++ b/docs/explanations/proofs.md @@ -0,0 +1,168 @@ +```{eval-rst} +.. _explanations-proofs: +``` + +# Proofs + +## Overview + +Proofs are a fundamental security feature of Dash Platform that enable trustless verification of data. When retrieving information from the network, clients can request cryptographic proofs that allow them to verify the data's authenticity without trusting the individual node that provided it. + +This is particularly important in a decentralized system where any single node could potentially return incorrect or malicious data. With proofs, clients can mathematically verify that: + +- The data exists (or doesn't exist) in the platform state +- The state was agreed upon by the network's validator quorum +- No tampering occurred between the node and the client + +Proofs enable light clients and mobile applications to interact securely with Dash Platform without running a full node or blindly trusting remote servers. + +## How Proofs Work + +Dash Platform uses a two-layer proof architecture that combines Merkle proofs from the storage layer with consensus signatures from the validator network. + +### GroveDB Merkle Proofs + +The first layer of verification uses [GroveDB](https://github.com/dashpay/grovedb), Dash Platform's authenticated data structure. GroveDB organizes all platform data in a tree structure where each piece of data contributes to a cryptographic hash that rolls up to a single root hash. + +When a client requests data with a proof, GroveDB returns: + +- The requested data (or proof of its absence) +- A Merkle path showing how the data connects to the root hash + +This allows clients to independently calculate what the root hash should be and verify it matches. Any modification to the data would produce a different root hash, making tampering detectable. + +### Tenderdash Consensus Signatures + +The second layer connects the GroveDB root hash to the network's consensus. Dash Platform uses [Tenderdash](../explanations/platform-consensus.md), a Byzantine fault-tolerant consensus protocol, where validator quorums sign each block. + +The proof includes: + +- A BLS threshold signature from the validator quorum +- The quorum hash identifying which validators signed +- Block metadata (height, round, timestamp) + +Clients verify that the root hash from the GroveDB proof matches what the quorum signed. Since producing a valid BLS threshold signature requires participation from more than two-thirds of the quorum members, this proves the network agreed on this exact state. + +:::{tip} +BLS threshold signatures are particularly efficient because regardless of how many validators participated, the final signature is always the same compact size. This keeps proofs small even as the validator set scales. +::: + +### Verification Flow + +The complete verification process follows these steps: + +1. Client sends a request to [DAPI](../explanations/dapi.md) with `prove: true` +2. DAPI retrieves the data and generates a proof from [Drive](../explanations/drive.md) +3. Client receives the response containing data, GroveDB proof, and consensus signature +4. Client verifies the GroveDB proof to extract the root hash +5. Client verifies the BLS signature against the root hash using the quorum's public key +6. If both verifications pass, the data is cryptographically confirmed + +## What Can Be Proven + +Dash Platform supports proofs for all core data types: + +**Identities** + +- Identity existence and full details +- Identity balance and revision +- Public keys associated with an identity +- Identity nonces (for replay protection) + +**Data Contracts** + +- Contract existence and contents +- Contract history (for contracts that track changes) + +**Documents** + +- Document existence within a contract +- Document queries with multiple results +- Proof of document absence (data doesn't exist) +- Aggregate values over a document set (count, sum, average) — see [Aggregate Proofs](#aggregate-proofs) below + +**Tokens** + +- Token balances for identities +- Token total supply +- Token status and configuration + +**System State** + +- Current epoch information +- Protocol version and upgrade status +- Contested resource voting state + +## Aggregate Proofs + +Beyond proving the existence and contents of individual documents, Dash Platform can produce verifiable answers to aggregate queries — questions about a *set* of documents, answered with one or more aggregate values instead of a list. This avoids streaming and verifying every matching document just to learn how many there are or what they sum to. + +Three aggregate primitives are supported: + +- **Count** — number of documents matching the query. +- **Sum** — sum of an integer field across matching documents. +- **Average** — average of an integer field across matching documents. + +Some aggregate queries can return either one total or grouped totals, depending on the query shape. + +Aggregate queries use the same two-layer verification as any other proof (GroveDB Merkle proof plus Tenderdash consensus signature), so the result carries the same trust model as other proven Platform responses. + +For the exact request and response shapes, see the [DAPI Platform endpoints reference](../reference/dapi-endpoints-platform-endpoints.md). + +## Requesting and Verifying Proofs + +### DAPI Integration + +The Decentralized API (DAPI) provides the interface for requesting proofs. When making queries, clients can set the `prove` parameter to receive cryptographic proofs alongside the data. + +Without proofs, clients must trust that the DAPI node is returning accurate data. With proofs enabled, clients can verify responses independently, treating DAPI nodes as untrusted data carriers rather than trusted authorities. + +:::{note} +The Dash Platform SDKs handle proof verification automatically when proofs are requested. Developers using the SDK don't need to implement verification logic manually. +::: + +### What Verification Confirms + +When a proof verifies successfully, the client has cryptographic assurance that: + +1. **Data integrity**: The data matches exactly what is stored in platform state +2. **Consensus agreement**: A valid validator quorum signed this state at a specific block height +3. **Temporal accuracy**: The proof is tied to a specific block height and timestamp +4. **Completeness**: For queries, all matching results are included (nothing omitted) + +Proof verification also detects proof-of-absence, confirming when requested data genuinely doesn't exist rather than being withheld by a malicious node. + +## Asset Lock Proofs + +Asset lock proofs are a special category used when creating or funding [identities](../explanations/identity.md). They prove that Dash has been locked on the core blockchain (layer 1) to establish credits on Dash Platform (layer 2). + +### Instant Asset Lock Proof + +Uses Dash's InstantSend feature to prove funds are locked immediately: + +- Contains the InstantSend lock proving transaction finality +- Includes the asset lock special transaction +- Enables immediate identity creation without waiting for block confirmations + +This is the preferred method as it allows near-instant identity creation. + +### Chain Asset Lock Proof + +Uses ChainLocks to prove funds are locked at a specific core blockchain height: + +- References the asset lock transaction by its outpoint +- Specifies the core chain height where the transaction was chain-locked +- Provides finality guarantee through Dash's ChainLock mechanism + +This method is used when InstantSend confirmation is not available. + +:::{attention} +Asset lock proofs are verified by the network during identity creation and topup state transitions. The locked funds cannot be spent on the core chain once used to create platform credits. +::: + +## Related Topics + +- [Platform Consensus](../explanations/platform-consensus.md) - How Tenderdash and validator quorums work +- [Identity](../explanations/identity.md) - Identity creation using asset lock proofs +- [DAPI](../explanations/dapi.md) - The API layer for requesting proofs +- [Drive](../explanations/drive.md) - The storage layer that generates proofs diff --git a/docs/index.md b/docs/index.md index 7c9f81501..e89b33b43 100644 --- a/docs/index.md +++ b/docs/index.md @@ -134,6 +134,7 @@ explanations/dashpay explanations/fees explanations/tokens explanations/nft +explanations/proofs explanations/query ``` diff --git a/docs/protocol-ref/address-system.md b/docs/protocol-ref/address-system.md index 55e97c2ae..cd078e609 100644 --- a/docs/protocol-ref/address-system.md +++ b/docs/protocol-ref/address-system.md @@ -27,19 +27,16 @@ There are six address-based state transition types: ### Platform Address -Platform addresses are derived from standard Bitcoin/Dash address formats and encoded using bech32m per [DIP-0018](https://github.com/dashpay/dips/blob/master/dip-0018.md). +Platform addresses are derived from standard Bitcoin/Dash address formats and encoded as bech32m strings per [DIP-0018](https://github.com/dashpay/dips/blob/master/dip-0018.md). The human-readable part (HRP) is `dash` on mainnet and `tdash` on testnet, devnet, and regtest. The 21-byte payload is `type_byte || Hash160(compressed_pubkey)`, where `Hash160 = RIPEMD160(SHA256(x))`. The checksum is bech32m ([BIP-350](https://github.com/bitcoin/bips/blob/master/bip-0350.mediawiki)). -| Variant | Type Byte | Size | Description | -| ------- | ---- | -------- | ---------------------------------------------------- | -| `P2PKH` | 0xb0 | 21 bytes | Pay-to-Public-Key-Hash (1 type byte + 20 hash bytes) | -| `P2SH` | 0x80 | 21 bytes | Pay-to-Script-Hash (1 type byte + 20 hash bytes) | +| Variant | Type Byte | Description | +| ------- | --------- | ----------- | +| `P2PKH` | 0xb0 | Pay-to-Public-Key-Hash | +| `P2SH` | 0x80 | Pay-to-Script-Hash | -**Encoding:** - -- **Mainnet HRP:** `dash` -- **Testnet HRP:** `tdash` (also used for Devnet and Regtest) - -**Derivation:** Standard Bitcoin derivation using `Hash160(compressed_pubkey)` where Hash160 = RIPEMD160(SHA256(x)). +:::{note} +A `PlatformAddress` has two distinct byte encodings depending on context. The type bytes above (`0xb0` / `0x80`) apply to the user-facing bech32m encoding — what appears in address strings like `dash1k...`. Internal GroveDB storage keys use bincode variant indices `0x00` / `0x01` instead. Decoding one through the other's code path will fail. +::: See the [Platform address implementation in rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/address_funds/platform_address.rs). diff --git a/docs/protocol-ref/protocol-constants.md b/docs/protocol-ref/protocol-constants.md index 4d0b94995..c06962160 100644 --- a/docs/protocol-ref/protocol-constants.md +++ b/docs/protocol-ref/protocol-constants.md @@ -177,6 +177,7 @@ Fees related to contested document voting. | Min top-up balance | 50,000 duffs | 0.0005 Dash minimum | [rs-platform-version](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-platform-version/src/version/dpp_versions/dpp_state_transition_versions/v1.rs#L21) | | Min address funding balance | 50,000 duffs | 0.0005 Dash minimum | [rs-platform-version](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-platform-version/src/version/dpp_versions/dpp_state_transition_versions/v1.rs#L22) | | Min identity funding amount | 200,000 credits | Minimum for address-based creation | [rs-platform-version](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-platform-version/src/version/dpp_versions/dpp_state_transition_versions/v1.rs#L41) | +| Max asset-lock transaction inputs | 100 | Maximum Core inputs in an asset-lock transaction used to fund an identity or top-up (introduced in protocol v3 to prevent stuck funds; v1/v2 had no effective limit) | [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) | ## Document & Data Contract Model @@ -253,10 +254,10 @@ These limits apply to token perpetual distribution function parameters. | Constant | Value | Description | Source | |----------|-------|-------------|--------| | Address hash size | 20 bytes | Size of address hash | [rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/address_funds/platform_address.rs#L22) | -| Platform HRP (mainnet) | "dash" | Human-readable prefix | [rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/address_funds/platform_address.rs#L89) | -| Platform HRP (testnet) | "tdash" | Testnet human-readable prefix | [rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/address_funds/platform_address.rs#L91) | -| P2PKH address type | 0xb0 (176) | Pay-to-public-key-hash encoding type byte | [rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/address_funds/platform_address.rs#L95) | -| P2SH address type | 0x80 (128) | Pay-to-script-hash encoding type byte | [rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/address_funds/platform_address.rs#L97) | +| Platform HRP (mainnet) | "dash" | Human-readable prefix | [rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/address_funds/platform_address.rs#L184) | +| Platform HRP (non-mainnet) | "tdash" | Human-readable prefix used for testnet, devnet, and regtest | [rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/address_funds/platform_address.rs#L186) | +| P2PKH address type (bech32m) | 0xb0 (176) | Pay-to-public-key-hash bech32m encoding type byte | [rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/address_funds/platform_address.rs#L190) | +| P2SH address type (bech32m) | 0x80 (128) | Pay-to-script-hash bech32m encoding type byte | [rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/address_funds/platform_address.rs#L192) | ### Transaction Limits diff --git a/docs/tutorials/node-setup/connect-to-a-network-dash-masternode.md b/docs/tutorials/node-setup/connect-to-a-network-dash-masternode.md index 3d2f03800..8d007fe21 100644 --- a/docs/tutorials/node-setup/connect-to-a-network-dash-masternode.md +++ b/docs/tutorials/node-setup/connect-to-a-network-dash-masternode.md @@ -44,12 +44,6 @@ Example (partial) output of the setup wizard showing important information: › Dashpay contract ID: EAv8ePXREdJ719ntcRiKuEYxv9XooMwL1mJmPHMGuW9r ✔ Obtain Dashpay contract commit block height › Dashpay contract block height: 15 - ✔ Register Feature Flags identity - › Feature Flags identity: 8BsvV4RCbW7srWj81kgjJCykRBF2rzyigys8XkBchY96 - ✔ Register Feature Flags contract - › Feature Flags contract ID: JDrDAGVqTWsM9k7KGBsSjcyC11Vd2UdPxPoPf4NzyyrP - ✔ Obtain Feature Flags contract commit block height - › Feature Flags contract block height: 20 ``` From 35c27c7c84bd83b4d7d8efb007fcf64555fb5955 Mon Sep 17 00:00:00 2001 From: thephez Date: Tue, 26 May 2026 14:03:10 -0400 Subject: [PATCH 2/8] docs(reference): document v3.1 getDocuments v0/v1 and aggregate queries (#149) * docs(reference): document v3.1 getDocuments v0/v1 surface and aggregate queries Rewrite the getDocuments entry to cover the v0 legacy CBOR surface and the v1 typed SQL-shaped surface with Fetch / Count / Sum / Average modes. Add doctype-level aggregate query flags (documentsCountable, rangeCountable, documentsSummable, rangeSummable, documentsAverageable, rangeAverageable) to the data-contract-document reference, an aggregate-queries section to query-syntax, and a v3.1 annotation on the dapi-endpoints overview row. Co-Authored-By: Claude Opus 4.7 (1M context) * docs: add DAPI endpoint reference convention and release checklist Co-Authored-By: Claude Opus 4.7 (1M context) --------- Co-authored-by: Claude Opus 4.7 (1M context) --- CLAUDE.md | 12 + RELEASE.md | 14 + conf.py | 1 + docs/protocol-ref/data-contract-document.md | 27 + docs/protocol-ref/data-contract.md | 2 +- .../dapi-endpoints-platform-endpoints.md | 462 ++++++++++++------ docs/reference/dapi-endpoints.md | 2 +- docs/reference/query-syntax.md | 24 + 8 files changed, 406 insertions(+), 138 deletions(-) create mode 100644 RELEASE.md diff --git a/CLAUDE.md b/CLAUDE.md index 01c6b2abe..8cc4a1371 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -74,6 +74,18 @@ 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 +## 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//packages/dapi-grpc/protos` — check the proto when adding or modifying entries. + +When you add or materially update an entry on a detail page, also update the matching row on `dapi-endpoints.md`: + +- Keep the description in sync between the two pages. +- Prefix the overview row's description with `**Added in Dash Platform vX.Y.Z**` (new endpoints) or `**Updated in Dash Platform vX.Y.Z**` (modified endpoints), followed by `
    ` and the description. Use **bold** for the current release's annotations; older releases use *italics*. +- For a whole new endpoint group, wrap the new section in a `:::{versionadded} X.Y.Z` admonition above its table — see Security Groups, Tokens, Address System, and Shielded Transactions for the pattern. + +For the full per-release endpoint review process (proto diff, example refresh, demoting annotations to italics), see [RELEASE.md](RELEASE.md). + ## File Patterns - Documentation files: `docs/**/*.md` diff --git a/RELEASE.md b/RELEASE.md new file mode 100644 index 000000000..c87e3594d --- /dev/null +++ b/RELEASE.md @@ -0,0 +1,14 @@ +# Release Checklist + +Per-release tasks for the docs. For editing conventions, see [CLAUDE.md](CLAUDE.md). + +## DAPI endpoint review + +1. Diff the platform proto between the previous release tag and the current release branch — that's the source of truth for what changed. Proto source: `https://github.com/dashpay/platform/tree//packages/dapi-grpc/protos`. +2. For each affected endpoint, update both the detail page (`docs/reference/dapi-endpoints-*.md`) and the matching row on the overview page (`docs/reference/dapi-endpoints.md`), with the bold version annotation on the overview row. +3. Demote the previous release's bold annotations on the overview page to italics. +4. Re-run example requests against testnet and refresh response examples if necessary. Testnet state may have been wiped, so even unchanged endpoints may have stale data. + +## Update "Previous version" links + +Several pages (including the DAPI endpoints pages) link to the previous version of the docs. These links are not updated automatically. Search the site for "previous version" and update each link to point to the appropriate version. diff --git a/conf.py b/conf.py index f4814c927..8945ee5ff 100644 --- a/conf.py +++ b/conf.py @@ -41,6 +41,7 @@ '.DS_Store', 'README.md', 'CLAUDE.md', + 'RELEASE.md', '.devcontainer', '.codex', '.local', diff --git a/docs/protocol-ref/data-contract-document.md b/docs/protocol-ref/data-contract-document.md index ce360232e..22d85fbcc 100644 --- a/docs/protocol-ref/data-contract-document.md +++ b/docs/protocol-ref/data-contract-document.md @@ -328,6 +328,33 @@ The following example (from the [DPNS contract's `domain` document](https://gith } ``` +## Aggregate Query Flags + +:::{versionadded} 3.1.0 +::: + +Document types can opt into aggregate query support (count / sum / average) by setting flags at the document-type level. These flags control the underlying storage layout — once set on a published contract they cannot be changed by a contract update. + +There are two axes: + +* **Doctype-wide** (`documents*`) — applies the aggregate over the entire document type. Set at the document type root, alongside other doctype options like `documentsKeepHistory`. +* **Per-index range** (`range*`) — extends the corresponding aggregate to range queries on indexed properties. Set on the index's property entry. Requires the matching base flag. + +| Flag | Type | Purpose | Required for | +| - | - | - | - | +| `documentsCountable` | Boolean | Doctype-wide counts (empty `where` or `==`/`IN` clauses on indexed fields). | `SELECT COUNT(*)` without a range clause. | +| `rangeCountable` | Boolean | Per-index counts over a range. Requires `documentsCountable`. | `SELECT COUNT(*)` with a range clause or `GROUP BY `. | +| `documentsSummable` | String | Doctype-wide sums of the named integer property. | `SELECT SUM()`. | +| `rangeSummable` | Boolean | Per-index sums over a range. Requires `documentsSummable`. | `SELECT SUM()` with a range clause. | +| `documentsAverageable` | String | Syntactic sugar for `documentsCountable: true` + `documentsSummable: ""`. | `SELECT AVG()`. | +| `rangeAverageable` | Boolean | Syntactic sugar for `rangeCountable: true` + `rangeSummable: true`. Requires `documentsAverageable`. | `SELECT AVG()` with a range clause. | + +The averageable flags desugar to the underlying count + sum flags during contract parsing — same on-disk layout — so authors who think in terms of averages get a single flag and downstream code paths (insert, query, estimation) stay unchanged. If both `documentsAverageable` and `documentsSummable` are set, they must name the same property. + +These flags are validated against the v1 document meta-schema and are rejected when applied to pre-v12 contracts. The full v1 meta-schema, including these flags, is defined [in rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/schema/meta_schemas/document/v1/document-meta.json). + +See the [`getDocuments` reference](../reference/dapi-endpoints-platform-endpoints.md#getdocuments) for the request/response shapes that consume these flags. + ## Keyword Constraints There are a variety of keyword constraints currently defined for performance and security reasons. The diff --git a/docs/protocol-ref/data-contract.md b/docs/protocol-ref/data-contract.md index 252be8ec7..c2c351576 100644 --- a/docs/protocol-ref/data-contract.md +++ b/docs/protocol-ref/data-contract.md @@ -740,7 +740,7 @@ property must be incremented if the contract is updated. ### Data Contract documents -See the [data contract documents](./data-contract-document.md) page for details. +See the [data contract documents](./data-contract-document.md) page for details, including the [aggregate query flags](./data-contract-document.md#aggregate-query-flags) that opt document types into count/sum/average queries. ### Data Contract config diff --git a/docs/reference/dapi-endpoints-platform-endpoints.md b/docs/reference/dapi-endpoints-platform-endpoints.md index 47ca03209..9ec4003da 100644 --- a/docs/reference/dapi-endpoints-platform-endpoints.md +++ b/docs/reference/dapi-endpoints-platform-endpoints.md @@ -984,32 +984,89 @@ grpcurl -proto protos/platform/v0/platform.proto \ ### getDocuments -**Returns**: [Document](../explanations/platform-protocol-document.md) information for the requested document(s) -**Parameters**: +:::{versionchanged} 3.1.0 +Adds a typed v1 request surface (`WhereClause` / `OrderClause` / `Select`) and four aggregate modes — `DOCUMENTS`, `COUNT`, `SUM`, `AVG`. The legacy v0 CBOR surface is still supported. +::: -:::{note} -The `where`, `order_by`, `limit`, `start_at`, and `start_after` parameters must comply with the limits defined on the [Query Syntax](../reference/query-syntax.md) page. -::: - -| Name | Type | Required | Description | -| ----------------------- | ------- | -------- | ------------------------------------------------------------------------------------------------ | -| `data_contract_id` | Bytes | Yes | A data contract `id` | -| `document_type` | String | Yes | A document type defined by the data contract (e.g. `preorder` or `domain` for the DPNS contract) | -| `where` \* | Bytes | No | Where clause to filter the results | -| `order_by` \* | Bytes | No | Sort records by the field(s) provided | -| `limit` | Integer | No | Maximum number of results to return | -| ---------- | | | | -| _One_ of the following: | | | | -| `start_at` | Integer | No | Return records beginning with the index provided | -| `start_after` | Integer | No | Return records beginning after the index provided | -| ---------- | | | | -| `prove` | Boolean | No | Set to `true` to receive a proof that contains the requested document(s). The data requested will be encoded as part of the proof in the response. | +**Returns**: [Document](../explanations/platform-protocol-document.md) information for the requested document(s), or an aggregate count/sum/average over the matched document set. -**Example Request and Response** +The request envelope is `oneof version { v0; v1; }`. Pick a version per call: + +- **v1** (default for new code, v3.1+) — typed request fields and aggregate `select` modes. +- **v0** (legacy) — CBOR-encoded `where` / `order_by` byte strings. Fetch only. + +**Common request fields** (apply to every variant below) + +| Name | Type | Required | Description | +| ---- | ---- | -------- | ----------- | +| `data_contract_id` | Bytes | Yes | A data contract `id`. | +| `document_type` | String | Yes | A document type defined by the data contract. | +| `where_clauses` (v1) / `where` (v0) | Typed (v1) or CBOR bytes (v0) | No | Filter clauses. See [Query Syntax](../reference/query-syntax.md). | +| `order_by` | Typed (v1) or CBOR bytes (v0) | No | Sort order. See [Query Syntax](../reference/query-syntax.md). | +| `prove` | Boolean | No | Return a proof instead of data. See [Platform proofs](../reference/platform-proofs.md). | + +For v1, see also the [doctype-level aggregate flags](../protocol-ref/data-contract-document.md#aggregate-query-flags), which control whether a document type supports the `COUNT` / `SUM` / `AVG` modes below. + +#### Fetch documents + +Returns matched documents. + +**Mode-specific request fields** + +| Name | Type | Required | Description | +| ---- | ---- | -------- | ----------- | +| `limit` | Integer | No | Maximum number of documents to return. | +| `start_at` _or_ `start_after` | Bytes | No | Cursor — start at / after this document ID. | + +For v1, `selects` may be omitted (defaults to `[Select{ function: DOCUMENTS }]`) or set explicitly. + +**Example Request** ::::{tab-set} +:::{tab-item} v1 (gRPCurl) +:sync: v1-grpcurl + +```shell +# `data_contract_id` must be represented in base64 +grpcurl -proto protos/platform/v0/platform.proto \ + -d '{ + "v1": { + "data_contract_id": "5mjGWa9mruHnLBht3ntbfgodcSoJxA1XIfYiv1PFMVU=", + "document_type": "domain", + "where_clauses": [ + { "field": "normalizedParentDomainName", "operator": "EQUAL", "value": { "text": "dash" } } + ], + "limit": 1 + } + }' \ + seed-1.testnet.networks.dash.org:1443 \ + org.dash.platform.dapi.v0.Platform/getDocuments +``` + +::: + +:::{tab-item} v0 (gRPCurl) +:sync: v0-grpcurl + +```shell +# `data_contract_id` must be represented in base64 +grpcurl -proto protos/platform/v0/platform.proto \ + -d '{ + "v0": { + "data_contract_id": "5mjGWa9mruHnLBht3ntbfgodcSoJxA1XIfYiv1PFMVU=", + "document_type": "domain", + "limit": 1 + } + }' \ + seed-1.testnet.networks.dash.org:1443 \ + org.dash.platform.dapi.v0.Platform/getDocuments +``` + +::: + :::{tab-item} JavaScript (dapi-client) :sync: js-dapi-client + ```javascript const DAPIClient = require('@dashevo/dapi-client'); const { @@ -1029,11 +1086,8 @@ client.platform.getDataContract(contractId).then((contractResponse) => { dpp.dataContract .createFromBuffer(contractResponse.getDataContract()) .then((contract) => { - // Get document(s) client.platform - .getDocuments(contractId, type, { - limit, - }) + .getDocuments(contractId, type, { limit }) .then((response) => { for (const document of response.documents) { const doc = dpp.document.createExtendedDocumentFromDocumentBuffer( @@ -1047,155 +1101,291 @@ client.platform.getDataContract(contractId).then((contractResponse) => { }); }); ``` + ::: +:::: -:::{tab-item} JavaScript (dapi-grpc) -:sync: js-dapi-grpc -```javascript -const { - v0: { PlatformPromiseClient, GetDataContractRequest, GetDocumentsRequest }, -} = require('@dashevo/dapi-grpc'); -const { default: loadDpp, DashPlatformProtocol, Identifier } = require('@dashevo/wasm-dpp'); +**Example Response** -loadDpp(); -const dpp = new DashPlatformProtocol(null); -const platformPromiseClient = new PlatformPromiseClient( - 'https://seed-1.testnet.networks.dash.org:1443', -); +::::{tab-set} +:::{tab-item} v1 (gRPCurl) +:sync: v1-grpcurl -const contractId = Identifier.from('GWRSAVFMjXx8HpQFaNJMqBV7MBgMK4br5UESsB4S31Ec'); -const contractIdBuffer = Buffer.from(contractId); -const getDataContractRequest = new GetDataContractRequest(); -getDataContractRequest.setId(contractIdBuffer); +```json +{ + "v1": { + "data": { + "documents": { + "documents": [ + "AAZ1S7dbhY4VJrSCvjs2Z1DIwa9Qt9MAyjbJdh7gPu6oDsGC/h1Ayf+ZzXp2zLWDF4XB2qMLWZ0brsAKo0r/0sYBAAcAAAGRivixugAAAZGK+LG6AAABkYr4sboAF2F1ZzI1LTEyMzQ1Njc4OTAxMjM0NTY3F2F1ZzI1LTEyMzQ1Njc4OTAxMjM0NTY3AQRkYXNoBGRhc2gAIQEOwYL+HUDJ/5nNenbMtYMXhcHaowtZnRuuwAqjSv/SxgEA" + ] + } + }, + "metadata": { + "height": "5991", + "coreChainLockedHeight": 1097384, + "epoch": 1170, + "timeMs": "1725567845055", + "protocolVersion": 1, + "chainId": "dash-testnet-51" + } + } +} +``` -platformPromiseClient - .getDataContract(getDataContractRequest) - .then((contractResponse) => { - dpp.dataContract.createFromBuffer(contractResponse.getDataContract()).then((contract) => { - // Get documents - const getDocumentsRequest = new GetDocumentsRequest(); - const type = 'domain'; - const limit = 10; - - getDocumentsRequest.setDataContractId(contractIdBuffer); - getDocumentsRequest.setDocumentType(type); - // getDocumentsRequest.setWhere(whereSerialized); - // getDocumentsRequest.setOrderBy(orderBySerialized); - getDocumentsRequest.setLimit(limit); - // getDocumentsRequest.setStartAfter(startAfter); - // getDocumentsRequest.setStartAt(startAt); - - platformPromiseClient.getDocuments(getDocumentsRequest).then((response) => { - for (const document of response.getDocuments().getDocumentsList()) { - const documentBuffer = Buffer.from(document); - const doc = dpp.document.createExtendedDocumentFromDocumentBuffer( - documentBuffer, - type, - contract, - ); - console.log(doc.toJSON()); - } - }); - }); - }) - .catch((e) => console.error(e)); +::: + +:::{tab-item} v0 (gRPCurl) +:sync: v0-grpcurl + +```json +{ + "v0": { + "documents": { + "documents": [ + "AAZ1S7dbhY4VJrSCvjs2Z1DIwa9Qt9MAyjbJdh7gPu6oDsGC/h1Ayf+ZzXp2zLWDF4XB2qMLWZ0brsAKo0r/0sYBAAcAAAGRivixugAAAZGK+LG6AAABkYr4sboAF2F1ZzI1LTEyMzQ1Njc4OTAxMjM0NTY3F2F1ZzI1LTEyMzQ1Njc4OTAxMjM0NTY3AQRkYXNoBGRhc2gAIQEOwYL+HUDJ/5nNenbMtYMXhcHaowtZnRuuwAqjSv/SxgEA" + ] + }, + "metadata": { + "height": "5991", + "coreChainLockedHeight": 1097384, + "epoch": 1170, + "timeMs": "1725567845055", + "protocolVersion": 1, + "chainId": "dash-testnet-51" + } + } +} ``` + ::: -:::{tab-item} Request (gRPCurl) +:::{tab-item} JavaScript (decoded document) +:sync: js-dapi-client + +```json +{ + "$id": "Do3YtBPJG72zG4tCbN5VE8djJ6rLpvx7yvtMWEy89HC", + "$ownerId": "4pk6ZhgDtxn9yN2bbB6kfsYLRmUBH7PKUq275cjyzepT", + "label": "Chronic", + "normalizedLabel": "chr0n1c", + "normalizedParentDomainName": "dash", + "parentDomainName": "dash", + "records": { + "dashUniqueIdentityId": "OM4WaCQNLedQ0rpbl1UMTZhEbnVeMfL4941ZD08iyFw=" + }, + "subdomainRules": { "allowSubdomains": false }, + "$revision": 1, + "$type": "domain" +} +``` + +::: +:::: + +#### Count documents + +:::{versionadded} 3.1.0 +::: + +Returns one aggregate count, or per-group counts when `group_by` is set. Requires the doctype to set `documentsCountable: true` (and `rangeCountable: true` for range-grouped queries). See [aggregate query flags](../protocol-ref/data-contract-document.md#aggregate-query-flags). + +**Mode-specific request fields** + +| Name | Type | Required | Description | +| ---- | ---- | -------- | ----------- | +| `selects` | `[Select{ function: COUNT }]` | Yes | Projection. | +| `group_by` | Repeated string | No | `[]`, `[in_field]`, `[range_field]`, or `[in_field, range_field]`. | + +`limit` is rejected for `group_by=[]` and `group_by=[in_field]` (the result is bounded by construction). `start_at` / `start_after` are not valid in this mode — paginate by narrowing the where clause. + +**Response shape** + +- `group_by = []` → `counts.aggregate_count` (single integer). +- `group_by = [...]` → `counts.entries[]` of `{ in_key?, key, count }`. + +`IN` values that match no documents are omitted from `counts.entries` rather than returned with `count: 0`. Diff your request's `IN` array against the returned `key` values to detect "queried but absent." + +**Example Request** + +::::{tab-set} +:::{tab-item} gRPCurl :sync: grpcurl + ```shell -# Request documents -# `id` must be represented in base64 +# TODO: Replace with a real example once a contract using +# `documentsCountable` is published on testnet. The contract id, +# document type, and field name below are illustrative only. grpcurl -proto protos/platform/v0/platform.proto \ -d '{ - "v0": { - "data_contract_id":"5mjGWa9mruHnLBht3ntbfgodcSoJxA1XIfYiv1PFMVU=", - "document_type":"domain", - "limit":1 + "v1": { + "data_contract_id": "", + "document_type": "shipments", + "selects": [{ "function": "COUNT" }], + "where_clauses": [ + { "field": "status", "operator": "EQUAL", "value": { "text": "delivered" } } + ] } }' \ seed-1.testnet.networks.dash.org:1443 \ org.dash.platform.dapi.v0.Platform/getDocuments ``` + ::: :::: -::::{tab-set} -:::{tab-item} Response (JavaScript) -:sync: js-dapi-client +**Example Response** + ```json { - "$id":"Do3YtBPJG72zG4tCbN5VE8djJ6rLpvx7yvtMWEy89HC", - "$ownerId":"4pk6ZhgDtxn9yN2bbB6kfsYLRmUBH7PKUq275cjyzepT", - "label":"Chronic", - "normalizedLabel":"chr0n1c", - "normalizedParentDomainName":"dash", - "parentDomainName":"dash", - "preorderSalt":"1P9N5qv1Ww2xkv6/XXpsvymyGYychRsLXMhCqvW79Jo=", - "records":{ - "dashUniqueIdentityId":"OM4WaCQNLedQ0rpbl1UMTZhEbnVeMfL4941ZD08iyFw=" - }, - "subdomainRules":{ - "allowSubdomains":false - }, - "$revision":1, - "$createdAt":null, - "$updatedAt":null, - "$dataContract":{ - "$format_version":"0", - "id":"GWRSAVFMjXx8HpQFaNJMqBV7MBgMK4br5UESsB4S31Ec", - "config":{ - "$format_version":"0", - "canBeDeleted":false, - "readonly":false, - "keepsHistory":false, - "documentsKeepHistoryContractDefault":false, - "documentsMutableContractDefault":true, - "requiresIdentityEncryptionBoundedKey":null, - "requiresIdentityDecryptionBoundedKey":null + "v1": { + "data": { + "counts": { + "aggregateCount": "1234" + } }, - "version":1, - "ownerId":"EuzJmuZdBSJs2eTrxHEp6QqJztbp6FKDNGMeb4W2Ds7h", - "schemaDefs":null, - "documentSchemas":{ - "domain":[ - "Object" - ], - "preorder":[ - "Object" - ] - } - }, - "$type":"domain" + "metadata": { "height": "5991", "coreChainLockedHeight": 1097384 } + } } ``` + +Count values use `[jstype = JS_STRING]` on the proto, so JavaScript clients receive strings to avoid precision loss above `Number.MAX_SAFE_INTEGER`. + +#### Sum documents + +:::{versionadded} 3.1.0 ::: -:::{tab-item} Response (gRPCurl) +Returns the sum of an integer field across matched documents, or per-group sums when `group_by` is set. Requires the doctype to set `documentsSummable: ""` (and `rangeSummable: true` for range-grouped queries). See [aggregate query flags](../protocol-ref/data-contract-document.md#aggregate-query-flags). + +**Mode-specific request fields** + +| Name | Type | Required | Description | +| ---- | ---- | -------- | ----------- | +| `selects` | `[Select{ function: SUM, field: "" }]` | Yes | `field` must name the summable property. | +| `group_by` | Repeated string | No | Same shape rules as Count above. | + +`start_at` / `start_after` are not valid. + +**Response shape** + +- `group_by = []` → `sums.aggregate_sum` (signed integer). +- `group_by = [...]` → `sums.entries[]` of `{ in_key?, key, sum }`. + +**Example Request** + +::::{tab-set} +:::{tab-item} gRPCurl :sync: grpcurl + +```shell +# TODO: Replace with a real example once a contract using +# `documentsSummable` is published on testnet. The contract id, +# document type, and field name below are illustrative only. +grpcurl -proto protos/platform/v0/platform.proto \ + -d '{ + "v1": { + "data_contract_id": "", + "document_type": "inventory", + "selects": [{ "function": "SUM", "field": "quantity" }], + "where_clauses": [ + { "field": "warehouse", "operator": "EQUAL", "value": { "text": "north" } } + ] + } + }' \ + seed-1.testnet.networks.dash.org:1443 \ + org.dash.platform.dapi.v0.Platform/getDocuments +``` + +::: +:::: + +**Example Response** + ```json { - "v0": { - "documents": { - "documents": [ - "AAZ1S7dbhY4VJrSCvjs2Z1DIwa9Qt9MAyjbJdh7gPu6oDsGC/h1Ayf+ZzXp2zLWDF4XB2qMLWZ0brsAKo0r/0sYBAAcAAAGRivixugAAAZGK+LG6AAABkYr4sboAF2F1ZzI1LTEyMzQ1Njc4OTAxMjM0NTY3F2F1ZzI1LTEyMzQ1Njc4OTAxMjM0NTY3AQRkYXNoBGRhc2gAIQEOwYL+HUDJ/5nNenbMtYMXhcHaowtZnRuuwAqjSv/SxgEA" - ] + "v1": { + "data": { + "sums": { + "aggregateSum": "42000" + } }, - "metadata": { - "height": "5991", - "coreChainLockedHeight": 1097384, - "epoch": 1170, - "timeMs": "1725567845055", - "protocolVersion": 1, - "chainId": "dash-testnet-51" - } + "metadata": { "height": "5991", "coreChainLockedHeight": 1097384 } } } ``` + +#### Average documents + +:::{versionadded} 3.1.0 +::: + +Returns a `(count, sum)` pair the client divides to compute the average, or per-group `(count, sum)` pairs when `group_by` is set. Requires the doctype to set `documentsAverageable: ""` (and `rangeAverageable: true` for range-grouped queries). See [aggregate query flags](../protocol-ref/data-contract-document.md#aggregate-query-flags). + +Why `(count, sum)` instead of a single `average`? Returning the pair preserves full precision and lets the client pick how to represent the result (integer division, floating-point, decimal). + +**Mode-specific request fields** + +| Name | Type | Required | Description | +| ---- | ---- | -------- | ----------- | +| `selects` | `[Select{ function: AVG, field: "" }]` | Yes | `field` must name the averageable property. | +| `group_by` | Repeated string | No | Same shape rules as Count above. | + +`start_at` / `start_after` are not valid. + +**Response shape** + +- `group_by = []` → `averages.aggregate_average` of `{ count, sum }`. +- `group_by = [...]` → `averages.entries[]` of `{ in_key?, key, count, sum }`. + +**Example Request** + +::::{tab-set} +:::{tab-item} gRPCurl +:sync: grpcurl + +```shell +# TODO: Replace with a real example once a contract using +# `documentsAverageable` is published on testnet. The contract id, +# document type, and field name below are illustrative only. +grpcurl -proto protos/platform/v0/platform.proto \ + -d '{ + "v1": { + "data_contract_id": "", + "document_type": "ratings", + "selects": [{ "function": "AVG", "field": "score" }], + "where_clauses": [ + { "field": "productId", "operator": "EQUAL", "value": { "text": "abc123" } } + ] + } + }' \ + seed-1.testnet.networks.dash.org:1443 \ + org.dash.platform.dapi.v0.Platform/getDocuments +``` + ::: :::: +**Example Response** + +```json +{ + "v1": { + "data": { + "averages": { + "aggregateAverage": { + "count": "50", + "sum": "215" + } + } + }, + "metadata": { "height": "5991", "coreChainLockedHeight": 1097384 } + } +} +``` + +Client computes `avg = 215 / 50 = 4.3`. + ## Identity Endpoints ### getIdentity diff --git a/docs/reference/dapi-endpoints.md b/docs/reference/dapi-endpoints.md index 0e996f47d..9ea2f26d2 100644 --- a/docs/reference/dapi-endpoints.md +++ b/docs/reference/dapi-endpoints.md @@ -34,7 +34,7 @@ without introducing issues for endpoint consumers. | [`getDataContract`](../reference/dapi-endpoints-platform-endpoints.md#getdatacontract) | Returns the requested data contract | | [`getDataContracts`](../reference/dapi-endpoints-platform-endpoints.md#getdatacontracts) | Returns the requested data contracts | | [`getDataContractHistory`](../reference/dapi-endpoints-platform-endpoints.md#getdatacontracthistory) | Returns the requested data contract history | -| [`getDocuments`](../reference/dapi-endpoints-platform-endpoints.md#getdocuments) | Returns the requested document(s) | +| [`getDocuments`](../reference/dapi-endpoints-platform-endpoints.md#getdocuments) | **Updated in Dash Platform v3.1.0**
    Returns the requested document(s), or an aggregate count/sum/average over the matched document set. | ### Identities diff --git a/docs/reference/query-syntax.md b/docs/reference/query-syntax.md index 266dcc899..4bef41722 100644 --- a/docs/reference/query-syntax.md +++ b/docs/reference/query-syntax.md @@ -148,6 +148,30 @@ The query modifiers described here determine how query results will be sorted an For indices composed of multiple fields ([example from the DPNS data contract](https://github.com/dashpay/platform/blob/master/packages/dpns-contract/schema/v1/dpns-contract-documents.json)), the sort order in an `orderBy` must either match the order defined in the data contract OR be the inverse order. ::: +## Aggregate Queries + +:::{versionadded} 3.1.0 +::: + +The [getDocuments](../reference/dapi-endpoints-platform-endpoints.md#getdocuments) v1 surface adds an aggregate-query mode. The same `where` / `orderBy` clauses described above still apply; an additional `select` projection (and optional `groupBy`) determines whether the request returns documents or aggregate values over the matched set. + +| `select` | Returns | +| ---------------- | ------- | +| `DOCUMENTS` | Matched documents (same as v0). | +| `COUNT(*)` | Number of documents matching the query. | +| `SUM()` | Sum of `` across matching documents. | +| `AVG()` | `(count, sum)` pair the client divides to compute the average. | + +`groupBy` is optional. With an empty `groupBy`, the response carries a single aggregate value; with a `groupBy` of one or two fields, the response carries one entry per group. + +Aggregate queries impose extra schema requirements on the document type — `COUNT` needs `documentsCountable`, `SUM` needs `documentsSummable`, `AVG` needs `documentsAverageable` (or both base flags). Range-grouped aggregates additionally need the `range*` variants. See the [doctype-level aggregate flags](../protocol-ref/data-contract-document.md#aggregate-query-flags) for the schema annotations and the [`getDocuments` reference](../reference/dapi-endpoints-platform-endpoints.md#getdocuments) for the full `select` × `groupBy` shape table. + +`SUM` / `AVG` integer values are returned as JS strings so JavaScript clients don't lose precision on values larger than `Number.MAX_SAFE_INTEGER`. + +:::{note} +`HAVING`, `OFFSET`, `COUNT()`, `MIN`, `MAX`, and multi-projection `SELECT` are present on the wire but currently return `Unsupported`. Callers can encode them in builders ahead of server support landing, but evaluation rejects them today. +::: + ## Example query The following query combines both a where clause and query modifiers. From 1a8793b9900d8dad692c4f33aa34e2ece41fe8a4 Mon Sep 17 00:00:00 2001 From: thephez Date: Wed, 27 May 2026 10:36:10 -0400 Subject: [PATCH 3/8] docs(protocol-ref): add shielded pool concept and wire format (#150) * docs(explanations): add shielded pool concept page Introduces the Orchard-based shielded pool, its core concepts (notes, nullifiers, anchors, encrypted notes), the 5 shielded transition flows, and the 16-action-per-transition limit. Wired into the Explanations toctree. Co-Authored-By: Claude Opus 4.7 (1M context) * docs(protocol-ref): add shielded pool wire format and signing New protocol-ref/shielded-pool.md documents the five shielded state transition types (Shield, Shielded Transfer, Unshield, Shield from Asset Lock, Shielded Withdrawal) along with the shared Orchard bundle primitives, the per-action serialized form, and the Orchard / address witness / asset-lock signature layers that authorize them. Wires the discriminator rows 15-19 in state-transition.md to the new page, adds a Signing Shielded Transitions subsection, and links from the signing-methods table. Fixes the stale max_shielded_transition_actions constant (was 100; correct value is 16) and adds the max_asset_lock_transaction_inputs limit to protocol-constants.md. Co-Authored-By: Claude Opus 4.7 (1M context) * docs: document toctree requirement and sync sidebar for shielded pool Adds an "Adding a new doc page" section to CLAUDE.md explaining that new pages must be wired into a Sphinx toctree in docs/index.md and that scripts/sync_sidebar.py needs to run afterwards. Syncs the sidebar so the new explanations/shielded-pool.md and protocol-ref/shielded-pool.md pages appear in the rendered nav. Co-Authored-By: Claude Opus 4.7 (1M context) --------- Co-authored-by: Claude Opus 4.7 (1M context) --- CLAUDE.md | 8 + _templates/sidebar-main.html | 10 ++ docs/explanations/shielded-pool.md | 73 ++++++++ docs/index.md | 2 + docs/protocol-ref/protocol-constants.md | 3 +- docs/protocol-ref/shielded-pool.md | 213 ++++++++++++++++++++++++ docs/protocol-ref/state-transition.md | 21 ++- 7 files changed, 323 insertions(+), 7 deletions(-) create mode 100644 docs/explanations/shielded-pool.md create mode 100644 docs/protocol-ref/shielded-pool.md diff --git a/CLAUDE.md b/CLAUDE.md index 8cc4a1371..9760866d1 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -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/
    /`, 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//packages/dapi-grpc/protos` — check the proto when adding or modifying entries. diff --git a/_templates/sidebar-main.html b/_templates/sidebar-main.html index 56fa79b72..c973bc7b4 100644 --- a/_templates/sidebar-main.html +++ b/_templates/sidebar-main.html @@ -335,6 +335,11 @@ DashPay
  • +
  • + + Shielded Pool + +
  • Fees @@ -484,6 +489,11 @@ Platform Address System
  • +
  • + + Shielded Pool + +
  • Protocol Constants diff --git a/docs/explanations/shielded-pool.md b/docs/explanations/shielded-pool.md new file mode 100644 index 000000000..489ec95dc --- /dev/null +++ b/docs/explanations/shielded-pool.md @@ -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. diff --git a/docs/index.md b/docs/index.md index e89b33b43..e42d5fdf5 100644 --- a/docs/index.md +++ b/docs/index.md @@ -131,6 +131,7 @@ explanations/dpns explanations/drive explanations/platform-consensus explanations/dashpay +explanations/shielded-pool explanations/fees explanations/tokens explanations/nft @@ -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 ``` diff --git a/docs/protocol-ref/protocol-constants.md b/docs/protocol-ref/protocol-constants.md index c06962160..a5a620808 100644 --- a/docs/protocol-ref/protocol-constants.md +++ b/docs/protocol-ref/protocol-constants.md @@ -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) | @@ -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 diff --git a/docs/protocol-ref/shielded-pool.md b/docs/protocol-ref/shielded-pool.md new file mode 100644 index 000000000..6279b9de5 --- /dev/null +++ b/docs/protocol-ref/shielded-pool.md @@ -0,0 +1,213 @@ +```{eval-rst} +.. _protocol-ref-shielded-pool: +``` + +# Shielded Pool + +:::{attention} +Shielded state transitions were [enabled in Protocol Version 12](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-platform-version/src/version/feature_initial_protocol_versions.rs#L4). They use the [Orchard](https://zips.z.cash/protocol/protocol.pdf) shielded protocol to move credits into, within, and out of a pool that hides amounts, senders, and recipients. + +For the conceptual overview of how the pool works and when to use it, see [Shielded Pool](../explanations/shielded-pool.md). +::: + +## Overview + +The shielded pool is implemented through five state transition types that share a common Orchard bundle structure: + +| Type | Name | Description | +| --- | --- | --- | +| 15 | [Shield](#shield) | Move credits from Platform addresses into the shielded pool | +| 16 | [Shielded Transfer](#shielded-transfer) | Move credits within the pool (no transparent surface) | +| 17 | [Unshield](#unshield) | Move credits from the pool to a Platform address | +| 18 | [Shield from Asset Lock](#shield-from-asset-lock) | Move credits from an L1 asset lock directly into the pool | +| 19 | [Shielded Withdrawal](#shielded-withdrawal) | Move credits from the pool back to Dash Core (L1) | + +All five transitions share a common Orchard bundle (anchor, actions, proof, binding signature). Transitions that touch the transparent side (Shield, Unshield, Shield from Asset Lock, Shielded Withdrawal) layer the transparent fields on top of that bundle. Shielded Transfer has no transparent surface beyond the bundle itself. + +## Common Components + +### Orchard Bundle + +Every shielded transition includes an Orchard bundle proving that a set of note spends and outputs is internally consistent. The bundle consists of: + +| Field | Type | Size | Description | +| --- | --- | --- | --- | +| actions | array | Varies | Orchard [actions](#actions) (spend-output pairs). Limited to [`max_shielded_transition_actions`](protocol-constants.md) per transition. | +| anchor | array of bytes | 32 bytes | Sinsemilla root of the note commitment tree at bundle creation time. Must match an [anchor](#anchors) the platform has previously recorded | +| proof | array of bytes | Varies | Halo 2 zero-knowledge proof that the actions are valid | +| bindingSignature | array of bytes | 64 bytes | RedPallas signature binding the bundle's actions to its net value balance | + +See the [Orchard bundle primitives in rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/shielded/mod.rs). + +### Actions + +Each Orchard action structurally contains one spend and one output. The spend consumes a previously created note (revealing its nullifier), while the output creates a new note (publishing its commitment). Although paired in the same struct, observers cannot link which prior note was spent or what value the new note holds — the zero-knowledge proof ensures privacy. + +Each action publishes: + +| Field | Type | Size | Description | +| --- | --- | --- | --- | +| nullifier | array of bytes | 32 bytes | Unique tag derived from the spent note. Used to prevent double-spending | +| rk | array of bytes | 32 bytes | Randomized verification key for the action's spend authorization signature | +| cmx | array of bytes | 32 bytes | Extracted note commitment for the new note | +| encryptedNote | array of bytes | 216 bytes | Encrypted note payload — 32-byte ephemeral public key + 104-byte note ciphertext + 80-byte out-of-band ciphertext | +| cvNet | array of bytes | 32 bytes | Net value commitment (Pedersen commitment to the action's value contribution) | +| spendAuthSig | array of bytes | 64 bytes | Per-action spend authorization signature — see [Shielded Transition Signing](#shielded-transition-signing) | + +Permanent storage cost per action is [312 bytes](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/shielded/mod.rs#L13-L16) (280 bytes in the note commitment tree + 32 bytes in the nullifier tree). + +See the [serialized action implementation in rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/shielded/mod.rs). + +### Anchors + +An **anchor** is the Sinsemilla root of the note commitment tree at the time the bundle was constructed. Each shielded transition specifies the anchor it was built against; the platform validates that the anchor was previously published. Clients fetch anchors using [`getShieldedAnchors`](../reference/dapi-endpoints-platform-endpoints.md#getshieldedanchors) or [`getMostRecentShieldedAnchor`](../reference/dapi-endpoints-platform-endpoints.md#getmostrecentshieldedanchor). + +### Platform Sighash + +Transitions with transparent fields (Unshield, Shielded Withdrawal, etc.) bind those fields to the Orchard signatures via a platform sighash computed as: + +``` +SHA-256(SIGHASH_DOMAIN || bundle_commitment || extra_data) +``` + +This prevents replay attacks where an attacker substitutes transparent fields while reusing a valid Orchard bundle. See the [platform sighash implementation in rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/shielded/mod.rs#L20-L40). + +## Shielded State Transition Details + +### Shield + +Move credits from one or more [Platform addresses](address-system.md#platform-address) into the shielded pool. The total contributed across address inputs must cover the value being shielded plus the transition fee; excess credits remain in the source addresses. + +| Field | Type | Size | Description | +| --- | --- | --- | --- | +| inputs | map | Varies | Map of source [Platform addresses](address-system.md#platform-address) to (`AddressNonce`, max contribution in credits) pairs | +| actions | array | Varies | Orchard [actions](#actions) (output-only — Shield creates new notes without consuming prior ones) | +| amount | unsigned integer | 64 bits | Credits entering the shielded pool | +| anchor | array of bytes | 32 bytes | [Anchor](#anchors) | +| proof | array of bytes | Varies | Halo 2 proof | +| bindingSignature | array of bytes | 64 bytes | RedPallas binding signature | +| feeStrategy | array | Varies | [Fee deduction strategy](address-system.md#fee-strategy) for address inputs | +| userFeeIncrease | unsigned integer | 16 bits | Extra fee to prioritize processing if the mempool is full | +| inputWitnesses | array | Varies | [Address witnesses](address-system.md#address-witness) for each input | + +:::{note} +Maximum actions per transition: [`max_shielded_transition_actions`](protocol-constants.md). Address witness signatures are excluded from the signable bytes used by the platform sighash. +::: + +See the [implementation in rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/state_transition/state_transitions/shielded/shield_transition/). + +### Shielded Transfer + +Move credits within the pool between notes. There is no transparent surface — to an outside observer, only the Orchard bundle is visible. + +| Field | Type | Size | Description | +| --- | --- | --- | --- | +| actions | array | Varies | Orchard [actions](#actions) | +| valueBalance | unsigned integer | 64 bits | Net value balance — the fee amount extracted from the shielded pool for this transition | +| anchor | array of bytes | 32 bytes | [Anchor](#anchors) | +| proof | array of bytes | Varies | Halo 2 proof | +| bindingSignature | array of bytes | 64 bytes | RedPallas binding signature | + +:::{note} +Maximum actions per transition: [`max_shielded_transition_actions`](protocol-constants.md). +::: + +See the [implementation in rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/state_transition/state_transitions/shielded/shielded_transfer_transition/). + +### Unshield + +Move credits from the pool to a [Platform address](address-system.md#platform-address) the sender designates. The unshielded amount becomes spendable through normal address-based transitions. + +| Field | Type | Size | Description | +| --- | --- | --- | --- | +| outputAddress | object | Varies | Destination [Platform address](address-system.md#platform-address) | +| actions | array | Varies | Orchard [actions](#actions) (spends consume shielded notes) | +| unshieldingAmount | unsigned integer | 64 bits | Total credits leaving the pool (recipient amount + fee) | +| anchor | array of bytes | 32 bytes | [Anchor](#anchors) | +| proof | array of bytes | Varies | Halo 2 proof | +| bindingSignature | array of bytes | 64 bytes | RedPallas binding signature | + +:::{note} +The `outputAddress` is bound to the Orchard bundle through the [platform sighash](#platform-sighash) to prevent substitution attacks. Maximum actions per transition: [`max_shielded_transition_actions`](protocol-constants.md). +::: + +See the [implementation in rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/state_transition/state_transitions/shielded/unshield_transition/). + +### Shield from Asset Lock + +Move credits from a Dash Core (L1) asset-lock transaction directly into the shielded pool, without first funding a Platform address. + +| Field | Type | Size | Description | +| --- | --- | --- | --- | +| assetLockProof | object | Varies | [Asset lock proof](identity.md#asset-lock) (InstantSend or ChainLock) authorizing the funds | +| actions | array | Varies | Orchard [actions](#actions) | +| valueBalance | unsigned integer | 64 bits | Credits entering the shielded pool from the asset lock | +| anchor | array of bytes | 32 bytes | [Anchor](#anchors) | +| proof | array of bytes | Varies | Halo 2 proof | +| bindingSignature | array of bytes | 64 bytes | RedPallas binding signature | +| signature | array of bytes | 65 bytes | ECDSA signature over the signable bytes proving control of the asset-locked output | + +:::{note} +`valueBalance` must be greater than zero and at most `i64::MAX`. The ECDSA signature is excluded from the signable bytes used by the platform sighash. Maximum actions per transition: [`max_shielded_transition_actions`](protocol-constants.md). +::: + +See the [implementation in rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/state_transition/state_transitions/shielded/shield_from_asset_lock_transition/). + +### Shielded Withdrawal + +Move credits from the pool back to Dash Core (L1). The funds leave Platform entirely rather than landing in a Platform address. + +| Field | Type | Size | Description | +| --- | --- | --- | --- | +| actions | array | Varies | Orchard [actions](#actions) (spends + change outputs) | +| unshieldingAmount | unsigned integer | 64 bits | Total credits leaving the pool (recipient amount + fee) | +| anchor | array of bytes | 32 bytes | [Anchor](#anchors) | +| proof | array of bytes | Varies | Halo 2 proof | +| bindingSignature | array of bytes | 64 bytes | RedPallas binding signature | +| coreFeePerByte | unsigned integer | 32 bits | Core transaction fee rate for the L1 withdrawal transaction | +| pooling | unsigned integer | 8 bits | Withdrawal pooling strategy (see [Identity Credit Withdrawal](identity.md#identity-credit-withdrawal)) | +| outputScript | array of bytes | Varies | Core script of the L1 address receiving the withdrawn funds | + +:::{note} +Transparent fields (`coreFeePerByte`, `pooling`, `outputScript`) are bound to the Orchard bundle through the [platform sighash](#platform-sighash). Maximum actions per transition: [`max_shielded_transition_actions`](protocol-constants.md). +::: + +See the [implementation in rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/state_transition/state_transitions/shielded/shielded_withdrawal_transition/). + +## Shielded Transition Signing + +Shielded transitions are not signed by an identity public key. The 65-byte `signature` and the `signaturePublicKeyId` fields listed in the [common fields](state-transition.md#common-fields) for identity-signed transitions do not appear on Unshield, Shielded Transfer, or Shielded Withdrawal. Authorization is instead carried by cryptographic primitives attached to the Orchard bundle and, where applicable, to the transparent side of the transition. + +### Orchard bundle signatures + +Every shielded transition includes: + +- **Per-action spend authorization signatures** (`spendAuthSig` on each [action](#actions)). Each is a 64-byte RedPallas signature, produced by the holder of the spent note over the randomized verification key `rk`. The proof binds `rk` to the original spending key, so verifying the signature against `rk` proves the spender is authorized. +- **Binding signature** (`bindingSignature` on the transition). A 64-byte RedPallas signature over the sum of the action value commitments, proving that the actions' net value balance matches the transition's declared value balance. + +### Platform sighash + +Transitions that include transparent fields (Shield, Unshield, Shield from Asset Lock, Shielded Withdrawal) bind those fields to the Orchard bundle through the [platform sighash](#platform-sighash). Any modification to the transparent fields invalidates the Orchard signatures, preventing replay attacks that substitute transparent fields while reusing a valid bundle. + +### Transparent signatures (Shield, Shield from Asset Lock) + +Two shielded transitions also carry transparent signatures over the transparent side of the transition: + +- **Shield** includes an array of [address witnesses](address-system.md#address-witness) (`inputWitnesses`) — one per address input. Each witness proves control of its corresponding Platform address. Address witness signatures are excluded from the bytes that feed the platform sighash (they sign the platform sighash output, not vice-versa). +- **Shield from Asset Lock** includes a 65-byte ECDSA `signature` proving control of the L1 asset-locked output, in the same form used by [Identity Create](identity.md#identity-create). The signature is excluded from the bytes that feed the platform sighash. + +Shielded Transfer, Unshield, and Shielded Withdrawal have no transparent signatures; the Orchard bundle signatures plus the platform sighash provide full authorization. + +## Querying shielded state + +DAPI exposes a set of read-only endpoints for clients that need to fetch anchors, scan encrypted notes, verify nullifier status, or sync incremental nullifier updates. See the [DAPI Platform endpoints reference](../reference/dapi-endpoints-platform-endpoints.md) for request and response shapes: + +- [`getShieldedPoolState`](../reference/dapi-endpoints-platform-endpoints.md#getshieldedpoolstate) +- [`getShieldedAnchors`](../reference/dapi-endpoints-platform-endpoints.md#getshieldedanchors) +- [`getMostRecentShieldedAnchor`](../reference/dapi-endpoints-platform-endpoints.md#getmostrecentshieldedanchor) +- [`getShieldedEncryptedNotes`](../reference/dapi-endpoints-platform-endpoints.md#getshieldedencryptednotes) +- [`getShieldedNullifiers`](../reference/dapi-endpoints-platform-endpoints.md#getshieldednullifiers) +- [`getNullifiersTrunkState`](../reference/dapi-endpoints-platform-endpoints.md#getnullifierstrunkstate) +- [`getNullifiersBranchState`](../reference/dapi-endpoints-platform-endpoints.md#getnullifiersbranchstate) +- [`getRecentNullifierChanges`](../reference/dapi-endpoints-platform-endpoints.md#getrecentnullifierchanges) +- [`getRecentCompactedNullifierChanges`](../reference/dapi-endpoints-platform-endpoints.md#getrecentcompactednullifierchanges) diff --git a/docs/protocol-ref/state-transition.md b/docs/protocol-ref/state-transition.md index 9f310528d..e55d1c76e 100644 --- a/docs/protocol-ref/state-transition.md +++ b/docs/protocol-ref/state-transition.md @@ -26,7 +26,7 @@ The list of common fields used by multiple state transitions is defined in [rs-d | Field | Type | Size | Description | | --------------- | -------------- | ---- | ----------- | | $version | unsigned integer | 16 bits | The state transition format version (FeatureVersion). Currently `0` for most transitions, `1` for Batch. This is not the global platform protocol version, which is negotiated separately. | -| type | unsigned integer | 8 bits | State transition type (defined in [rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/state_transition/state_transition_types.rs#L21)):
    `0` - [data contract create](../protocol-ref/data-contract.md#data-contract-create)
    `1` - [batch](#batch)
    `2` - [identity create](../protocol-ref/identity.md#identity-create)
    `3` - [identity topup](identity.md#identity-topup)
    `4` - [data contract update](data-contract.md#data-contract-update)
    `5` - [identity update](identity.md#identity-update)
    `6` - [identity credit withdrawal](identity.md#identity-credit-withdrawal)
    `7` - [identity credit transfer](identity.md#identity-credit-transfer)
    `8` - [masternode vote](#masternode-vote)
    `9` - [identity credit transfer to addresses](address-system.md#identity-credit-transfer-to-addresses)
    `10` - [identity create from addresses](address-system.md#identity-create-from-addresses)
    `11` - [identity topup from addresses](address-system.md#identity-topup-from-addresses)
    `12` - [address funds transfer](address-system.md#address-funds-transfer)
    `13` - [address funding from asset lock](address-system.md#address-funding-from-asset-lock)
    `14` - [address credit withdrawal](address-system.md#address-credit-withdrawal)
    `15` - shield
    `16` - shielded transfer
    `17` - unshield
    `18` - shield from asset lock
    `19` - shielded withdrawal | +| type | unsigned integer | 8 bits | State transition type (defined in [rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/state_transition/state_transition_types.rs#L21)):
    `0` - [data contract create](../protocol-ref/data-contract.md#data-contract-create)
    `1` - [batch](#batch)
    `2` - [identity create](../protocol-ref/identity.md#identity-create)
    `3` - [identity topup](identity.md#identity-topup)
    `4` - [data contract update](data-contract.md#data-contract-update)
    `5` - [identity update](identity.md#identity-update)
    `6` - [identity credit withdrawal](identity.md#identity-credit-withdrawal)
    `7` - [identity credit transfer](identity.md#identity-credit-transfer)
    `8` - [masternode vote](#masternode-vote)
    `9` - [identity credit transfer to addresses](address-system.md#identity-credit-transfer-to-addresses)
    `10` - [identity create from addresses](address-system.md#identity-create-from-addresses)
    `11` - [identity topup from addresses](address-system.md#identity-topup-from-addresses)
    `12` - [address funds transfer](address-system.md#address-funds-transfer)
    `13` - [address funding from asset lock](address-system.md#address-funding-from-asset-lock)
    `14` - [address credit withdrawal](address-system.md#address-credit-withdrawal)
    `15` - [shield](shielded-pool.md#shield)
    `16` - [shielded transfer](shielded-pool.md#shielded-transfer)
    `17` - [unshield](shielded-pool.md#unshield)
    `18` - [shield from asset lock](shielded-pool.md#shield-from-asset-lock)
    `19` - [shielded withdrawal](shielded-pool.md#shielded-withdrawal) | | userFeeIncrease | unsigned integer | 16 bits | Extra fee to prioritize processing if the mempool is full. Typically set to zero. | | signature | array of bytes | 65 bytes |Signature of state transition data | @@ -142,14 +142,13 @@ transition type: | Signing Method | State Transitions | | -------------- | ----------------- | | [Identity](#signing-with-identity) | Batch, Contract create, Contract update, Identity update, Identity credit transfer, Identity credit transfer to addresses, Identity credit withdrawal, Masternode vote | -| [Asset lock](#signing-with-asset-lock) | Identity create, Identity topup, Address funding from asset lock* | -| [Address witness](#signing-with-address-witness) | Identity create from addresses, Identity topup from addresses, Address funds transfer, Address credit withdrawal, Address funding from asset lock* | +| [Asset lock](#signing-with-asset-lock) | Identity create, Identity topup, Address funding from asset lock\*, Shield from asset lock\*\* | +| [Address witness](#signing-with-address-witness) | Identity create from addresses, Identity topup from addresses, Address funds transfer, Address credit withdrawal, Address funding from asset lock\*, Shield\*\* | +| [Shielded (Orchard)](shielded-pool.md#shielded-transition-signing) | Shield\*\*, Shielded transfer, Unshield, Shield from asset lock\*\*, Shielded withdrawal | \* Address funding from asset lock requires both an asset lock signature and address witnesses (`input_witnesses`). -:::{note} -Shield-related state transitions (types 15-19: Shield, ShieldedTransfer, Unshield, ShieldFromAssetLock, ShieldedWithdrawal) are defined in the protocol but their signing methods are not yet documented here. -::: +\*\* Shielded transitions are always authorized by Orchard bundle signatures (per-action `spendAuthSig` plus the transition-level `bindingSignature`). Shield additionally carries address witnesses for its transparent address inputs; Shield from asset lock additionally carries an asset-lock ECDSA signature. :::{note} Address-based state transitions (types 9-14) were introduced in Protocol Version 11. For detailed information on these transitions, see [Address-Based State Transitions](address-system.md). @@ -218,6 +217,12 @@ Public keys can be added to an identity by the identity create or identity updat - Use the private key that derived the public key to sign the hash. - Store the result in the public key's `signature` field. +### Signing Shielded Transitions + +Shielded transitions are not signed by an identity public key or an address private key at the transition level — they do not include `signature` or `signaturePublicKeyId` fields. Authorization is carried instead by Orchard primitives attached to each action and to the bundle as a whole. Shield additionally carries [address witnesses](#signing-with-address-witness) over its address inputs, and Shield from asset lock additionally carries an [asset-lock ECDSA signature](#signing-with-asset-lock). Both `input_witnesses` (on Shield) and `signature` (on Shield from asset lock) are omitted from the bytes that feed the platform sighash. + +See [Shielded Transition Signing](shielded-pool.md#shielded-transition-signing) for the full signing model. + ### Non-signable Fields This table shows the fields that must be excluded when creating state transition signatures. All transitions exclude the signature field. Some transitions contain other fields that must be excluded also. Click the state transition name to see the rs-dpp implementation for additional context. @@ -233,3 +238,7 @@ This table shows the fields that must be excluded when creating state transition | [Identity credit transfer](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_transfer_transition/v0/mod.rs#L49-L52) | Exclude | Exclude | N/A | N/A | | [Identity credit withdrawal](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_withdrawal_transition/v1/mod.rs#L44-L47) | Exclude | Exclude | N/A | N/A | | [Masternode vote](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/state_transition/state_transitions/identity/masternode_vote_transition/v0/mod.rs#L49-L52) | Exclude | Exclude | N/A | N/A | + +:::{note} +The table above does not cover shielded transitions, which do not carry transition-level `signature` or `signaturePublicKeyId` fields. See [Signing Shielded Transitions](#signing-shielded-transitions). +::: From d4807267f8cb9c905cc3a8b4b65e7b51113af08a Mon Sep 17 00:00:00 2001 From: thephez Date: Thu, 28 May 2026 10:34:33 -0400 Subject: [PATCH 4/8] docs: v3.1 release cleanup (state-transition dedup, deprecated DAPI removal, build-warning fixes) (#151) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs(protocol-ref): dedup state transition page and drop deprecated DAPI entries Replace the cramped one-cell type discriminator with a proper catalog table, remove the 7 type-0–8 detail sections that duplicate the canonical identity and data-contract pages, and drop the long-deprecated getIdentities and getIdentitiesByPublicKeyHashes endpoints (removed from the platform proto in v1.0.0). Co-Authored-By: Claude Opus 4.7 (1M context) * docs: minor formatting update * docs: fix broken cross-references to clean up build warnings Co-Authored-By: Claude Opus 4.7 (1M context) * docs: silence Pygments warnings on placeholder JSON blocks Convert affected fences to code-block directives with :force: so JSON highlighting is preserved without lexer errors on schema-style placeholders and JS-literal query examples. Co-Authored-By: Claude Opus 4.7 (1M context) --------- Co-authored-by: Claude Opus 4.7 (1M context) --- docs/protocol-ref/data-contract-document.md | 12 ++- docs/protocol-ref/state-transition.md | 97 +++++-------------- .../dapi-endpoints-platform-endpoints.md | 33 ------- docs/reference/dapi-endpoints.md | 4 +- docs/reference/data-contracts.md | 22 +++-- docs/reference/query-syntax.md | 45 ++++++--- docs/tutorials/example-apps/dashmint-lab.md | 2 +- 7 files changed, 79 insertions(+), 136 deletions(-) diff --git a/docs/protocol-ref/data-contract-document.md b/docs/protocol-ref/data-contract-document.md index 22d85fbcc..6aca6f486 100644 --- a/docs/protocol-ref/data-contract-document.md +++ b/docs/protocol-ref/data-contract-document.md @@ -144,7 +144,9 @@ The `indices` array consists of one or more objects that each contain: * An optional `nullSearchable` element that indicates whether the index allows searching for NULL values. If nullSearchable is false (default: true) and all properties of the index are null then no reference is added. * An optional `contested` element that determines if duplicate values are allowed for the document -```json +:::{code-block} json +:force: + "indices": [ { "name": "", @@ -171,7 +173,7 @@ The `indices` array consists of one or more objects that each contain: ], } ] -``` +::: ### Contested Indices @@ -380,7 +382,9 @@ schema](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/schema This example syntax shows the structure of a documents object that defines two documents, an index, and a required field. -```json +:::{code-block} json +:force: + { "": { "type": "object", @@ -425,7 +429,7 @@ This example syntax shows the structure of a documents object that defines two d "additionalProperties": false }, } -``` +::: ## Document Schema diff --git a/docs/protocol-ref/state-transition.md b/docs/protocol-ref/state-transition.md index e55d1c76e..e52209e7e 100644 --- a/docs/protocol-ref/state-transition.md +++ b/docs/protocol-ref/state-transition.md @@ -26,7 +26,7 @@ The list of common fields used by multiple state transitions is defined in [rs-d | Field | Type | Size | Description | | --------------- | -------------- | ---- | ----------- | | $version | unsigned integer | 16 bits | The state transition format version (FeatureVersion). Currently `0` for most transitions, `1` for Batch. This is not the global platform protocol version, which is negotiated separately. | -| type | unsigned integer | 8 bits | State transition type (defined in [rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/state_transition/state_transition_types.rs#L21)):
    `0` - [data contract create](../protocol-ref/data-contract.md#data-contract-create)
    `1` - [batch](#batch)
    `2` - [identity create](../protocol-ref/identity.md#identity-create)
    `3` - [identity topup](identity.md#identity-topup)
    `4` - [data contract update](data-contract.md#data-contract-update)
    `5` - [identity update](identity.md#identity-update)
    `6` - [identity credit withdrawal](identity.md#identity-credit-withdrawal)
    `7` - [identity credit transfer](identity.md#identity-credit-transfer)
    `8` - [masternode vote](#masternode-vote)
    `9` - [identity credit transfer to addresses](address-system.md#identity-credit-transfer-to-addresses)
    `10` - [identity create from addresses](address-system.md#identity-create-from-addresses)
    `11` - [identity topup from addresses](address-system.md#identity-topup-from-addresses)
    `12` - [address funds transfer](address-system.md#address-funds-transfer)
    `13` - [address funding from asset lock](address-system.md#address-funding-from-asset-lock)
    `14` - [address credit withdrawal](address-system.md#address-credit-withdrawal)
    `15` - [shield](shielded-pool.md#shield)
    `16` - [shielded transfer](shielded-pool.md#shielded-transfer)
    `17` - [unshield](shielded-pool.md#unshield)
    `18` - [shield from asset lock](shielded-pool.md#shield-from-asset-lock)
    `19` - [shielded withdrawal](shielded-pool.md#shielded-withdrawal) | +| type | unsigned integer | 8 bits | State transition type discriminator (defined in [rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/state_transition/state_transition_types.rs#L21)). See [State Transition Types](#state-transition-types) for the full list. | | userFeeIncrease | unsigned integer | 16 bits | Extra fee to prioritize processing if the mempool is full. Typically set to zero. | | signature | array of bytes | 65 bytes |Signature of state transition data | @@ -42,85 +42,40 @@ Additionally, all state transitions except the identity create and topup state t ## State Transition Types -Dash Platform Protocol defines the [state transition types](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/state_transition/state_transition_types.rs#L21-L43) that perform identity, contract, document, and token operations. See the subsections below for details on each state transition type. +Dash Platform Protocol defines the following [state transition types](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/state_transition/state_transition_types.rs#L21-L43). Most are documented in detail on the protocol reference page for the feature they operate on. Batch and Masternode Vote do not have a dedicated feature page; their formats are documented inline below. + +| Type | Name | Documented in | +| --- | --- | --- | +| 0 | Data Contract Create | [Data Contract Create](data-contract.md#data-contract-create) | +| 1 | Batch | [Batch](#batch) (below) | +| 2 | Identity Create | [Identity Create](identity.md#identity-create) | +| 3 | Identity TopUp | [Identity TopUp](identity.md#identity-topup) | +| 4 | Data Contract Update | [Data Contract Update](data-contract.md#data-contract-update) | +| 5 | Identity Update | [Identity Update](identity.md#identity-update) | +| 6 | Identity Credit Withdrawal | [Identity Credit Withdrawal](identity.md#identity-credit-withdrawal) | +| 7 | Identity Credit Transfer | [Identity Credit Transfer](identity.md#identity-credit-transfer) | +| 8 | Masternode Vote | [Masternode Vote](#masternode-vote) (below) | +| 9 | Identity Credit Transfer to Addresses | [Identity Credit Transfer to Addresses](address-system.md#identity-credit-transfer-to-addresses) | +| 10 | Identity Create from Addresses | [Identity Create from Addresses](address-system.md#identity-create-from-addresses) | +| 11 | Identity TopUp from Addresses | [Identity TopUp from Addresses](address-system.md#identity-top-up-from-addresses) | +| 12 | Address Funds Transfer | [Address Funds Transfer](address-system.md#address-funds-transfer) | +| 13 | Address Funding from Asset Lock | [Address Funding from Asset Lock](address-system.md#address-funding-from-asset-lock) | +| 14 | Address Credit Withdrawal | [Address Credit Withdrawal](address-system.md#address-credit-withdrawal) | +| 15 | Shield | [Shield](shielded-pool.md#shield) | +| 16 | Shielded Transfer | [Shielded Transfer](shielded-pool.md#shielded-transfer) | +| 17 | Unshield | [Unshield](shielded-pool.md#unshield) | +| 18 | Shield from Asset Lock | [Shield from Asset Lock](shielded-pool.md#shield-from-asset-lock) | +| 19 | Shielded Withdrawal | [Shielded Withdrawal](shielded-pool.md#shielded-withdrawal) | ### Batch | Field | Type | Size | Description | | ----------- | -------------- | ---- | ----------- | -| ownerId | array of bytes | 32 bytes | [Identity](../protocol-ref/identity.md) submitting the document(s) | +| ownerId | array of bytes | 32 bytes | [Identity](../protocol-ref/identity.md) submitting the document(s) or token action(s) | | transitions | array of transition objects | Varies | A batch of [document](../protocol-ref/document.md#document-overview) or token actions (currently limited to [1 object per batch](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-platform-version/src/version/system_limits/v1.rs#L7)) | More detailed information about the `transitions` array can be found in the [document section](../protocol-ref/document.md). See the implementation in [rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v1/mod.rs#L31-L39). -### Data Contract Create - -| Field | Type | Size | Description | -| --------------- | -------------- | ---- | ----------- | -| dataContract | [data contract object](../protocol-ref/data-contract.md#data-contract-object) | Varies | Object containing valid [data contract](../protocol-ref/data-contract.md) details | -| identityNonce | unsigned integer | 64 bits | Identity nonce for this transition to prevent replay attacks | - -More detailed information about the `dataContract` object can be found in the [data contract section](../protocol-ref/data-contract.md). - -### Data Contract Update - -| Field | Type | Size | Description | -| --------------- | -------------- | ---- | ----------- | -| dataContract | [data contract object](../protocol-ref/data-contract.md#data-contract-object) | Varies | Object containing valid [data contract](../protocol-ref/data-contract.md) details | -| identityContractNonce | unsigned integer | 64 bits | Identity contract nonce for replay protection | - -More detailed information about the `dataContract` object can be found in the [data contract section](../protocol-ref/data-contract.md). - -### Identity Create - -| Field | Type | Size | Description | -| --------------- | -------------- | ---- | ----------- | -| assetLockProof | array of bytes | 36 bytes | Lock [outpoint](https://docs.dash.org/en/stable/docs/core/resources/glossary.html#outpoint) from the layer 1 locking transaction (36 bytes) | -| publicKeys | array of keys | Varies | [Public key(s)](../protocol-ref/identity.md#identity-publickeys) associated with the identity (maximum number of keys: `6`) | - -More detailed information about the `publicKeys` object can be found in the [identity section](../protocol-ref/identity.md). - -### Identity TopUp - -| Field | Type | Size | Description | -| --------------- | -------------- | ---- | ----------- | -| assetLockProof | array of bytes | 36 bytes | Lock [outpoint](https://docs.dash.org/en/stable/docs/core/resources/glossary.html#outpoint) from the layer 1 locking transaction (36 bytes) | -| identityId | array of bytes | 32 bytes | An [Identity ID](../protocol-ref/identity.md#identity-id) for the identity receiving the topup (can be any identity) (32 bytes) | - -### Identity Update - -| Field | Type | Size | Description | -| --------------- | -------------- | ---- | ----------- | -| identityId | array of bytes | 32 bytes | The [Identity ID](../protocol-ref/identity.md#identity-id) for the identity being updated | -| revision | unsigned integer | 64 bits | Identity update revision. Used for optimistic concurrency control. Incremented by one with each new update so that the update will fail if the underlying data is modified between reading and writing. | -| nonce | unsigned integer | 64 bits | Identity nonce for this transition to prevent replay attacks | -| addPublicKeys | array of public keys | Varies | (Optional) Array of up to 6 new public keys to add to the identity. Required if adding keys. | -| disablePublicKeys | array of integers | Varies | (Optional) Array of up to 10 existing identity public key ID(s) to disable for the identity. Required if disabling keys. | - -### Identity Credit Transfer - -| Field | Type | Size | Description | -| --------------- | -------------- | ---- | ----------- | -| identityId | array of bytes | 32 bytes | An [Identity ID](../protocol-ref/identity.md#identity-id) for the identity sending the credits | -| recipientId | array of bytes | 32 bytes | An [Identity ID](../protocol-ref/identity.md#identity-id) for the identity receiving the credits | -| amount | unsigned integer | 64 bits | Number of credits being transferred | -| nonce | unsigned integer | 64 bits | Identity nonce for this transition to prevent replay attacks | - -See the implementation in [rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_transfer_transition/v0/mod.rs#L42-L53). - -### Identity Credit Withdrawal - -| Field | Type | Size | Description | -| --------------- | -------------- | ---- | ----------- | -| identityId | array of bytes | 32 bytes | An [Identity ID](../protocol-ref/identity.md#identity-id) for the identity sending the credits | -| amount | unsigned integer | 64 bits | Number of credits being transferred | -| coreFeePerByte | unsigned integer | 32 bits | | -| pooling | unsigned integer | 8 bits | 0 = Never, 1 = If Available, 2 = Standard | -| outputScript | script | Varies | If None, the withdrawal is sent to the address set by Core | -| nonce | unsigned integer | 64 bits | Identity nonce for this transition to prevent replay attacks | - -See the implementation in [rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_withdrawal_transition/v1/mod.rs#L35-L48). - ### Masternode Vote | Field | Type | Size | Description | diff --git a/docs/reference/dapi-endpoints-platform-endpoints.md b/docs/reference/dapi-endpoints-platform-endpoints.md index 9ec4003da..d0a985791 100644 --- a/docs/reference/dapi-endpoints-platform-endpoints.md +++ b/docs/reference/dapi-endpoints-platform-endpoints.md @@ -4627,39 +4627,6 @@ Returns compacted nullifier additions from a specified block height. Compacted c | `start_block_height` | String (uint64) | Yes | Block height to start from (as a string due to uint64 size) | | `prove` | Boolean | No | Set to `true` to receive a proof that contains the requested changes | -## Deprecated Endpoints - -The following endpoints were recently deprecated. See the [previous version of documentation](https://docs.dash.org/projects/platform/en/2.0.0/docs/reference/dapi-endpoints-platform-endpoints.html) for additional information on these endpoints. - -### getIdentities - -:::{attention} -Deprecated in Dash Platform v1.0.0 -::: - -**Returns**: [Identity](../explanations/identity.md) information for the requested identities - -**Parameters**: - -| Name | Type | Required | Description | -| ------- | ------- | -------- | ------------ | -| `ids` | Array | Yes | An array of identity IDs -| `prove` | Boolean | No | Set to `true` to receive a proof that contains the requested identity - -### getIdentitiesByPublicKeyHashes - -:::{attention} -Deprecated in Dash Platform v1.0.0 -::: - -**Returns**: An array of [identities](../explanations/identity.md) associated with the provided public key hashes -**Parameters**: - -| Name | Type | Required | Description | -| ------------------- | ------- | -------- | ----------------------------------------------------------------------- | -| `public_key_hashes` | Bytes | Yes | Public key hashes (sha256-ripemd160) of identity public keys | -| `prove` | Boolean | No | Set to `true` to receive a proof that contains the requested identities | - ## Code Reference Implementation details related to the information on this page can be found in: diff --git a/docs/reference/dapi-endpoints.md b/docs/reference/dapi-endpoints.md index 9ea2f26d2..5e1e87c41 100644 --- a/docs/reference/dapi-endpoints.md +++ b/docs/reference/dapi-endpoints.md @@ -43,7 +43,7 @@ without introducing issues for endpoint consumers. | [`getIdentity`](../reference/dapi-endpoints-platform-endpoints.md#getidentity) | Returns the requested identity | | [`getIdentityBalance`](../reference/dapi-endpoints-platform-endpoints.md#getidentitybalance) | Returns the requested identity's balance | | [`getIdentityBalanceAndRevision`](../reference/dapi-endpoints-platform-endpoints.md#getidentitybalanceandrevision) | Returns the requested identity's balance and revision | -| [`getIdentityByNonUniquePublicKeyHash`](../reference/dapi-endpoints-platform-endpoints.md#getidentitybynonuniquepublickeyhash) | **Added in Dash Platform v2.0.0**
    Returns one or more identities associated with a public key hash, including for non-unique masternode keys. | +| [`getIdentityByNonUniquePublicKeyHash`](../reference/dapi-endpoints-platform-endpoints.md#getidentitybynonuniquepublickeyhash) | *Added in Dash Platform v2.0.0*
    Returns one or more identities associated with a public key hash, including for non-unique masternode keys. | | [`getIdentityByPublicKeyHash`](../reference/dapi-endpoints-platform-endpoints.md#getidentitybypublickeyhash) | Returns the identity associated with the provided public key hash | | [`getIdentityContractNonce`](../reference/dapi-endpoints-platform-endpoints.md#getidentitycontractnonce) | Returns the identity contract nonce | | [`getIdentityKeys`](../reference/dapi-endpoints-platform-endpoints.md#getidentitykeys) | Returns the requested identity keys | @@ -80,7 +80,7 @@ Security groups provide a way to distribute token configuration and update autho | [`getEvonodesProposedEpochBlocksByIds`](../reference/dapi-endpoints-platform-endpoints.md#getevonodesproposedepochblocksbyids) | *Added in Dash Platform v1.3.0*
    Retrieves the number of blocks proposed by the specified evonodes in a certain epoch, based on their IDs | | [`getEvonodesProposedEpochBlocksByRange`](../reference/dapi-endpoints-platform-endpoints.md#getevonodesproposedepochblocksbyrange) | *Added in Dash Platform v1.3.0*
    Retrieves the number of blocks proposed by evonodes for a specified epoch | | [`getEpochsInfo`](../reference/dapi-endpoints-platform-endpoints.md#getepochsinfo) | Returns information about the requested epoch(s) | -| [`getFinalizedEpochInfos`](../reference/dapi-endpoints-platform-endpoints.md#getfinalizedepochinfos) | **Added in Dash Platform v2.0.0**
    Retrieves finalized epoch information within a specified index range | +| [`getFinalizedEpochInfos`](../reference/dapi-endpoints-platform-endpoints.md#getfinalizedepochinfos) | *Added in Dash Platform v2.0.0*
    Retrieves finalized epoch information within a specified index range | | [`getPathElements`](../reference/dapi-endpoints-platform-endpoints.md#getpathelements) | *Added in Dash Platform v1.0.0*
    Returns elements for a specified path in the Platform | | [`getPrefundedSpecializedBalance`](../reference/dapi-endpoints-platform-endpoints.md#getprefundedspecializedbalance) | *Added in Dash Platform v1.0.0*
    Returns the pre-funded specialized balance for a specific identity | | [`getProtocolVersionUpgradeState`](../reference/dapi-endpoints-platform-endpoints.md#getprotocolversionupgradestate) | Returns the number of votes cast for each protocol version | diff --git a/docs/reference/data-contracts.md b/docs/reference/data-contracts.md index a96c6af26..5f38d1c62 100644 --- a/docs/reference/data-contracts.md +++ b/docs/reference/data-contracts.md @@ -249,14 +249,16 @@ The `indices` array consists of one or more objects that each contain: * An optional `nullSearchable` element that indicates whether the index allows searching for NULL values. If nullSearchable is false (default: true) and all properties of the index are null then no reference is added. * An optional `contested` element that determines if duplicate values are allowed for the document -```json -"indices": [ +:::{code-block} json +:force: + +"indices": [ { "name": "", "properties": [ { "": "" }, { "": "" } - ], + ], "unique": true|false, "nullSearchable": true|false, "contested": { @@ -273,10 +275,10 @@ The `indices` array consists of one or more objects that each contain: "name": "", "properties": [ { "": "" }, - ], - } + ], + } ] -``` +::: #### Contested indices @@ -343,10 +345,12 @@ The following example (excerpt from the DPNS contract's `preorder` document) cre This example syntax shows the structure of a document object including all optional properties. -:::{dropdown} Document schema +::::{dropdown} Document schema :open: -```json +:::{code-block} json +:force: + { "": { "documentsKeepHistory": true|false, @@ -411,8 +415,8 @@ This example syntax shows the structure of a document object including all optio "additionalProperties": false }, } -``` ::: +:::: ## General Constraints diff --git a/docs/reference/query-syntax.md b/docs/reference/query-syntax.md index 4bef41722..c2859d12b 100644 --- a/docs/reference/query-syntax.md +++ b/docs/reference/query-syntax.md @@ -12,14 +12,17 @@ Generally queries will consist of a `where` clause plus optional [modifiers](#qu The Where clause is an optional array of conditions. If omitted or empty, all documents of the queried type are returned (subject to `limit`). For some operators, `value` will be an array. All fields referenced in a query's where clause must be defined in the same index. This includes system timestamp fields (e.g., `$createdAt`, `$updatedAt`, `$transferredAt`, and their block-height variants such as `$createdAtBlockHeight` and `$createdAtCoreBlockHeight`). See the following general syntax example: -```json Syntax +:::{code-block} json +:force: +:caption: Syntax + { where: [ [, , ], [, , [, ]] - ] + ] } -``` +::: ### Fields @@ -78,19 +81,23 @@ Valid fields consist of the indices defined for the document being queried. For ### Operator Examples -::::{tab-set} -:::{tab-item} Range -```json +:::::{tab-set} +::::{tab-item} Range +:::{code-block} json +:force: + { where: [ ["nameHash", "<", "56116861626961756e6176657a382e64617368"], ], } -``` ::: +:::: + +::::{tab-item} Between +:::{code-block} json +:force: -:::{tab-item} Between -```json { where: [ ["normalizedParentDomainName", "==", "dash"], @@ -101,11 +108,14 @@ Valid fields consist of the indices defined for the document being queried. For ["normalizedLabel", "asc"], ] } -``` ::: +:::: + +::::{tab-item} in +:::{code-block} json +:force: +:caption: in -:::{tab-item} in -```json in { where: [ ["normalizedParentDomainName", "==", "dash"], @@ -113,11 +123,14 @@ Valid fields consist of the indices defined for the document being queried. For ["normalizedLabel", "in", ["alice", "bob"]], ] } -``` ::: +:::: + +::::{tab-item} startsWith +:::{code-block} json +:force: +:caption: startsWith -:::{tab-item} startsWith -```json startsWith { where: [ ["normalizedParentDomainName", "==", "dash"], @@ -128,9 +141,9 @@ Valid fields consist of the indices defined for the document being queried. For ["normalizedLabel", "asc"], ] } -``` ::: :::: +::::: ## Query Modifiers diff --git a/docs/tutorials/example-apps/dashmint-lab.md b/docs/tutorials/example-apps/dashmint-lab.md index 226ffd1ea..60950caf8 100644 --- a/docs/tutorials/example-apps/dashmint-lab.md +++ b/docs/tutorials/example-apps/dashmint-lab.md @@ -660,7 +660,7 @@ export async function burnCard({ ### What makes this an NFT contract -The card data contract defines one document type (`card`) with four fields and three indices. Three top-level flags turn it into an NFT contract: `transferable: 1` lets owners send cards to other identities, `tradeMode: 1` enables the built-in price/purchase flow, and `creationRestrictionMode: 1` controls who can mint. See the [NFT explanation](../../explanations/nft.md#explanations-dash-nfts) for what each flag does, and the [NFT tab in Register a Data Contract](../contracts-and-documents/register-a-data-contract.md) for the schema in JSON form. +The card data contract defines one document type (`card`) with four fields and three indices. Three top-level flags turn it into an NFT contract: `transferable: 1` lets owners send cards to other identities, `tradeMode: 1` enables the built-in price/purchase flow, and `creationRestrictionMode: 1` controls who can mint. See the {ref}`NFT explanation ` for what each flag does, and the [NFT tab in Register a Data Contract](../contracts-and-documents/register-a-data-contract.md) for the schema in JSON form. ### How the app registers or reuses the contract From bb51758c966bce3aed1db5e58981514447cc9502 Mon Sep 17 00:00:00 2001 From: thephez Date: Wed, 17 Jun 2026 11:55:21 -0400 Subject: [PATCH 5/8] docs(tutorials): sync to Evo SDK 4.0.0-rc.2 and document token-burn scarcity (#152) * docs(tutorials): sync with tutorial repo -Bump to Evo SDK v4.0-rc.2 (3.1 was renamed 4.0) and Node 22. -Add the DashMint token-cost flow: a fixed-supply token configuration burned on card create, with creationRestrictionMode opened to anyone who can pay the token cost. - Add note update revision checking, raise the withdrawal amount to the protocol minimum, and drop the obsolete note message maxLength. * docs(tutorials): document DashMint token-burn scarcity model Add a token flow section and Transfer DashMint tokens walkthrough to DashMint Lab, register both blocks in the sync map, and align the intro, TL;DR, and contract-schema prose with token-gated minting. For Dashnote, restructure the update-note steps, note the expectedRevision guard, fix the message maxLength description, and bump the Node prerequisite to 22. Co-Authored-By: Claude Opus 4.8 (1M context) --------- Co-authored-by: Claude Opus 4.8 (1M context) --- _static/dashmint-lite.html | 16 +- _static/dashnote-lite.html | 2 +- _static/dashproof-lite.html | 2 +- docs/tutorials/connecting-to-testnet.md | 2 +- docs/tutorials/example-apps/dashmint-lab.md | 302 ++++++++++++++++-- docs/tutorials/example-apps/dashnote.md | 34 +- .../withdraw-an-identity-balance.md | 2 +- docs/tutorials/introduction.md | 2 +- docs/tutorials/setup-sdk-client.md | 11 +- scripts/tutorial-sync/tutorial-code-map.yml | 12 + 10 files changed, 348 insertions(+), 37 deletions(-) diff --git a/_static/dashmint-lite.html b/_static/dashmint-lite.html index 41de9f965..bb7836ab1 100644 --- a/_static/dashmint-lite.html +++ b/_static/dashmint-lite.html @@ -119,18 +119,24 @@

    Browse cards

    // package and serves it as a browser-native ES module. Pinned to the same // version the React app at ../package.json depends on so both UIs behave // identically against the same testnet contract. - import { EvoSDK } from 'https://esm.sh/@dashevo/evo-sdk@3.1.0-dev.1'; + import { EvoSDK } from 'https://esm.sh/@dashevo/evo-sdk@4.0.0-rc.2'; - // The "card" data contract is already published on testnet by the React app. - // Anyone querying with the same contract id hits the same documents. - const CONTRACT_ID = '4eJR4pgV9mQdyoodfTTwFUp3SYBRJbUrJ5X1ViN2zBhY'; + // The token-enabled "card" data contract is already published on testnet by + // the React app. Anyone querying with the same contract id hits the same + // documents. + const CONTRACT_ID = '5hK6SMfN4m2vU1t9qhvngUUQjsXeMNwr8MZdFeGBH8Aa'; const DOC_TYPE = 'card'; // Connect to testnet. testnetTrusted() uses the SDK's bundled list of trusted // nodes — no node URL or config needed. connect() does the gRPC handshake // + initial sync. No identity or signing is required for read-only queries. + // + // Workaround: pin the platform protocol version for evo-sdk dev.6 so the + // SDK doesn't ask testnet for a newer protocol it can't decode. Mirrors + // PLATFORM_VERSION_OVERRIDE in setupDashClient-core.mjs. Remove once a + // fixed SDK release lands. async function connectSdk() { - const sdk = EvoSDK.testnetTrusted(); + const sdk = EvoSDK.testnetTrusted({ version: 11 }); await sdk.connect(); return sdk; } diff --git a/_static/dashnote-lite.html b/_static/dashnote-lite.html index 4227bc038..3a3f29beb 100644 --- a/_static/dashnote-lite.html +++ b/_static/dashnote-lite.html @@ -129,7 +129,7 @@

    Get note by ID

    // package and serves it as a browser-native ES module. Pinned to the same // version the React app at ../package.json depends on so both UIs behave // identically against the same testnet contract. - import { EvoSDK } from 'https://esm.sh/@dashevo/evo-sdk@3.1.0-dev.1'; + import { EvoSDK } from 'https://esm.sh/@dashevo/evo-sdk@4.0.0-rc.2'; // The "note" data contract is already published on testnet by the React app. // Anyone querying with the same contract id hits the same documents. diff --git a/_static/dashproof-lite.html b/_static/dashproof-lite.html index a9e10f558..1631115df 100644 --- a/_static/dashproof-lite.html +++ b/_static/dashproof-lite.html @@ -120,7 +120,7 @@

    History by chainId

    // package and serves it as a browser-native ES module. Pinned to the same // version the React app at ../package.json depends on so both UIs behave // identically against the same testnet contract. - import { EvoSDK } from 'https://esm.sh/@dashevo/evo-sdk@3.1.0-dev.1'; + import { EvoSDK } from 'https://esm.sh/@dashevo/evo-sdk@4.0.0-rc.2'; // The "anchor" data contract is already published on testnet by the React app. // Anyone querying with the same contract id hits the same documents. diff --git a/docs/tutorials/connecting-to-testnet.md b/docs/tutorials/connecting-to-testnet.md index 91e6ecade..96cc8d9ee 100644 --- a/docs/tutorials/connecting-to-testnet.md +++ b/docs/tutorials/connecting-to-testnet.md @@ -12,7 +12,7 @@ Platform services are provided via a combination of HTTP and gRPC connections to ## Prerequisites -- An installation of [NodeJS v20 or higher](https://nodejs.org/en/download/) +- An installation of [NodeJS v22 or higher](https://nodejs.org/en/download/) ## Connect via Dash SDK diff --git a/docs/tutorials/example-apps/dashmint-lab.md b/docs/tutorials/example-apps/dashmint-lab.md index 60950caf8..5245391bb 100644 --- a/docs/tutorials/example-apps/dashmint-lab.md +++ b/docs/tutorials/example-apps/dashmint-lab.md @@ -4,13 +4,13 @@ # DashMint Lab — NFT marketplace -[DashMint Lab](https://dashpay.github.io/platform-tutorials/dashmint-lab/) is a React + TypeScript + Vite single-page app that exercises every Dash Platform NFT operation: mint, transfer, price, purchase, burn, and query. This walkthrough shows how those SDK calls are organized inside a real UI. +[DashMint Lab](https://dashpay.github.io/platform-tutorials/dashmint-lab/) is a React + TypeScript + Vite single-page app that exercises every Dash Platform NFT operation: mint, transfer, price, purchase, burn, and query. Minting is gated by a fixed-supply DashMint token, so the walkthrough also shows how token balances, token transfers, and token-paid document creation fit into a real UI. ![DashMint Lab - Collection](./img/dashmint-collection.png) ## What this app does -The app lets users log in with a BIP-39 mnemonic, mint "card" NFTs with random attack/defense stats, browse cards across the network, set sale prices, purchase cards from other identities, transfer cards as gifts, and burn cards they no longer want. Read-only browsing works without any credentials. +The app lets users log in with a BIP-39 mnemonic, mint "card" NFTs with random attack/defense stats by burning DashMint tokens, browse cards across the network, set sale prices, purchase cards from other identities, transfer cards or DashMint tokens as gifts, and burn cards they no longer want. Read-only browsing works without any credentials. For background on Dash Platform NFT features such as transfer, trade, delete, and creation restrictions, see the [NFT explanation](../../explanations/nft.md). @@ -21,12 +21,13 @@ Every Platform SDK call lives in its own file under `src/dash/`. The React UI is ## TL;DR - Each NFT operation lives in its own `src/dash/*.ts` file. -- The easiest entry points are `src/dash/queries.ts`, `src/dash/mintCard.ts`, and `src/dash/transferCard.ts`. +- The easiest entry points are `src/dash/queries.ts`, `src/dash/contract.ts`, `src/dash/dashMintToken.ts`, and `src/dash/mintCard.ts`. +- Minting costs 1 DashMint token. The contract burns that token through `card.tokenCost.create`, so the fixed token supply caps the card supply. - Most mutations share one helper: `src/dash/withAuthedCard.ts`. - The UI mostly passes form input into those functions and renders the results. - `client.ts` and `keyManager.ts` are thin re-exports of `setupDashClient-core.mjs`. -If you just want the mental model: read the architecture table, then `withAuthedCard.ts`, then whichever operation you care about. +If you just want the mental model: read the architecture table, then `contract.ts`, `dashMintToken.ts`, `mintCard.ts`, and whichever operation you care about. ## Prerequisites @@ -34,7 +35,8 @@ If you just want the mental model: read the architecture table, then `withAuthed - A configured client: [Setup SDK Client](../setup-sdk-client.md) — DashMint re-uses `setupDashClient-core.mjs` - A registered identity: [Register an Identity](../identities-and-names/register-an-identity.md) - Familiarity with data contracts: [Register a Data Contract](../contracts-and-documents/register-a-data-contract.md) — particularly the NFT tab -- Node >= 20 and a funded testnet identity (BIP-39 mnemonic + identity index) +- Node >= 22 and a funded testnet identity (BIP-39 mnemonic + identity index) +- DashMint tokens on the active contract if you want to mint on an existing contract. Registering a fresh contract starts it with 100 DashMint tokens owned by the registering identity. - (Optional) A second funded identity to test cross-profile transfer and purchase ## Clone and run @@ -46,7 +48,7 @@ npm install npm run dev ``` -The dev server runs on `http://localhost:5173`. Open it in a browser, click **Login**, paste your testnet mnemonic, and start minting. The app ships with a default contract ID so browse-only mode works on a fresh install. +The dev server runs on `http://localhost:5173`. Open it in a browser, click **Login**, and paste your testnet mnemonic. The app ships with a default contract ID so browse-only mode works on a fresh install. To mint, use an identity that already has DashMint tokens for the active contract, transfer tokens from another identity, or register a fresh contract from the login modal. Production build: `npm run build && npm run preview`. @@ -60,15 +62,18 @@ Every Platform SDK call lives in its own file under `src/dash/`: | Derive identity keys | `src/dash/keyManager.ts` | `wallet.deriveKeyFromSeedWithPath` | | Deploy card contract | `src/dash/contract.ts` | `sdk.contracts.publish` | | Query cards | `src/dash/queries.ts` | `sdk.documents.query` | -| Mint a card | `src/dash/mintCard.ts` | `sdk.documents.create` | +| Token balance / supply | `src/dash/dashMintToken.ts` | `sdk.tokens.calculateId`, `sdk.tokens.identityBalances`, `sdk.tokens.totalSupply` | +| Mint a card | `src/dash/mintCard.ts` | `sdk.documents.create` + `tokenPaymentInfo` | +| Transfer DashMint tokens | `src/dash/transferDashMintTokens.ts` | `sdk.tokens.transfer` | | Transfer a card | `src/dash/transferCard.ts` | `sdk.documents.transfer` | | Set / remove price | `src/dash/setPrice.ts` | `sdk.documents.setPrice` | | Purchase a card | `src/dash/purchaseCard.ts` | `sdk.documents.purchase` | | Burn (delete) a card | `src/dash/burnCard.ts` | `sdk.documents.delete` | -Two supporting files glue the operations together: +A few supporting files glue the operations together: - `src/dash/withAuthedCard.ts` — shared mutation prelude used by transfer, setPrice, purchase, and burn. Fetches the document, bumps its revision, and resolves the auth signer. +- `src/dash/dashMintToken.ts` — fixed-supply DashMint token constants, `tokenPaymentInfo`, token balance lookup, and minted-count calculation. - `src/dash/logger.ts` — shared `Logger` type so every operation can stream progress to the UI activity log. `client.ts` and `keyManager.ts` are just re-exports: @@ -80,6 +85,78 @@ export { IdentityKeyManager } from '../../../../setupDashClient-core.mjs'; That means the connection and key-derivation behavior are the same as in the Node tutorials. Read [Setup SDK Client](../setup-sdk-client.md) for the full client setup details. +## DashMint token flow + +DashMint Lab uses a token to make minting scarce without adding a separate minting service. The data contract defines token position `0` as a fixed-supply DashMint token with a supply of 100. The `card` document type charges 1 token on create and burns it, so every successful card mint reduces the remaining mint capacity. + +The token helper file centralizes the constants, the `tokenPaymentInfo` passed to `sdk.documents.create`, and the read helpers used by the Mint and Tokens tabs. + +```{code-block} typescript +:caption: dashMintToken.ts +:name: dashmint-token.ts + +/** + * DashMint token constants and helpers. + * + * The data contract defines token position 0 as a fixed-supply DashMint token. + * Creating a `card` document burns one token via `card.tokenCost.create`. + * UI code uses this file to build tokenPaymentInfo and display the signed-in + * identity's remaining DashMint token balance. + */ +import type { DashSdk } from "./types"; + +export const DASHMINT_TOKEN_POSITION = 0; +export const DASHMINT_TOKEN_COST = 1n; +export const DASHMINT_TOKEN_SUPPLY = 100n; +export const DASHMINT_TOKEN_NAME = "DashMint"; +export const DASHMINT_TOKEN_PLURAL = "DashMint"; + +// Agreement passed to sdk.documents.create() to satisfy the contract's +// one-token burn requirement for card creation. +export const DASHMINT_TOKEN_PAYMENT_INFO = { + tokenContractPosition: DASHMINT_TOKEN_POSITION, + maximumTokenCost: DASHMINT_TOKEN_COST, + gasFeesPaidBy: "documentOwner" as const, +}; + +export async function fetchDashMintTokenBalance({ + sdk, + contractId, + identityId, +}: { + sdk: DashSdk; + contractId: string; + identityId: string; +}): Promise { + const tokenId = await sdk.tokens.calculateId( + contractId, + DASHMINT_TOKEN_POSITION, + ); + const balances = await sdk.tokens.identityBalances(identityId, [tokenId]); + return balances.get(tokenId) ?? 0n; +} + +// Every mint burns exactly one DashMint token (manual burns/mints are locked +// in the contract), so cards minted = SUPPLY - current circulating supply. +export async function fetchCardsMintedCount({ + sdk, + contractId, +}: { + sdk: DashSdk; + contractId: string; +}): Promise { + const tokenId = await sdk.tokens.calculateId( + contractId, + DASHMINT_TOKEN_POSITION, + ); + const supply = await sdk.tokens.totalSupply(tokenId); + const remaining = supply?.totalSupply ?? DASHMINT_TOKEN_SUPPLY; + return DASHMINT_TOKEN_SUPPLY - remaining; +} +``` + +The Mint tab uses `fetchDashMintTokenBalance()` to disable minting when the signed-in identity has no DashMint tokens. It uses `fetchCardsMintedCount()` to show the supply meter, hide the mint form when all 100 cards have been minted, and disable the Starter Pack button when fewer than three mints remain. + ## Shared mutation pattern Every mutation on an existing card — transfer, set price, purchase, burn — runs the same four steps: @@ -233,6 +310,10 @@ export interface Card { $price?: number | bigint; } +function hasSalePrice(card: Card): boolean { + return card.$price != null && card.$price !== 0 && card.$price !== 0n; +} + function toCard(id: string | null, raw: DashCardQueryDocument): Card { const j: Record = typeof raw?.toJSON === "function" ? raw.toJSON() : raw; @@ -311,7 +392,7 @@ export async function listMarketplaceCards({ documentTypeName: "card", limit, }); - const cards = normalizeCards(results).filter((c) => c.$price); + const cards = normalizeCards(results).filter(hasSalePrice); log?.(`Found ${cards.length} card(s) for sale.`); return cards; } @@ -323,12 +404,14 @@ Each operation file is intentionally small. The app-level pattern is: validate i ### Mint a card -Minting is the simplest write operation: build a `Document` with the card properties and owner, then call `sdk.documents.create`. No existing document to fetch, no revision to bump. +Minting builds a `Document` with the card properties and owner, then calls `sdk.documents.create`. There is no existing document to fetch and no revision to bump. The `card` document type has `tokenCost.create` configured, so the call also passes `tokenPaymentInfo` to burn one DashMint token. That token burn is what enforces the fixed card supply. + +The UI exposes this in two ways: a single-card form that burns 1 token, and a Starter Pack button that calls `mintCard()` repeatedly for multiple predefined cards. Both paths use the same SDK helper, so each card still costs 1 DashMint token and each successful create burns one token. ```{code-block} typescript :caption: mintCard.ts :name: dashmint-mintCard.ts -:emphasize-lines: 51,56-63 +:emphasize-lines: 56-58,72-77 /** * Mint a new card (create a document against the card data contract). @@ -336,11 +419,18 @@ Minting is the simplest write operation: build a `Document` with the card proper * Attack and defense are rolled client-side (1-10 each). Name is required, * description is optional. * - * SDK method: sdk.documents.create({ document, identityKey, signer }) + * Scarcity comes from the contract, not this function: the `card` document + * type has `tokenCost.create` configured to burn 1 token at position 0. + * Passing `tokenPaymentInfo` below is the caller's agreement to spend that + * DashMint token, so each successful document create consumes one fixed-supply + * token and reduces the remaining mint capacity. + * + * SDK method: sdk.documents.create({ document, identityKey, signer, tokenPaymentInfo }) */ import { Document } from "@dashevo/evo-sdk"; import type { Logger } from "./logger"; +import { DASHMINT_TOKEN_PAYMENT_INFO } from "./dashMintToken"; import type { DashKeyManager, DashSdk } from "./types"; export interface MintCardInput { @@ -378,7 +468,9 @@ export async function mintCard({ const defense = card.defense ?? rollStat(); const description = card.description?.trim(); - log?.(`Minting "${name}" (ATK ${attack} / DEF ${defense})…`); + log?.( + `Burning 1 DashMint token to mint "${name}" (ATK ${attack} / DEF ${defense})…`, + ); const { identity, identityKey, signer } = await keyManager.getAuth(); @@ -392,7 +484,12 @@ export async function mintCard({ ownerId: identity.id, }); - await sdk.documents.create({ document: doc, identityKey, signer }); + await sdk.documents.create({ + document: doc, + identityKey, + signer, + tokenPaymentInfo: DASHMINT_TOKEN_PAYMENT_INFO, + }); log?.(`Card "${name}" minted!`, "success"); } ``` @@ -656,11 +753,89 @@ export async function burnCard({ } ``` +### Transfer DashMint tokens + +DashMint tokens are ordinary Platform tokens on the active app contract. The Tokens tab lets a signed-in identity send whole DashMint token amounts to another identity, which is useful for testing scarcity across multiple profiles. Unlike card document operations, explicit token sends use the transfer key returned by `keyManager.getTransfer()`. + +```{code-block} typescript +:caption: transferDashMintTokens.ts +:name: dashmint-transfer-dashmint-tokens.ts +:emphasize-lines: 44-64 + +/** + * Transfer DashMint tokens from the signed-in identity to another identity. + * + * DashMint lives at token position 0 on the active app contract. Token + * single-transfer transitions can be signed by a critical auth or transfer + * purpose key; this app keeps explicit token sends on the transfer key. + * + * SDK method: sdk.tokens.transfer({ dataContractId, tokenPosition, amount, senderId, recipientId, identityKey, signer }) + */ +import { DASHMINT_TOKEN_NAME, DASHMINT_TOKEN_POSITION } from "./dashMintToken"; +import type { Logger } from "./logger"; +import type { DashKeyManager, DashSdk } from "./types"; + +export interface TransferDashMintTokensInput { + sdk: DashSdk; + keyManager: DashKeyManager; + contractId: string; + recipientId: string; + amount: bigint; + log?: Logger; +} + +export async function transferDashMintTokens({ + sdk, + keyManager, + contractId, + recipientId, + amount, + log, +}: TransferDashMintTokensInput): Promise { + const trimmedRecipientId = recipientId.trim(); + if (!trimmedRecipientId) { + throw new Error("Recipient identity ID is required."); + } + if (amount <= 0n) { + throw new Error("Amount must be greater than 0."); + } + + const knownSenderId = keyManager.identityId?.toString(); + if (knownSenderId && trimmedRecipientId === knownSenderId) { + throw new Error("Cannot transfer tokens to yourself."); + } + + const { identity, identityKey, signer } = await keyManager.getTransfer(); + const senderId = identity.id.toString(); + if (trimmedRecipientId === senderId) { + throw new Error("Cannot transfer tokens to yourself."); + } + + log?.( + `Transferring ${amount.toString()} ${DASHMINT_TOKEN_NAME} token${ + amount === 1n ? "" : "s" + }...`, + ); + + await sdk.tokens.transfer({ + dataContractId: contractId, + tokenPosition: DASHMINT_TOKEN_POSITION, + amount, + senderId, + recipientId: trimmedRecipientId, + identityKey, + signer, + }); + + log?.(`${DASHMINT_TOKEN_NAME} tokens transferred.`, "success"); +} +``` + ## Contract schema ### What makes this an NFT contract -The card data contract defines one document type (`card`) with four fields and three indices. Three top-level flags turn it into an NFT contract: `transferable: 1` lets owners send cards to other identities, `tradeMode: 1` enables the built-in price/purchase flow, and `creationRestrictionMode: 1` controls who can mint. See the {ref}`NFT explanation ` for what each flag does, and the [NFT tab in Register a Data Contract](../contracts-and-documents/register-a-data-contract.md) for the schema in JSON form. +The card data contract defines one document type (`card`) with four fields and three indices. Three top-level settings control its NFT behavior: `transferable: 1` lets owners send cards to other identities, `tradeMode: 1` enables the built-in price/purchase flow, and `creationRestrictionMode: 0` leaves creation open. Scarcity comes from `tokenCost.create`, so any identity can mint when it can pay and burn 1 DashMint token. See the {ref}`NFT explanation ` for what each flag does, and the [NFT tab in Register a Data Contract](../contracts-and-documents/register-a-data-contract.md) for the schema in JSON form. ### How the app registers or reuses the contract @@ -681,7 +856,10 @@ The card data contract defines one document type (`card`) with four fields and t * The three flags at the top of the schema are what make this an NFT: * transferable: 1 — documents can be sent to another identity (0 to disable) * tradeMode: 1 — documents can be priced and purchased (0 to disable) - * creationRestrictionMode: 1 — (1 - only the contract owner can mint; 0 - anyone can mint) + * creationRestrictionMode: 0 — anyone can create when they can pay tokenCost.create + * + * tokenCost.create burns 1 DashMint token, turning the fixed token + * supply into the maximum number of cards that can ever be minted. * * Storage helpers (loadStoredContractId, saveContractId, …) and the owner * lookup live in contractStorage.ts so they can be imported without @@ -689,10 +867,27 @@ The card data contract defines one document type (`card`) with four fields and t * * SDK methods: new DataContract({ ... }), sdk.contracts.publish(...) */ -import { DataContract } from "@dashevo/evo-sdk"; +import { + AuthorizedActionTakers, + ChangeControlRules, + DataContract, + TokenConfiguration, + TokenConfigurationConvention, + TokenConfigurationLocalization, + TokenDistributionRules, + TokenKeepsHistoryRules, + TokenMarketplaceRules, + TokenTradeMode, +} from "@dashevo/evo-sdk"; import { loadStoredContractId, saveContractId } from "./contractStorage"; import type { Logger } from "./logger"; +import { + DASHMINT_TOKEN_NAME, + DASHMINT_TOKEN_PLURAL, + DASHMINT_TOKEN_POSITION, + DASHMINT_TOKEN_SUPPLY, +} from "./dashMintToken"; import type { DashKeyManager, DashSdk } from "./types"; export { @@ -710,7 +905,15 @@ export const CARD_SCHEMAS = { canBeDeleted: true, transferable: 1, tradeMode: 1, - creationRestrictionMode: 1, + creationRestrictionMode: 0, + tokenCost: { + create: { + tokenPosition: DASHMINT_TOKEN_POSITION, + amount: 1, + effect: 1, + gasFeesPaidBy: 0, + }, + }, properties: { name: { type: "string", @@ -747,6 +950,64 @@ export const CARD_SCHEMAS = { }, } as const; +export function createDashMintTokenConfiguration(ownerId: string) { + const contractOwner = AuthorizedActionTakers.ContractOwner(); + const noOne = AuthorizedActionTakers.NoOne(); + + const ownerRules = new ChangeControlRules({ + authorizedToMakeChange: contractOwner, + adminActionTakers: contractOwner, + isChangingAuthorizedActionTakersToNoOneAllowed: true, + isChangingAdminActionTakersToNoOneAllowed: true, + isSelfChangingAdminActionTakersAllowed: true, + }); + const lockedRules = new ChangeControlRules({ + authorizedToMakeChange: noOne, + adminActionTakers: noOne, + }); + + return new TokenConfiguration({ + conventions: new TokenConfigurationConvention( + { + en: new TokenConfigurationLocalization( + false, + DASHMINT_TOKEN_NAME, + DASHMINT_TOKEN_PLURAL, + ), + }, + 0, + ), + conventionsChangeRules: ownerRules, + baseSupply: DASHMINT_TOKEN_SUPPLY, + maxSupply: DASHMINT_TOKEN_SUPPLY, + keepsHistory: new TokenKeepsHistoryRules({ + isKeepingBurningHistory: true, + isKeepingTransferHistory: true, + }), + maxSupplyChangeRules: lockedRules, + distributionRules: new TokenDistributionRules({ + newTokensDestinationIdentity: ownerId, + newTokensDestinationIdentityRules: ownerRules, + mintingAllowChoosingDestination: false, + mintingAllowChoosingDestinationRules: ownerRules, + perpetualDistributionRules: lockedRules, + changeDirectPurchasePricingRules: lockedRules, + }), + marketplaceRules: new TokenMarketplaceRules( + TokenTradeMode.NotTradeable(), + lockedRules, + ), + manualMintingRules: lockedRules, + manualBurningRules: lockedRules, + freezeRules: lockedRules, + unfreezeRules: lockedRules, + destroyFrozenFundsRules: lockedRules, + emergencyActionRules: lockedRules, + mainControlGroupCanBeModified: noOne, + description: "Fixed-supply DashMint token burned to mint demo cards.", + }); +} + /** * Register a fresh NFT card data contract on Platform and persist its ID. * @@ -768,6 +1029,11 @@ export async function registerContract({ ownerId: identity.id, identityNonce: (identityNonce || 0n) + 1n, schemas: CARD_SCHEMAS, + tokens: { + [DASHMINT_TOKEN_POSITION]: createDashMintTokenConfiguration( + identity.id.toString(), + ), + }, fullValidation: true, }); diff --git a/docs/tutorials/example-apps/dashnote.md b/docs/tutorials/example-apps/dashnote.md index 9a63bca05..52e22a58a 100644 --- a/docs/tutorials/example-apps/dashnote.md +++ b/docs/tutorials/example-apps/dashnote.md @@ -35,7 +35,7 @@ If you just want the mental model: read the architecture table, then `createNote - A configured client: [Setup SDK Client](../setup-sdk-client.md) — Dashnote re-uses `setupDashClient-core.mjs` - A registered identity: [Register an Identity](../identities-and-names/register-an-identity.md) - Familiarity with data contracts: [Register a Data Contract](../contracts-and-documents/register-a-data-contract.md) -- Node >= 20 and a funded testnet identity (BIP-39 mnemonic + identity index) for write operations +- Node >= 22 and a funded testnet identity (BIP-39 mnemonic + identity index) for write operations - Read-only browse works without any credentials against the bundled default contract ## Clone and run @@ -255,6 +255,7 @@ Each operation file is intentionally small. The app-level pattern is: validate i * SDK method: sdk.documents.create({ document, identityKey, signer }) */ import type { Logger } from "../lib/logger"; +import { PLATFORM_VERSION_OVERRIDE } from "../../../../platformVersion.mjs"; import { loadSdkModule } from "./sdkModule"; import type { DashKeyManager, DashSdk } from "./types"; @@ -297,7 +298,7 @@ export async function createNote({ const json = typeof document.toJSON === "function" - ? (document.toJSON() as Record) + ? (document.toJSON(PLATFORM_VERSION_OVERRIDE) as Record) : {}; const noteId = String(json.$id ?? json.id ?? ""); if (!noteId) { @@ -310,7 +311,13 @@ export async function createNote({ ### Update a note -`updateNote.ts` is the canonical fetch-then-bump-revision write. It calls `sdk.documents.get` to read the on-chain revision, increments it by one, builds a new `Document` with the same id and ownerId, and submits via `sdk.documents.replace`. Replays without bumping the revision are rejected by the state transition. +`updateNote.ts` is the canonical fetch-then-bump-revision write: + +- Call `sdk.documents.get` to read the current on-chain revision. +- Increment it by one and build a new `Document` with the same id and ownerId. +- Submit via `sdk.documents.replace`. Replays without bumping the revision are rejected by the state transition. + +The optional `expectedRevision` parameter guards against a concurrent edit: if the on-chain revision no longer matches what the caller last loaded, the update is refused with a "reload and try again" error instead of silently overwriting the newer version. ```{code-block} typescript :caption: updateNote.ts @@ -320,6 +327,10 @@ export async function createNote({ * Update an existing note. Fetches the current document to bump its revision, * then submits a replace state transition. * + * Pass `expectedRevision` to refuse the update if the network's revision + * doesn't match — i.e. the note was changed on the network after the local + * copy was loaded. + * * SDK methods: * sdk.documents.get(contractId, documentTypeName, documentId) * sdk.documents.replace({ document, identityKey, signer }) @@ -335,6 +346,7 @@ export interface UpdateNoteParams { noteId: string; title?: string; message: string; + expectedRevision?: number; log?: Logger; } @@ -345,6 +357,7 @@ export async function updateNote({ noteId, title, message, + expectedRevision, log, }: UpdateNoteParams): Promise { log?.(`Saving note ${noteId}…`); @@ -354,8 +367,18 @@ export async function updateNote({ throw new Error(`Note ${noteId} not found.`); } + const currentRevision = BigInt(existingDoc.revision ?? 0); + if ( + expectedRevision !== undefined && + currentRevision !== BigInt(expectedRevision) + ) { + throw new Error( + `Note changed on network (you had revision ${expectedRevision}, network is at ${currentRevision}). Reload your notes and try again.`, + ); + } + const { Document } = await loadSdkModule(); - const revision = BigInt(existingDoc.revision ?? 0) + 1n; + const revision = currentRevision + 1n; const trimmedTitle = title?.trim(); const document = new Document({ properties: { @@ -431,7 +454,7 @@ export async function deleteNote({ The note contract is intentionally minimal: one document type, two user-editable fields, two indices to support the recent-notes list. Key choices worth calling out: - `documentsMutable: true` and `canBeDeleted: true` — notes are editable and deletable. -- `maxLength: 120` for `title` and `maxLength: 10000` for `message` are **UTF-8 byte budgets**, not character counts. The editor's progress bar reflects bytes; emoji and non-ASCII sequences consume more of the budget than ASCII. +- `maxLength: 120` for `title` caps the title; `message` carries no `maxLength` and is instead bounded by Platform's per-field byte limit. The editor's progress bar tracks the `message` byte count against that limit — emoji and non-ASCII sequences consume more of the budget than ASCII. - `byOwnerUpdated` (`$ownerId`, `$updatedAt`) is the index the recent-notes list paginates on; `byOwnerCreated` is its created-time sibling. `registerContract` builds the `DataContract`, calls `setConfig()` to lock in those choices, then publishes via `sdk.contracts.publish`. `ensureContract` is the lazy wrapper used by the login flow: re-use a saved contract ID if one is present, otherwise register a fresh one. @@ -464,7 +487,6 @@ export const NOTE_SCHEMAS = { }, message: { type: "string", - maxLength: 10000, position: 1, }, }, diff --git a/docs/tutorials/identities-and-names/withdraw-an-identity-balance.md b/docs/tutorials/identities-and-names/withdraw-an-identity-balance.md index ef4311b47..e74319590 100644 --- a/docs/tutorials/identities-and-names/withdraw-an-identity-balance.md +++ b/docs/tutorials/identities-and-names/withdraw-an-identity-balance.md @@ -32,7 +32,7 @@ console.log('Identity balance before withdrawal:', identity.balance); // Default: testnet faucet address. Replace or override via WITHDRAWAL_ADDRESS. const toAddress = process.env.WITHDRAWAL_ADDRESS || 'yXWJGWuD4VBRMp9n2MtXQbGpgSeWyTRHme'; -const amount = 190000n; // Credits to withdraw +const amount = 1000000n; // Credits to withdraw (protocol minimum) const amountDash = Number(amount) / (1000 * 100000000); console.log(`Withdrawing ${amount} credits (${amountDash} DASH)`); diff --git a/docs/tutorials/introduction.md b/docs/tutorials/introduction.md index bf56233c1..9b2756950 100644 --- a/docs/tutorials/introduction.md +++ b/docs/tutorials/introduction.md @@ -12,7 +12,7 @@ Building on Dash Platform requires first registering an Identity and then regist The tutorials in this section are written in JavaScript and use [Node.js](https://nodejs.org/en/about/). The following prerequisites are necessary to complete the tutorials: -- [Node.js](https://nodejs.org/en/) (v20+) +- [Node.js](https://nodejs.org/en/) (v22+) - Familiarity with JavaScript asynchronous functions using [async/await](https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Asynchronous/Async_await) - The [Dash JavaScript SDK](https://www.npmjs.com/package/@dashevo/evo-sdk) (see [Connecting to a Network](../tutorials/connecting-to-testnet.md#1-install-the-dash-sdk)) diff --git a/docs/tutorials/setup-sdk-client.md b/docs/tutorials/setup-sdk-client.md index 1ba48510e..00e8f16d1 100644 --- a/docs/tutorials/setup-sdk-client.md +++ b/docs/tutorials/setup-sdk-client.md @@ -67,6 +67,7 @@ import { SecurityLevel, wallet, } from '@dashevo/evo-sdk'; +import { PLATFORM_VERSION_OVERRIDE } from './platformVersion.mjs'; /** @typedef {import('@dashevo/evo-sdk').Identity} Identity */ /** @typedef {import('@dashevo/evo-sdk').IdentityPublicKey} IdentityPublicKey */ @@ -144,6 +145,8 @@ export async function dip13KeyPath(network, identityIndex, keyIndex) { // SDK client helpers // --------------------------------------------------------------------------- +export { PLATFORM_VERSION_OVERRIDE }; + /** * Create and connect an EvoSDK client for the selected network. * @@ -152,9 +155,11 @@ export async function dip13KeyPath(network, identityIndex, keyIndex) { */ export async function createClient(network = 'testnet') { const factories = /** @type {Record EvoSDK>} */ ({ - testnet: () => EvoSDK.testnetTrusted(), - mainnet: () => EvoSDK.mainnetTrusted(), - local: () => EvoSDK.localTrusted(), + testnet: () => + EvoSDK.testnetTrusted({ version: PLATFORM_VERSION_OVERRIDE }), + mainnet: () => + EvoSDK.mainnetTrusted({ version: PLATFORM_VERSION_OVERRIDE }), + local: () => EvoSDK.localTrusted({ version: PLATFORM_VERSION_OVERRIDE }), }); const factory = factories[network]; diff --git a/scripts/tutorial-sync/tutorial-code-map.yml b/scripts/tutorial-sync/tutorial-code-map.yml index 56e9aba3e..c1296b9af 100644 --- a/scripts/tutorial-sync/tutorial-code-map.yml +++ b/scripts/tutorial-sync/tutorial-code-map.yml @@ -199,6 +199,12 @@ mappings: caption: contract.ts language: typescript + - source: example-apps/dashmint-lab/src/dash/dashMintToken.ts + doc: example-apps/dashmint-lab.md + block_id: + caption: dashMintToken.ts + language: typescript + - source: example-apps/dashmint-lab/src/dash/withAuthedCard.ts doc: example-apps/dashmint-lab.md block_id: @@ -217,6 +223,12 @@ mappings: caption: transferCard.ts language: typescript + - source: example-apps/dashmint-lab/src/dash/transferDashMintTokens.ts + doc: example-apps/dashmint-lab.md + block_id: + caption: transferDashMintTokens.ts + language: typescript + - source: example-apps/dashmint-lab/src/dash/setPrice.ts doc: example-apps/dashmint-lab.md block_id: From 07d9895fd47c6801984ddb17fe92780917f14721 Mon Sep 17 00:00:00 2001 From: thephez Date: Tue, 23 Jun 2026 12:07:15 -0400 Subject: [PATCH 6/8] docs(tutorials): add token lifecycle tutorials (#154) * docs(tutorials): add token lifecycle tutorials Add a Tokens tutorial section covering the issuer-managed token lifecycle on Evo SDK 4.0.0-rc.2: register a token contract, retrieve token info, mint, burn, and transfer tokens. Wire the new pages into the tutorials toctree and sidebar, and add their source mappings to the tutorial code-sync map so the embedded examples stay in sync with platform-tutorials. Co-Authored-By: Claude Opus 4.8 (1M context) * docs(tutorials): link token tutorials to DashMint Lab example app Add 'See this in an example app' tips on the register, retrieve-info, and transfer token tutorials pointing to the matching DashMint Lab sections, matching the cross-link pattern used by the contract and document tutorials. Co-Authored-By: Claude Opus 4.8 (1M context) * docs(tutorials): clarify token tutorial recipient and contract ID guidance Note that the recipient defaults to a demo testnet identity and explain when to set RECIPIENT_ID to a second identity you control. On the register page, clarify that TOKEN_CONTRACT_ID is the published contract ID, not the token ID printed at the end. --------- Co-authored-by: Claude Opus 4.8 (1M context) --- _templates/sidebar-main.html | 40 ++++ docs/index.md | 1 + docs/tutorials/tokens.md | 22 ++ docs/tutorials/tokens/burn-tokens.md | 68 ++++++ docs/tutorials/tokens/mint-tokens.md | 68 ++++++ .../tokens/register-a-token-contract.md | 203 ++++++++++++++++++ docs/tutorials/tokens/retrieve-token-info.md | 88 ++++++++ .../tokens/transfer-tokens-to-an-identity.md | 96 +++++++++ scripts/tutorial-sync/tutorial-code-map.yml | 27 +++ 9 files changed, 613 insertions(+) create mode 100644 docs/tutorials/tokens.md create mode 100644 docs/tutorials/tokens/burn-tokens.md create mode 100644 docs/tutorials/tokens/mint-tokens.md create mode 100644 docs/tutorials/tokens/register-a-token-contract.md create mode 100644 docs/tutorials/tokens/retrieve-token-info.md create mode 100644 docs/tutorials/tokens/transfer-tokens-to-an-identity.md diff --git a/_templates/sidebar-main.html b/_templates/sidebar-main.html index c973bc7b4..71eb257e9 100644 --- a/_templates/sidebar-main.html +++ b/_templates/sidebar-main.html @@ -163,6 +163,46 @@
  • +
  • + + Tokens + +
    + + + + + + + +
    +
  • Example apps diff --git a/docs/index.md b/docs/index.md index e42d5fdf5..875e97d6a 100644 --- a/docs/index.md +++ b/docs/index.md @@ -111,6 +111,7 @@ tutorials/create-and-fund-a-wallet tutorials/setup-sdk-client tutorials/identities-and-names tutorials/contracts-and-documents +tutorials/tokens tutorials/example-apps tutorials/send-funds tutorials/setup-a-node diff --git a/docs/tutorials/tokens.md b/docs/tutorials/tokens.md new file mode 100644 index 000000000..eea02af93 --- /dev/null +++ b/docs/tutorials/tokens.md @@ -0,0 +1,22 @@ +```{eval-rst} +.. tutorials-tokens: +``` + +# Tokens + +The following tutorials cover registering, querying, and managing tokens on Dash Platform, including minting, burning, and transferring them between identities. + +```{toctree} +:maxdepth: 2 +:titlesonly: + +tokens/register-a-token-contract +tokens/retrieve-token-info +tokens/mint-tokens +tokens/burn-tokens +tokens/transfer-tokens-to-an-identity +``` + +:::{tip} +You can clone a repository containing the code for all tutorials from GitHub or download it as a [zip file](https://github.com/dashpay/platform-readme-tutorials/archive/refs/heads/main.zip). +::: diff --git a/docs/tutorials/tokens/burn-tokens.md b/docs/tutorials/tokens/burn-tokens.md new file mode 100644 index 000000000..3cb662e68 --- /dev/null +++ b/docs/tutorials/tokens/burn-tokens.md @@ -0,0 +1,68 @@ +```{eval-rst} +.. tutorials-burn-tokens: +``` + +# Burn tokens + +The purpose of this tutorial is to walk through the steps necessary to burn (permanently destroy) [tokens](../../explanations/tokens.md), reducing the total supply. + +## Overview + +Burning permanently removes tokens from circulation, decreasing the token's total supply. Burning is only possible when the token contract authorizes it, which the [Register a token contract](register-a-token-contract.md) tutorial sets up. Additional details are available in the [tokens explanation](../../explanations/tokens.md) and the [token protocol reference](../../protocol-ref/token.md). + +## Prerequisites + +- [General prerequisites](../../tutorials/introduction.md#prerequisites) (Node.js / Dash SDK installed) +- A configured client: [Setup SDK Client](../setup-sdk-client.md) +- A registered token contract with a balance to burn: [Tutorial: Register a token contract](register-a-token-contract.md). Set the resulting contract ID as the `TOKEN_CONTRACT_ID` environment variable. + +## Code + +```{code-block} javascript +:caption: token-burn.mjs + +import { setupDashClient } from '../setupDashClient.mjs'; + +const { sdk, keyManager } = await setupDashClient(); +const { identity, identityKey, signer } = await keyManager.getAuth(); + +// TOKEN_CONTRACT_ID comes from token-register.mjs. +const dataContractId = process.env.TOKEN_CONTRACT_ID; +const tokenPosition = 0; +const amount = 1n; // Token amounts are bigint values + +try { + if (!dataContractId) { + throw new Error( + 'Set TOKEN_CONTRACT_ID in .env from token-register.mjs output.', + ); + } + + const tokenId = await sdk.tokens.calculateId(dataContractId, tokenPosition); + + await sdk.tokens.burn({ + dataContractId, + tokenPosition, + amount, + identityId: identity.id.toString(), + identityKey, + signer, + }); + + const balances = await sdk.tokens.identityBalances(identity.id, [tokenId]); + const totalSupply = await sdk.tokens.totalSupply(tokenId); + + console.log(`Burned ${amount} token`); + console.log('Token ID:', tokenId); + console.log(`Identity token balance: ${balances.get(tokenId) ?? 0n}`); + console.log('Total token supply:', totalSupply?.totalSupply ?? 0n); +} catch (e) { + console.error('Something went wrong:\n', e.message); +} +``` + +## What's Happening + +After connecting to the client, we get the auth key signer with `keyManager.getAuth()`. We then call `sdk.tokens.burn()` with the contract ID, token position, amount, and signing credentials to destroy 1 token from our balance. Token amounts are `bigint` values, which is why `1n` is written with the `n` suffix. + +After burning, we read back the identity's balance with `sdk.tokens.identityBalances()` and the new total supply with `sdk.tokens.totalSupply()` to confirm both have decreased. diff --git a/docs/tutorials/tokens/mint-tokens.md b/docs/tutorials/tokens/mint-tokens.md new file mode 100644 index 000000000..5924ea3c5 --- /dev/null +++ b/docs/tutorials/tokens/mint-tokens.md @@ -0,0 +1,68 @@ +```{eval-rst} +.. tutorials-mint-tokens: +``` + +# Mint tokens + +The purpose of this tutorial is to walk through the steps necessary to mint (issue) new [tokens](../../explanations/tokens.md), increasing the total supply. + +## Overview + +Minting issues new tokens to the contract owner, increasing the token's total supply up to its maximum. Minting is only possible when the token contract authorizes it, which the [Register a token contract](register-a-token-contract.md) tutorial sets up. Additional details are available in the [tokens explanation](../../explanations/tokens.md) and the [token protocol reference](../../protocol-ref/token.md). + +## Prerequisites + +- [General prerequisites](../../tutorials/introduction.md#prerequisites) (Node.js / Dash SDK installed) +- A configured client: [Setup SDK Client](../setup-sdk-client.md) +- A registered token contract: [Tutorial: Register a token contract](register-a-token-contract.md). Set the resulting contract ID as the `TOKEN_CONTRACT_ID` environment variable. + +## Code + +```{code-block} javascript +:caption: token-mint.mjs + +import { setupDashClient } from '../setupDashClient.mjs'; + +const { sdk, keyManager } = await setupDashClient(); +const { identity, identityKey, signer } = await keyManager.getAuth(); + +// TOKEN_CONTRACT_ID comes from token-register.mjs. +const dataContractId = process.env.TOKEN_CONTRACT_ID; +const tokenPosition = 0; +const amount = 10n; // Token amounts are bigint values + +try { + if (!dataContractId) { + throw new Error( + 'Set TOKEN_CONTRACT_ID in .env from token-register.mjs output.', + ); + } + + const tokenId = await sdk.tokens.calculateId(dataContractId, tokenPosition); + + await sdk.tokens.mint({ + dataContractId, + tokenPosition, + amount, + identityId: identity.id.toString(), + identityKey, + signer, + }); + + const balances = await sdk.tokens.identityBalances(identity.id, [tokenId]); + const totalSupply = await sdk.tokens.totalSupply(tokenId); + + console.log(`Minted ${amount} tokens`); + console.log('Token ID:', tokenId); + console.log(`Identity token balance: ${balances.get(tokenId) ?? 0n}`); + console.log('Total token supply:', totalSupply?.totalSupply ?? 0n); +} catch (e) { + console.error('Something went wrong:\n', e.message); +} +``` + +## What's Happening + +After connecting to the client, we get the auth key signer with `keyManager.getAuth()`. We then call `sdk.tokens.mint()` with the contract ID, token position, amount, and signing credentials to issue 10 new tokens to our identity. Token amounts are `bigint` values, which is why `10n` is written with the `n` suffix. + +After minting, we read back the identity's balance with `sdk.tokens.identityBalances()` and the new total supply with `sdk.tokens.totalSupply()` to confirm both have increased. diff --git a/docs/tutorials/tokens/register-a-token-contract.md b/docs/tutorials/tokens/register-a-token-contract.md new file mode 100644 index 000000000..b2ad8cc07 --- /dev/null +++ b/docs/tutorials/tokens/register-a-token-contract.md @@ -0,0 +1,203 @@ +```{eval-rst} +.. tutorials-register-token-contract: +``` + +# Register a token contract + +The purpose of this tutorial is to walk through the steps necessary to register a [token](../../explanations/tokens.md) on Dash Platform. + +## Overview + +Tokens on Dash Platform are defined inside a [data contract](../../explanations/platform-protocol-data-contract.md). A single contract can carry one or more tokens alongside its document types, and each token is identified by its position within the contract. Registering the contract creates the token, sets its supply limits, and establishes the rules that control who may mint, burn, transfer, or otherwise manage it. + +This tutorial registers an issuer-managed token: the contract owner controls minting and burning, and newly minted tokens always go to the owner identity. The token is not configured with advanced options. That keeps this tutorial focused on the normal token lifecycle used by the remaining token tutorials. Additional details are available in the [tokens explanation](../../explanations/tokens.md) and the [token protocol reference](../../protocol-ref/token.md). + +## Prerequisites + +- [General prerequisites](../../tutorials/introduction.md#prerequisites) (Node.js / Dash SDK installed) +- A platform address with a balance: [Tutorial: Create and Fund a Wallet](../../tutorials/create-and-fund-a-wallet.md) +- A configured client: [Setup SDK Client](../setup-sdk-client.md) +- A Dash Platform Identity: [Tutorial: Register an Identity](../../tutorials/identities-and-names/register-an-identity.md) + +## Code + +```{code-block} javascript +:caption: token-register.mjs + +import { + AuthorizedActionTakers, + ChangeControlRules, + DataContract, + TokenConfiguration, + TokenConfigurationConvention, + TokenConfigurationLocalization, + TokenDistributionRules, + TokenKeepsHistoryRules, + TokenMarketplaceRules, + TokenTradeMode, +} from '@dashevo/evo-sdk'; +import { setupDashClient } from '../setupDashClient.mjs'; + +const { sdk, keyManager } = await setupDashClient(); +const { identity, identityKey, signer } = await keyManager.getAuth(); + +const TOKEN_POSITION = 0; +const TOKEN_NAME = 'TutorialToken'; +const TOKEN_PLURAL = 'TutorialTokens'; +const TOKEN_BASE_SUPPLY = 100n; // Token amounts are bigint values +const TOKEN_MAX_SUPPLY = 1000n; + +// This contract includes one small document type so learners can still use the +// standard document tutorials with the same contract if they want to. +const documentSchemas = { + note: { + type: 'object', + properties: { + message: { + type: 'string', + position: 0, + }, + }, + additionalProperties: false, + }, +}; + +function createTutorialTokenConfiguration(ownerId) { + const contractOwner = AuthorizedActionTakers.ContractOwner(); + const noOne = AuthorizedActionTakers.NoOne(); + + const ownerRules = new ChangeControlRules({ + authorizedToMakeChange: contractOwner, + adminActionTakers: contractOwner, + isChangingAuthorizedActionTakersToNoOneAllowed: true, + isChangingAdminActionTakersToNoOneAllowed: true, + isSelfChangingAdminActionTakersAllowed: true, + }); + const lockedRules = new ChangeControlRules({ + authorizedToMakeChange: noOne, + adminActionTakers: noOne, + }); + + return new TokenConfiguration({ + conventions: new TokenConfigurationConvention( + { + en: new TokenConfigurationLocalization(false, TOKEN_NAME, TOKEN_PLURAL), + }, + 0, + ), + conventionsChangeRules: ownerRules, + baseSupply: TOKEN_BASE_SUPPLY, + maxSupply: TOKEN_MAX_SUPPLY, + keepsHistory: new TokenKeepsHistoryRules({ + isKeepingBurningHistory: true, + isKeepingMintingHistory: true, + isKeepingTransferHistory: true, + }), + maxSupplyChangeRules: lockedRules, + distributionRules: new TokenDistributionRules({ + newTokensDestinationIdentity: ownerId, + newTokensDestinationIdentityRules: ownerRules, + mintingAllowChoosingDestination: false, + mintingAllowChoosingDestinationRules: ownerRules, + perpetualDistributionRules: lockedRules, + changeDirectPurchasePricingRules: lockedRules, + }), + marketplaceRules: new TokenMarketplaceRules( + TokenTradeMode.NotTradeable(), + lockedRules, + ), + // Minting and burning are enabled so the next tutorials can demonstrate + // the normal issuer-managed token lifecycle. + manualMintingRules: ownerRules, + manualBurningRules: ownerRules, + freezeRules: lockedRules, + unfreezeRules: lockedRules, + destroyFrozenFundsRules: lockedRules, + emergencyActionRules: lockedRules, + mainControlGroupCanBeModified: noOne, + description: 'Issuer-managed token for Platform token tutorials.', + }); +} + +try { + const identityNonce = await sdk.identities.nonce(identity.id.toString()); + + const dataContract = new DataContract({ + ownerId: identity.id, + identityNonce: (identityNonce || 0n) + 1n, + schemas: documentSchemas, + tokens: { + [TOKEN_POSITION]: createTutorialTokenConfiguration( + identity.id.toString(), + ), + }, + fullValidation: true, + }); + + const publishedContract = await sdk.contracts.publish({ + dataContract, + identityKey, + signer, + }); + + const contractId = + publishedContract.id?.toString() || publishedContract.toJSON?.()?.id; + + if (!contractId) { + const publishResult = publishedContract.toJSON?.() ?? publishedContract; + throw new Error( + `Contract publish returned no id: ${JSON.stringify(publishResult)}`, + ); + } + + const tokenId = await sdk.tokens.calculateId(contractId, TOKEN_POSITION); + + console.log('Token contract registered:\n', publishedContract.toJSON()); + console.log('Token position:', TOKEN_POSITION); + console.log('Token ID:', tokenId); + console.log('Initial owner token balance:', TOKEN_BASE_SUPPLY.toString()); + console.log('Maximum token supply:', TOKEN_MAX_SUPPLY.toString()); +} catch (e) { + console.error('Something went wrong:\n', e.message); +} +``` + +:::{attention} +Make a note of the returned contract ID. The remaining token tutorials read it from the `TOKEN_CONTRACT_ID` environment variable, so set it before running them. + +Use the contract ID from the published contract output, not the token ID printed at the end: + +```text +TOKEN_CONTRACT_ID= +``` +::: + +## What's Happening + +After initializing the client, we get the auth key signer from the key manager. We then register a data contract that carries a token at position 0. The token starts with a base supply of 100 (minted to the owner) and a maximum supply of 1,000. Token amounts are always `bigint` values, which is why they are written with the `n` suffix (for example, `100n`). + +Minting and burning are enabled and restricted to the contract owner, so the [mint](mint-tokens.md) and [burn](burn-tokens.md) tutorials work out of the box. The token also keeps a full history of mints, burns, and transfers. + +To register the contract, we fetch the identity's current nonce and increment it, build a `DataContract` with the document schemas and the token configuration, and call `sdk.contracts.publish()`. Finally, we derive the token ID from the contract ID and token position with `sdk.tokens.calculateId()`. + +:::{dropdown} Token configuration details +The token's behaviour is defined by a `TokenConfiguration`. Each group of rules is a `ChangeControlRules` object that says who may perform an action and who may change that permission. The tutorial uses two presets: + +- `ownerRules` — the contract owner is authorized (`AuthorizedActionTakers.ContractOwner()`). +- `lockedRules` — no one is authorized (`AuthorizedActionTakers.NoOne()`), permanently disabling the action. + +The main groups: + +- **Supply** — `baseSupply` is minted to the owner at registration; `maxSupply` caps the total. `maxSupplyChangeRules` is locked, so the cap cannot be changed later. +- **Minting and burning** — `manualMintingRules` and `manualBurningRules` use `ownerRules`, letting the owner issue and destroy tokens. +- **History** — `keepsHistory` records minting, burning, and transfer events so they can be queried later. +- **Distribution** — `distributionRules` sends newly minted tokens to the owner (`newTokensDestinationIdentity`) and prevents minting from choosing a different destination (`mintingAllowChoosingDestination: false`). Perpetual distribution is locked, so there is no automated recurring distribution. +- **Marketplace and pricing** — `marketplaceRules` uses `TokenTradeMode.NotTradeable()`, so the token cannot be listed for direct purchase, and the trade mode itself is locked. The permission to set a direct-purchase price (`changeDirectPurchasePricingRules`, defined with the distribution rules) is also locked. +- **Freeze and emergency actions** — `freezeRules`, `unfreezeRules`, `destroyFrozenFundsRules`, and `emergencyActionRules` are locked in this example. + +See the [tokens explanation](../../explanations/tokens.md) and the [token protocol reference](../../protocol-ref/token.md) for the full set of configuration fields. +::: + +:::{tip} +See this in an example app: [DashMint Lab — Contract schema](../example-apps/dashmint-lab.md#contract-schema) defines a token alongside its NFT documents, and [DashMint Lab — DashMint token flow](../example-apps/dashmint-lab.md#dashmint-token-flow) shows how the token is used. +::: diff --git a/docs/tutorials/tokens/retrieve-token-info.md b/docs/tutorials/tokens/retrieve-token-info.md new file mode 100644 index 000000000..38b3af04e --- /dev/null +++ b/docs/tutorials/tokens/retrieve-token-info.md @@ -0,0 +1,88 @@ +```{eval-rst} +.. tutorials-retrieve-token-info: +``` + +# Retrieve token info + +The purpose of this tutorial is to walk through the steps necessary to retrieve information about a [token](../../explanations/tokens.md), including its contract details, total supply, status, and identity balances. + +## Overview + +Once a token contract is registered, its metadata and balances can be queried without submitting a state transition. This tutorial retrieves the token's contract info, total supply, status, and the token balances held by two identities. Additional details are available in the [tokens explanation](../../explanations/tokens.md) and the [token protocol reference](../../protocol-ref/token.md). + +## Prerequisites + +- [General prerequisites](../../tutorials/introduction.md#prerequisites) (Node.js / Dash SDK installed) +- A configured client: [Setup SDK Client](../setup-sdk-client.md) +- A registered token contract: [Tutorial: Register a token contract](register-a-token-contract.md). Set the resulting contract ID as the `TOKEN_CONTRACT_ID` environment variable. + +## Code + +```{code-block} javascript +:caption: token-info.mjs + +import { setupDashClient } from '../setupDashClient.mjs'; + +const { sdk, keyManager } = await setupDashClient(); + +// TOKEN_CONTRACT_ID comes from token-register.mjs. +const dataContractId = process.env.TOKEN_CONTRACT_ID; +const tokenPosition = 0; + +// Default recipient (testnet). Replace or override via RECIPIENT_ID. +const recipientId = + process.env.RECIPIENT_ID || '7XcruVSsGQVSgTcmPewaE4tXLutnW1F6PXxwMbo8GYQC'; + +try { + if (!dataContractId) { + throw new Error( + 'Set TOKEN_CONTRACT_ID in .env from token-register.mjs output.', + ); + } + + const tokenId = await sdk.tokens.calculateId(dataContractId, tokenPosition); + const contractInfo = await sdk.tokens.contractInfo(tokenId); + const totalSupply = await sdk.tokens.totalSupply(tokenId); + const statuses = await sdk.tokens.statuses([tokenId]); + const identityBalances = await sdk.tokens.identityBalances( + keyManager.identityId, + [tokenId], + ); + const recipientBalances = await sdk.tokens.identityBalances(recipientId, [ + tokenId, + ]); + + // A token only has a status record once one is published on-chain (e.g. via + // an emergency pause), so the Map is empty for a freshly registered token. + const status = statuses.get(tokenId); + + console.log('Token ID:', tokenId); + console.log('Token contract info:\n', contractInfo?.toJSON()); + console.log( + 'Token status:', + status ? status.isPaused : '(no status published)', + ); + console.log('Total token supply:', totalSupply?.totalSupply ?? 0n); + console.log(`Identity token balance: ${identityBalances.get(tokenId) ?? 0n}`); + console.log( + `Recipient token balance: ${recipientBalances.get(tokenId) ?? 0n}`, + ); +} catch (e) { + console.error('Something went wrong:\n', e.message); +} +``` + +## What's Happening + +After connecting to the client, we derive the token ID from the contract ID and token position with `sdk.tokens.calculateId()`. We then query several pieces of information: + +- `sdk.tokens.contractInfo()` returns the token's contract metadata. +- `sdk.tokens.totalSupply()` returns the number of tokens currently in circulation. +- `sdk.tokens.statuses()` returns a Map of token statuses. A status record only exists once one is published on-chain (for example, after an emergency pause), so the Map is empty for a freshly registered token. We fall back to `(no status published)` in that case. +- `sdk.tokens.identityBalances()` returns each identity's token balance, keyed by token ID. + +The recipient defaults to a demo testnet identity so the script can run without extra setup. Set `RECIPIENT_ID` in the .env file to your own second identity when you want the recipient balance check to reflect an identity you control. + +:::{tip} +See this in an example app: [DashMint Lab — DashMint token flow](../example-apps/dashmint-lab.md#dashmint-token-flow) reads the signed-in identity's token balance to display remaining mint capacity. +::: diff --git a/docs/tutorials/tokens/transfer-tokens-to-an-identity.md b/docs/tutorials/tokens/transfer-tokens-to-an-identity.md new file mode 100644 index 000000000..3d3d0c7bd --- /dev/null +++ b/docs/tutorials/tokens/transfer-tokens-to-an-identity.md @@ -0,0 +1,96 @@ +```{eval-rst} +.. tutorials-transfer-tokens-to-identity: +``` + +# Transfer tokens to an identity + +The purpose of this tutorial is to walk through the steps necessary to transfer [tokens](../../explanations/tokens.md) from one identity to another. + +## Overview + +Transferring moves tokens from the sender's balance to a recipient identity. The total supply is unchanged; only the balances of the two identities are affected. Additional details are available in the [tokens explanation](../../explanations/tokens.md) and the [token protocol reference](../../protocol-ref/token.md). + +## Prerequisites + +- [General prerequisites](../../tutorials/introduction.md#prerequisites) (Node.js / Dash SDK installed) +- A configured client: [Setup SDK Client](../setup-sdk-client.md) +- A registered token contract with a balance to transfer: [Tutorial: Register a token contract](register-a-token-contract.md). Set the resulting contract ID as the `TOKEN_CONTRACT_ID` environment variable. +- A second Dash Platform Identity to receive the tokens: [Tutorial: Register an Identity](../../tutorials/identities-and-names/register-an-identity.md) + +## Code + +```{code-block} javascript +:caption: token-transfer.mjs + +import { setupDashClient } from '../setupDashClient.mjs'; + +const { sdk, keyManager } = await setupDashClient(); +const { identity, identityKey, signer } = await keyManager.getTransfer(); + +// TOKEN_CONTRACT_ID comes from token-register.mjs. +const dataContractId = process.env.TOKEN_CONTRACT_ID; +const tokenPosition = 0; + +// Default recipient (testnet). Replace or override via RECIPIENT_ID. +const recipientId = + process.env.RECIPIENT_ID || '7XcruVSsGQVSgTcmPewaE4tXLutnW1F6PXxwMbo8GYQC'; +const amount = 1n; + +try { + if (!dataContractId) { + throw new Error( + 'Set TOKEN_CONTRACT_ID in .env from token-register.mjs output.', + ); + } + + const senderId = identity.id.toString(); + if (recipientId === senderId) { + throw new Error('Cannot transfer tokens to yourself.'); + } + + const tokenId = await sdk.tokens.calculateId(dataContractId, tokenPosition); + const balancesBefore = await sdk.tokens.identityBalances(recipientId, [ + tokenId, + ]); + + console.log( + `Recipient token balance before transfer: ${balancesBefore.get(tokenId) ?? 0n}`, + ); + + await sdk.tokens.transfer({ + dataContractId, + tokenPosition, + amount, + senderId, + recipientId, + identityKey, + signer, + }); + + const balancesAfter = await sdk.tokens.identityBalances(recipientId, [ + tokenId, + ]); + + console.log( + `Transferred ${amount} token${amount === 1n ? '' : 's'} from ${senderId} to ${recipientId}`, + ); + console.log('Token ID:', tokenId); + console.log( + `Recipient token balance after transfer: ${balancesAfter.get(tokenId) ?? 0n}`, + ); +} catch (e) { + console.error('Something went wrong:\n', e.message); +} +``` + +## What's Happening + +After connecting to the client, we get the transfer key signer with `keyManager.getTransfer()`. Token transfers are authorized with the identity's transfer key rather than its auth key. + +We derive the token ID with `sdk.tokens.calculateId()` and read the recipient's balance before the transfer so the change is visible. A guard rejects transfers where the recipient matches the sender, since an identity cannot transfer tokens to itself. + +We then call `sdk.tokens.transfer()` with the contract ID, token position, amount, sender ID, recipient ID, and signing credentials to move 1 token. After the transfer, we read the recipient's balance again with `sdk.tokens.identityBalances()` to confirm it increased. The recipient defaults to a demo testnet identity, but set `RECIPIENT_ID` in the .env file to your own second identity when you want to verify a transfer to an identity you control. + +:::{tip} +See this in an example app: [DashMint Lab — Transfer DashMint tokens](../example-apps/dashmint-lab.md#transfer-dashmint-tokens). +::: diff --git a/scripts/tutorial-sync/tutorial-code-map.yml b/scripts/tutorial-sync/tutorial-code-map.yml index c1296b9af..f8954a871 100644 --- a/scripts/tutorial-sync/tutorial-code-map.yml +++ b/scripts/tutorial-sync/tutorial-code-map.yml @@ -188,6 +188,33 @@ mappings: block_id: caption: document-delete.mjs + # -- Tokens -- + + - source: 3-Tokens/token-register.mjs + doc: tokens/register-a-token-contract.md + block_id: + caption: token-register.mjs + + - source: 3-Tokens/token-info.mjs + doc: tokens/retrieve-token-info.md + block_id: + caption: token-info.mjs + + - source: 3-Tokens/token-mint.mjs + doc: tokens/mint-tokens.md + block_id: + caption: token-mint.mjs + + - source: 3-Tokens/token-burn.mjs + doc: tokens/burn-tokens.md + block_id: + caption: token-burn.mjs + + - source: 3-Tokens/token-transfer.mjs + doc: tokens/transfer-tokens-to-an-identity.md + block_id: + caption: token-transfer.mjs + # -- Example apps -- # DashMint Lab — React + TypeScript NFT app. Every SDK operation lives in From 7b004e1b18cf8548902fcf71bd4dcb3b6e146c34 Mon Sep 17 00:00:00 2001 From: thephez Date: Wed, 1 Jul 2026 15:43:33 -0400 Subject: [PATCH 7/8] docs(reference): sync DAPI endpoint and query reference to v4.0 testnet (#155) * docs(reference): correct query orderBy rules and range/in examples Reword the orderBy modifier to describe sorting by a consecutive trailing run of an index's properties instead of "the last indexed property", which denied valid multi-field orderBy. Add the required orderBy to the Range and in examples so they execute (a terminal range-classified clause requires a matching orderBy), and note that in is treated as a range. Reframe the "range only after == and in" tip as an index-position rule that permits a standalone range. Co-Authored-By: Claude Opus 4.8 (1M context) * docs(reference): sync DAPI endpoint docs to v4.0 proto Remove the four orphaned nullifier-changes endpoints (getNullifiersTrunkState, getNullifiersBranchState, getRecentNullifierChanges, getRecentCompactedNullifierChanges) from the detail and overview pages, matching their removal from the proto. Document getShieldedNotesCount and getDocumentHistory, the latter with a real testnet gRPCurl example and response. Correct getIdentityKeys (identity_id name/type, key-based limit/offset), getIdentitiesContractKeys contract_id, getDataContractHistory optional fields, getProtocolVersionUpgradeVoteStatus start_pro_tx_hash, and the protocol-version-upgrade prove descriptions. Add the burn_from_id field and update_price token event to getGroupActions, the tokenContractPosition field to getTokenContractInfo, and the last_claim oneof note to getTokenPerpetualDistributionLastClaim. Drop the stray base64 comment from the getEpochsInfo example, the nonexistent version parameter and proof claim from getCurrentQuorumsInfo, and the orphaned asterisk on send_transaction_hashes. Co-Authored-By: Claude Opus 4.8 * docs(reference): add testnet examples for shielded endpoints Add gRPCurl request and response examples to the six Shielded Transaction endpoints (getShieldedEncryptedNotes, getShieldedAnchors, getMostRecentShieldedAnchor, getShieldedPoolState, getShieldedNotesCount, getShieldedNullifiers), captured from a live testnet seed node. Remove the admonition stating these endpoints are not yet available on public nodes, since v4 now serves them on testnet. Note that getShieldedNullifiers omits is_spent for unspent nullifiers. Co-Authored-By: Claude Opus 4.8 * docs(protocol-ref): fix shielded endpoint cross-references Remove the four removed nullifier-changes endpoints from the shielded query list, which produced broken myst.xref links, and add getShieldedNotesCount. Reword the intro from "sync incremental nullifier updates" to "track shielded sync progress". Co-Authored-By: Claude Opus 4.8 --------- Co-authored-by: Claude Opus 4.8 (1M context) --- docs/protocol-ref/shielded-pool.md | 7 +- .../dapi-endpoints-core-grpc-endpoints.md | 2 +- .../dapi-endpoints-platform-endpoints.md | 433 +++++++++++++++--- docs/reference/dapi-endpoints.md | 5 +- docs/reference/query-syntax.md | 14 +- 5 files changed, 380 insertions(+), 81 deletions(-) diff --git a/docs/protocol-ref/shielded-pool.md b/docs/protocol-ref/shielded-pool.md index 6279b9de5..c4b10cfa3 100644 --- a/docs/protocol-ref/shielded-pool.md +++ b/docs/protocol-ref/shielded-pool.md @@ -200,14 +200,11 @@ Shielded Transfer, Unshield, and Shielded Withdrawal have no transparent signatu ## Querying shielded state -DAPI exposes a set of read-only endpoints for clients that need to fetch anchors, scan encrypted notes, verify nullifier status, or sync incremental nullifier updates. See the [DAPI Platform endpoints reference](../reference/dapi-endpoints-platform-endpoints.md) for request and response shapes: +DAPI exposes a set of read-only endpoints for clients that need to fetch anchors, scan encrypted notes, verify nullifier status, or track shielded sync progress. See the [DAPI Platform endpoints reference](../reference/dapi-endpoints-platform-endpoints.md) for request and response shapes: - [`getShieldedPoolState`](../reference/dapi-endpoints-platform-endpoints.md#getshieldedpoolstate) - [`getShieldedAnchors`](../reference/dapi-endpoints-platform-endpoints.md#getshieldedanchors) - [`getMostRecentShieldedAnchor`](../reference/dapi-endpoints-platform-endpoints.md#getmostrecentshieldedanchor) - [`getShieldedEncryptedNotes`](../reference/dapi-endpoints-platform-endpoints.md#getshieldedencryptednotes) +- [`getShieldedNotesCount`](../reference/dapi-endpoints-platform-endpoints.md#getshieldednotescount) - [`getShieldedNullifiers`](../reference/dapi-endpoints-platform-endpoints.md#getshieldednullifiers) -- [`getNullifiersTrunkState`](../reference/dapi-endpoints-platform-endpoints.md#getnullifierstrunkstate) -- [`getNullifiersBranchState`](../reference/dapi-endpoints-platform-endpoints.md#getnullifiersbranchstate) -- [`getRecentNullifierChanges`](../reference/dapi-endpoints-platform-endpoints.md#getrecentnullifierchanges) -- [`getRecentCompactedNullifierChanges`](../reference/dapi-endpoints-platform-endpoints.md#getrecentcompactednullifierchanges) diff --git a/docs/reference/dapi-endpoints-core-grpc-endpoints.md b/docs/reference/dapi-endpoints-core-grpc-endpoints.md index 6a8798bbe..89ae2dcfd 100644 --- a/docs/reference/dapi-endpoints-core-grpc-endpoints.md +++ b/docs/reference/dapi-endpoints-core-grpc-endpoints.md @@ -498,7 +498,7 @@ the update messages following a new block. | `from_block_height` | Integer | No | Return records beginning with the block height provided | | ---------- | | | | | `count` | Integer | No | Number of blocks to sync. If set to 0, syncing continuously sends new data as well (default: 0) | -| `send_transaction_hashes` \* | Boolean | No | | +| `send_transaction_hashes` | Boolean | No | When `true`, includes transaction hashes in the response stream | **Example Request and Response** diff --git a/docs/reference/dapi-endpoints-platform-endpoints.md b/docs/reference/dapi-endpoints-platform-endpoints.md index d0a985791..d0bb66622 100644 --- a/docs/reference/dapi-endpoints-platform-endpoints.md +++ b/docs/reference/dapi-endpoints-platform-endpoints.md @@ -826,9 +826,9 @@ grpcurl -proto protos/platform/v0/platform.proto \ | Name | Type | Required | Description | | ------- | -------- | -------- | ---------------------------------------- | | `id` | Bytes | Yes | A data contract `id` | -| `start_at_ms` | Integer | Yes | Request revisions starting at this timestamp | -| `limit` | Integer | Yes | The maximum number of revisions to return | -| `offset` | Integer | Yes | The offset of the first revision to return | +| `start_at_ms` | Integer | No | Request revisions starting at this timestamp | +| `limit` | Integer | No | The maximum number of revisions to return | +| `offset` | Integer | No | The offset of the first revision to return | | `prove` | Boolean | No | Set to `true` to receive a proof that contains the requested data contract. The data requested will be encoded as part of the proof in the response.| **Example Request and Response** @@ -1386,6 +1386,78 @@ grpcurl -proto protos/platform/v0/platform.proto \ Client computes `avg = 215 / 50 = 4.3`. +### getDocumentHistory + +**Returns**: The revision history for a single document on a contract that keeps document history +**Parameters**: + +| Name | Type | Required | Description | +| ---- | ---- | -------- | ----------- | +| `data_contract_id` | Bytes | Yes | A data contract `id` | +| `document_type_name` | String | Yes | A document type defined by the data contract | +| `document_id` | Bytes | Yes | The `id` of the document whose history is requested | +| `limit` | Integer | No | The maximum number of history entries to return | +| `offset` | Integer | No | The offset for pagination through the document history | +| `start_at_ms` | Integer | No | Only return results starting at this time in milliseconds | +| `prove` | Boolean | No | Set to `true` to receive a proof that contains the requested document history. The data requested will be encoded as part of the proof in the response.| + +**Example Request** + +::::{tab-set} +:::{tab-item} gRPCurl +:sync: grpcurl +```shell +# `data_contract_id` and `document_id` must be represented in base64 +grpcurl -proto protos/platform/v0/platform.proto \ + -d '{ + "v0": { + "data_contract_id": "nfpmJoj9R+rFTYLo/ddAuhHA4Si2YlK6BAAvEGmUIdo=", + "document_type_name": "review", + "document_id": "wZiWoQCwYKPVjAZ8NDXpbSMb7IEh++hGXzB38niWrIg=", + "limit": 2, + "offset": 0, + "start_at_ms": 0, + "prove": false + } + }' \ + seed-1.testnet.networks.dash.org:1443 \ + org.dash.platform.dapi.v0.Platform/getDocumentHistory +``` +::: +:::: + +::::{tab-set} +:::{tab-item} Response (gRPCurl) +:sync: grpcurl +```json +{ + "v0": { + "documentHistory": { + "documentEntries": [ + { + "date": "1782423220252", + "value": "AsGYlqEAsGCj1YwGfDQ16W0jG+yBIfvoRl8wd/J4lqyIM1bHElsMayy0ZD9WkprWAf6lYDIwqyC8dsdzc++MmRsBAAMAAAGfALPwHAAAAZ8As/AcCGRhc2hub3RlBQEuV2Fsa3Rocm91Z2ggcmV2aWV3IGNyZWF0ZSAyMDI2LTA2LTI1VDIxOjMzOjM1Wg==" + }, + { + "date": "1782423230374", + "value": "AsGYlqEAsGCj1YwGfDQ16W0jG+yBIfvoRl8wd/J4lqyIM1bHElsMayy0ZD9WkprWAf6lYDIwqyC8dsdzc++MmRsCAAMAAAGfALPwHAAAAZ8AtBemCGRhc2hub3RlBQEsV2Fsa3Rocm91Z2ggcmV2aWV3IGVkaXQgMjAyNi0wNi0yNVQyMTozMzo0NVo=" + } + ] + }, + "metadata": { + "height": "375045", + "coreChainLockedHeight": 1506013, + "epoch": 17082, + "timeMs": "1782851061688", + "protocolVersion": 12, + "chainId": "dash-testnet-51" + } + } +} +``` +::: +:::: + ## Identity Endpoints ### getIdentity @@ -1846,10 +1918,10 @@ Current identity contract nonce: 0 | Name | Type | Required | Description | | ------- | ------- | -------- | ------------ | -| `identity_td` | String | Yes | An identity ID
    Note: masternode IDs are created uniquely as described in the [masternode identity IDs section](#masternode-identity-ids) +| `identity_id` | Bytes | Yes | An identity ID
    Note: masternode IDs are created uniquely as described in the [masternode identity IDs section](#masternode-identity-ids) | `request_type` | [KeyRequestType](#request-types) | Yes | Request all keys (`all_keys`), specific keys (`specific_keys`), search for keys (`search_key`) -| `limit` | Integer | Yes | The maximum number of revisions to return | -| `offset` | Integer | Yes | The offset of the first revision to return | +| `limit` | Integer | No | The maximum number of keys to return | +| `offset` | Integer | No | The offset for pagination through the keys | | `prove` | Boolean | No | Set to `true` to receive a proof that contains the requested identity #### Request Types @@ -2151,7 +2223,7 @@ grpcurl -proto protos/platform/v0/platform.proto \ | Name | Type | Required | Description | |----------------------|-------------------------|----------|-------------| | `identities_ids` | Array | Yes | An array of identity IDs
    Note: masternode IDs are created uniquely as described in the [masternode identity IDs section](#masternode-identity-ids) | -| `contract_id` | String | Yes | The ID of the contract | +| `contract_id` | Bytes | Yes | The ID of the contract | | `document_type_name` | String | No | Name of the document type | | `purposes` | Array of [KeyPurpose](#key-purposes) | No | Array of purposes for which keys are requested | | `prove` | Boolean | No | Set to `true` to receive a proof that contains the requested identity keys | @@ -2404,6 +2476,7 @@ Retrieves a list of actions performed by a specific group within a contract. | | `destroy_frozen_funds` | Destroys frozen funds for a specified entity. | | | `emergency_action` | Performs emergency actions like pausing or resuming the contract. | | | `token_config_update` | Updates token configuration settings. | +| | `update_price` | Updates the token's direct purchase price (fixed or tiered). | | **DocumentEvent** | `create` | Represents the creation of a document. | | **ContractEvent** | `update` | Represents updates to a contract. | @@ -2433,6 +2506,7 @@ Retrieves a list of actions performed by a specific group within a contract. | | `recipient_id` | Bytes | Identity ID of the recipient. | | | `public_note` | String (Optional) | A public note for the mint event. | | `burn` | `amount` | UInt64 | Amount of tokens to burn. | +| | `burn_from_id` | Bytes | Identity ID the tokens are burned from. | | | `public_note` | String (Optional) | A public note for the burn event. | | `freeze` | `frozen_id` | Bytes | Identifier of the entity being frozen. | | | `public_note` | String (Optional) | A public note for the freeze event. | @@ -2443,8 +2517,11 @@ Retrieves a list of actions performed by a specific group within a contract. | | `public_note` | String (Optional) | A public note for the destruction event. | | `emergency_action` | `action_type` | Enum (`PAUSE = 0`, `RESUME = 1`) | Type of emergency action performed. | | | `public_note` | String (Optional) | A public note for the emergency action. | -| `token_config_update` | `token_config_update_item` | Bytes | Configuration update details. | +| `token_config_update` | `token_config_`
    `update_item` | Bytes | Configuration update details. | | | `public_note` | String (Optional) | A public note for the configuration update. | +| `update_price` | `fixed_price` | UInt64 | Fixed direct purchase price (present when a fixed price is set). | +| | `variable_price` | Object | Tiered pricing schedule (`price_for_quantity` array of `{quantity, price}`), present when tiered pricing is set. | +| | `public_note` | String (Optional) | A public note for the price update event. | **Example Request and Response** @@ -2695,13 +2772,11 @@ grpcurl -proto protos/platform/v0/platform.proto \ Retrieves current quorum details, including validator sets and metadata for each quorum. **Returns**: Information about current quorums, including quorum hashes, validator sets, and -cryptographic proof. +the last block proposer. **Parameters**: -| Name | Type | Required | Description | -| ------------- | ------ | -------- | ----------- | -| `version` | Object | No | Version object containing request parameters | +This endpoint does not require any parameters. **Example Request and Response** @@ -2908,7 +2983,6 @@ grpcurl -proto protos/platform/v0/platform.proto \ :::{tab-item} gRPCurl :sync: grpcurl ```shell -# `id` must be represented in base64 grpcurl -proto protos/platform/v0/platform.proto \ -d '{ "v0": { @@ -3232,7 +3306,7 @@ grpcurl -proto protos/platform/v0/platform.proto \ | Name | Type | Required | Description | | ------- | ------- | -------- | ------------ | -| `prove` | Boolean | No | Set to `true` to receive a proof that contains the requested identity +| `prove` | Boolean | No | Set to `true` to receive a proof that contains the requested protocol version state **Example Request and Response** @@ -3286,9 +3360,9 @@ grpcurl -proto protos/platform/v0/platform.proto \ | Name | Type | Required | Description | | ------- | ------- | -------- | ------------ | -| `start_pro_tx_hash` | String | No | Protx hash of an evonode +| `start_pro_tx_hash` | Bytes | No | Protx hash of an evonode | `count` | Integer | No | Number of records to request -| `prove` | Boolean | No | Set to `true` to receive a proof that contains the requested identity +| `prove` | Boolean | No | Set to `true` to receive a proof that contains the requested protocol version vote status **Example Request and Response** @@ -3767,7 +3841,8 @@ grpcurl -proto protos/platform/v0/platform.proto \ { "v0": { "data": { - "contractId": "L+2jKoiBdmhzIAg82a3nnOn8/K5sQiaIW/Tinw0ypNM=" + "contractId": "L+2jKoiBdmhzIAg82a3nnOn8/K5sQiaIW/Tinw0ypNM=", + "tokenContractPosition": 0 }, "metadata": { "height": "157984", @@ -3895,6 +3970,8 @@ Retrieves the last-claim timestamp for a token’s perpetual distribution for a **Returns**: A timestamp indicating the last successful claim, or a cryptographic proof. +The returned `last_claim` value takes one of several forms depending on the token’s distribution interval: `timestamp_ms` (milliseconds since epoch), `block_height`, `epoch`, or `raw_bytes`. + **Parameters**: | Name | Type | Required | Description | @@ -4505,10 +4582,6 @@ grpcurl -proto protos/platform/v0/platform.proto \ :::{versionadded} 3.1.0 ::: -:::{attention} -These endpoints are defined in the protocol but are not yet available on public nodes. -::: - ### getShieldedEncryptedNotes Returns encrypted notes from the shielded pool for a specified range. Clients use these notes for trial decryption to identify notes belonging to their viewing key. @@ -4523,6 +4596,62 @@ Returns encrypted notes from the shielded pool for a specified range. Clients us | `count` | Integer | Yes | The number of notes to retrieve | | `prove` | Boolean | No | Set to `true` to receive a proof that contains the requested notes | +**Example Request and Response** + +::::{tab-set} +:::{tab-item} gRPCurl +:sync: grpcurl +```shell +grpcurl -proto protos/platform/v0/platform.proto \ + -d '{ + "v0": { + "start_index": 0, + "count": 2, + "prove": false + } + }' \ + seed-1.testnet.networks.dash.org:1443 \ + org.dash.platform.dapi.v0.Platform/getShieldedEncryptedNotes +``` +::: +:::: + +::::{tab-set} +:::{tab-item} Response (gRPCurl) +:sync: grpcurl +```json +{ + "v0": { + "encryptedNotes": { + "entries": [ + { + "nullifier": "ACLc9k5HtKNM//KyTT/iWa+MIA8f1Ya3HDIsURjUYRc=", + "cmx": "ecV1F/WDoBa8CfL2Fwdlq3gcBrrZqnvgI+NwtsJZ6Ss=", + "encryptedNote": "WhToIlQhpze9cE45wNRsmxukpDPVOQ5k2Ws5FW2WYIjJiNctiIDc0CvGIKA49tJu8Z0lwjhp8RTUPmLdGShZgSTIp7W/dO2emMRUtPxb1TWUVU8EYd1lBnIXOATGmuV35oUQbt94GeX2PLp5rEOmm0o5rtgqiDyJ305AiLRSwZeOPPRrFrly/XQX90nacrqVBVg7vNvLlTKQazFPAcyjG1O/DpYh82W4jzXWakCn5XQYnMkRHv/u+YxK87viIG5C6XLpxOkxBgeONeYFBBGz8YlTnCnOBIkp", + "cvNet": "3Z5DAoE4aC3roM3Qh4U+wuCndC1WiASsxer1oSIMIIY=" + }, + { + "nullifier": "5ShcfdX68dfTfdZZ4nAXwfooPvd+1XHLXFP4D5hUzS4=", + "cmx": "CEa3w+gR7bMftk6XcIA1/1JT27UqxZYGmfO7gP7fWwg=", + "encryptedNote": "JzRWtHVnO5x4Ijn4M2URM4ojlY9W9mPV2Qz/Rz2TeA6hz5s63bYlTzy/eAQuJStsjCYQwq5H9OtN/EqFov/f1CqtwRTEWnro/3H+QAwMW+hYW982lBNImsPZhLk533fG2f0QD3yuu+BQXAryxNg4jHFBb70wEDF+m9ZklhNH5Bdyl0KoTXjEZqL2mUcY6zcb5gjU6DkozwNOFuiVjMCRVjzRdwUVNLNQhZqqLFIeWUCo37GZbN8oC6p24Lb9phnYNu53Km2d4c74nLdOVdSMeAzTIjle+woH", + "cvNet": "TuY3Si9ojWn1BbX4oHLQ+ZDZ/eFlHpMNV5vh3rzd+jU=" + } + ] + }, + "metadata": { + "height": "375055", + "coreChainLockedHeight": 1506025, + "epoch": 17083, + "timeMs": "1782852695259", + "protocolVersion": 12, + "chainId": "dash-testnet-51" + } + } +} +``` +::: +:::: + ### getShieldedAnchors Returns all commitment tree anchors for the shielded pool. Anchors are used by shielded transaction provers to reference a valid state of the commitment tree. @@ -4535,6 +4664,51 @@ Returns all commitment tree anchors for the shielded pool. Anchors are used by s |---------|---------|----------|-------------| | `prove` | Boolean | No | Set to `true` to receive a proof that contains the requested anchors | +**Example Request and Response** + +::::{tab-set} +:::{tab-item} gRPCurl +:sync: grpcurl +```shell +grpcurl -proto protos/platform/v0/platform.proto \ + -d '{ + "v0": { + "prove": false + } + }' \ + seed-1.testnet.networks.dash.org:1443 \ + org.dash.platform.dapi.v0.Platform/getShieldedAnchors +``` +::: +:::: + +::::{tab-set} +:::{tab-item} Response (gRPCurl) +:sync: grpcurl +```json +{ + "v0": { + "anchors": { + "anchors": [ + "Ahh3yHTlv9H1vhEGVFRbRquziIuG7is28el/VpCv7jk=", + "JeaJEco0ewcWxwIudW6TX/GQQQ+muiLIMwn8S3cbNw8=", + "Li/voQtJmL93TZfi/j3ht81uXY4TfPB2iPkRpfnfhhw=" + ] + }, + "metadata": { + "height": "375055", + "coreChainLockedHeight": 1506025, + "epoch": 17083, + "timeMs": "1782852695259", + "protocolVersion": 12, + "chainId": "dash-testnet-51" + } + } +} +``` +::: +:::: + ### getMostRecentShieldedAnchor Returns the most recent commitment tree anchor for the shielded pool. @@ -4547,6 +4721,45 @@ Returns the most recent commitment tree anchor for the shielded pool. |---------|---------|----------|-------------| | `prove` | Boolean | No | Set to `true` to receive a proof that contains the requested anchor | +**Example Request and Response** + +::::{tab-set} +:::{tab-item} gRPCurl +:sync: grpcurl +```shell +grpcurl -proto protos/platform/v0/platform.proto \ + -d '{ + "v0": { + "prove": false + } + }' \ + seed-1.testnet.networks.dash.org:1443 \ + org.dash.platform.dapi.v0.Platform/getMostRecentShieldedAnchor +``` +::: +:::: + +::::{tab-set} +:::{tab-item} Response (gRPCurl) +:sync: grpcurl +```json +{ + "v0": { + "anchor": "Li/voQtJmL93TZfi/j3ht81uXY4TfPB2iPkRpfnfhhw=", + "metadata": { + "height": "375055", + "coreChainLockedHeight": 1506025, + "epoch": 17083, + "timeMs": "1782852695259", + "protocolVersion": 12, + "chainId": "dash-testnet-51" + } + } +} +``` +::: +:::: + ### getShieldedPoolState Returns the total balance held in the shielded pool. @@ -4559,73 +4772,159 @@ Returns the total balance held in the shielded pool. |---------|---------|----------|-------------| | `prove` | Boolean | No | Set to `true` to receive a proof that contains the requested pool state | -### getShieldedNullifiers - -Returns the spent status of specified nullifiers. Clients use this to determine whether notes have already been spent. - -**Returns**: A list of nullifier statuses or a cryptographic proof. +**Example Request and Response** -**Parameters**: +::::{tab-set} +:::{tab-item} gRPCurl +:sync: grpcurl +```shell +grpcurl -proto protos/platform/v0/platform.proto \ + -d '{ + "v0": { + "prove": false + } + }' \ + seed-1.testnet.networks.dash.org:1443 \ + org.dash.platform.dapi.v0.Platform/getShieldedPoolState +``` +::: +:::: -| Name | Type | Required | Description | -|--------------|----------------|----------|-------------| -| `nullifiers` | Array of Bytes | Yes | The nullifiers to query (each 32 bytes) | -| `prove` | Boolean | No | Set to `true` to receive a proof that contains the requested nullifier statuses | +::::{tab-set} +:::{tab-item} Response (gRPCurl) +:sync: grpcurl +```json +{ + "v0": { + "totalBalance": "1831893452700", + "metadata": { + "height": "375055", + "coreChainLockedHeight": 1506025, + "epoch": 17083, + "timeMs": "1782852695259", + "protocolVersion": 12, + "chainId": "dash-testnet-51" + } + } +} +``` +::: +:::: -### getNullifiersTrunkState +### getShieldedNotesCount -Returns a cryptographic proof of the trunk state of a nullifier tree. Used with `getNullifiersBranchState` to perform incremental sync of nullifier sets. +Returns the count of leaves in the shielded notes commitment tree. Wallets use this at the start of a shielded sync to seed a determinate progress indicator. -**Returns**: A cryptographic proof of the nullifier tree trunk state. +**Returns**: The total shielded notes count or a cryptographic proof. **Parameters**: -| Name | Type | Required | Description | -|-------------------|---------|----------|-------------| -| `pool_type` | Integer | Yes | The shielded pool type: `0` = credit pool, `1` = main token pool, `2` = individual token pool | -| `pool_identifier` | Bytes | No | 32-byte token identifier; required when `pool_type` is `2` | - -### getNullifiersBranchState - -Returns a Merkle proof for a branch of the nullifier tree. Use `checkpoint_height` from the metadata of a `getNullifiersTrunkState` response to ensure consistency. +| Name | Type | Required | Description | +|---------|---------|----------|-------------| +| `prove` | Boolean | No | Set to `true` to receive a proof that contains the requested count | -**Returns**: A Merkle proof for the specified branch. +**Example Request and Response** -**Parameters**: +::::{tab-set} +:::{tab-item} gRPCurl +:sync: grpcurl +```shell +grpcurl -proto protos/platform/v0/platform.proto \ + -d '{ + "v0": { + "prove": false + } + }' \ + seed-1.testnet.networks.dash.org:1443 \ + org.dash.platform.dapi.v0.Platform/getShieldedNotesCount +``` +::: +:::: -| Name | Type | Required | Description | -|---------------------|---------|----------|-------------| -| `pool_type` | Integer | Yes | The shielded pool type: `0` = credit pool, `1` = main token pool, `2` = individual token pool | -| `pool_identifier` | Bytes | No | 32-byte token identifier; required when `pool_type` is `2` | -| `key` | Bytes | Yes | The branch key to query | -| `depth` | Integer | Yes | The depth of the branch | -| `checkpoint_height` | Integer | Yes | Block height from a `getNullifiersTrunkState` response metadata, for consistency | +::::{tab-set} +:::{tab-item} Response (gRPCurl) +:sync: grpcurl +```json +{ + "v0": { + "totalNotesCount": "622", + "metadata": { + "height": "375055", + "coreChainLockedHeight": 1506025, + "epoch": 17083, + "timeMs": "1782852695259", + "protocolVersion": 12, + "chainId": "dash-testnet-51" + } + } +} +``` +::: +:::: -### getRecentNullifierChanges +### getShieldedNullifiers -Returns nullifier additions starting from a specified block height, indicating which notes were spent per block. +Returns the spent status of specified nullifiers. Clients use this to determine whether notes have already been spent. -**Returns**: A list of nullifier additions grouped by block, or a cryptographic proof. +**Returns**: A list of nullifier statuses or a cryptographic proof. **Parameters**: -| Name | Type | Required | Description | -|----------------|---------|----------|-------------| -| `start_height` | String (uint64) | Yes | Block height to start from (as a string due to uint64 size) | -| `prove` | Boolean | No | Set to `true` to receive a proof that contains the requested changes | - -### getRecentCompactedNullifierChanges +| Name | Type | Required | Description | +|--------------|----------------|----------|-------------| +| `nullifiers` | Array of Bytes | Yes | The nullifiers to query (each 32 bytes) | +| `prove` | Boolean | No | Set to `true` to receive a proof that contains the requested nullifier statuses | -Returns compacted nullifier additions from a specified block height. Compacted changes merge multiple blocks into ranges, reducing response size for bulk sync. +**Example Request and Response** -**Returns**: A list of compacted nullifier additions grouped by block range, or a cryptographic proof. +::::{tab-set} +:::{tab-item} gRPCurl +:sync: grpcurl +```shell +# Each nullifier must be represented in base64 +grpcurl -proto protos/platform/v0/platform.proto \ + -d '{ + "v0": { + "nullifiers": [ + "ACLc9k5HtKNM//KyTT/iWa+MIA8f1Ya3HDIsURjUYRc=" + ], + "prove": false + } + }' \ + seed-1.testnet.networks.dash.org:1443 \ + org.dash.platform.dapi.v0.Platform/getShieldedNullifiers +``` +::: +:::: -**Parameters**: +::::{tab-set} +:::{tab-item} Response (gRPCurl) +:sync: grpcurl +```json +{ + "v0": { + "nullifierStatuses": { + "entries": [ + { + "nullifier": "ACLc9k5HtKNM//KyTT/iWa+MIA8f1Ya3HDIsURjUYRc=" + } + ] + }, + "metadata": { + "height": "375055", + "coreChainLockedHeight": 1506025, + "epoch": 17083, + "timeMs": "1782852695259", + "protocolVersion": 12, + "chainId": "dash-testnet-51" + } + } +} +``` +::: +:::: -| Name | Type | Required | Description | -|----------------------|---------|----------|-------------| -| `start_block_height` | String (uint64) | Yes | Block height to start from (as a string due to uint64 size) | -| `prove` | Boolean | No | Set to `true` to receive a proof that contains the requested changes | +A nullifier's `is_spent` field is omitted from the response when `false` (proto3 default), so an entry without `is_spent` indicates the nullifier has not been spent. ## Code Reference diff --git a/docs/reference/dapi-endpoints.md b/docs/reference/dapi-endpoints.md index 5e1e87c41..252892e1a 100644 --- a/docs/reference/dapi-endpoints.md +++ b/docs/reference/dapi-endpoints.md @@ -135,11 +135,8 @@ Shielded Transaction endpoints are defined in the protocol but are not yet avail | [`getShieldedAnchors`](../reference/dapi-endpoints-platform-endpoints.md#getshieldedanchors) | Returns all commitment tree anchors for the shielded pool. | | [`getMostRecentShieldedAnchor`](../reference/dapi-endpoints-platform-endpoints.md#getmostrecentshieldedanchor) | Returns the most recent commitment tree anchor. | | [`getShieldedPoolState`](../reference/dapi-endpoints-platform-endpoints.md#getshieldedpoolstate) | Returns the total balance held in the shielded pool. | +| [`getShieldedNotesCount`](../reference/dapi-endpoints-platform-endpoints.md#getshieldednotescount) | Returns the count of leaves in the shielded notes commitment tree, used to seed shielded sync progress. | | [`getShieldedNullifiers`](../reference/dapi-endpoints-platform-endpoints.md#getshieldednullifiers) | Returns the spent status of specified nullifiers. | -| [`getNullifiersTrunkState`](../reference/dapi-endpoints-platform-endpoints.md#getnullifierstrunkstate) | Returns a proof of the trunk state of a nullifier tree. | -| [`getNullifiersBranchState`](../reference/dapi-endpoints-platform-endpoints.md#getnullifiersbranchstate) | Returns a Merkle proof for a branch of the nullifier tree. | -| [`getRecentNullifierChanges`](../reference/dapi-endpoints-platform-endpoints.md#getrecentnullifierchanges) | Returns recent nullifier additions starting from a specified block height. | -| [`getRecentCompactedNullifierChanges`](../reference/dapi-endpoints-platform-endpoints.md#getrecentcompactednullifierchanges) | Returns compacted nullifier additions from a specified block height. | ```{eval-rst} .. diff --git a/docs/reference/query-syntax.md b/docs/reference/query-syntax.md index c2859d12b..1832f4cc6 100644 --- a/docs/reference/query-syntax.md +++ b/docs/reference/query-syntax.md @@ -68,9 +68,9 @@ Valid fields consist of the indices defined for the document being queried. For :::{tip} - Only one range operator is allowed in a query. `Between` and its variants are single operators that replace a `>=`/`<=` pair — the engine also normalizes two range operators on the same field into the equivalent `Between*` form automatically - The `in` operator is only allowed for last two indexed properties -- Range operators are only allowed after `==` and `in` operators +- Range operators apply to an indexed field that follows any `==` and `in` clauses in the index. A standalone range (with no preceding `==`/`in` clause) is valid when a matching index exists - Range operators are only allowed for the last two fields used in the where condition -- Queries using range operators must also include an `orderBy` statement +- Queries using range operators (including `in`, which is treated as a range) must also include an `orderBy` statement ::: ### Evaluation Operators @@ -90,6 +90,9 @@ Valid fields consist of the indices defined for the document being queried. For where: [ ["nameHash", "<", "56116861626961756e6176657a382e64617368"], ], + orderBy: [ + ["nameHash", "asc"], + ], } ::: :::: @@ -121,7 +124,10 @@ Valid fields consist of the indices defined for the document being queried. For ["normalizedParentDomainName", "==", "dash"], // Return all matching names from the provided array ["normalizedLabel", "in", ["alice", "bob"]], - ] + ], + orderBy: [ + ["normalizedLabel", "asc"], + ] } ::: :::: @@ -152,7 +158,7 @@ The query modifiers described here determine how query results will be sorted an | Modifier | Effect | Example | | - | - | - | | `limit` | Restricts the number of results returned (maximum: 100) | `limit: 10` | -| `orderBy` | Returns records sorted by the field(s) provided. Sorting must be by the last indexed property. Can only be used with `>`, `<`, `>=`, `<=`, `Between`, `BetweenExcludeBounds`, `BetweenExcludeLeft`, `BetweenExcludeRight`, and `startsWith` queries. | `orderBy: [['normalizedLabel', 'asc']]` | +| `orderBy` | Returns records sorted by the field(s) provided. The `orderBy` fields must match a consecutive run of the index's properties, read from the end of the index (for a compound index, sort by one or more of its trailing fields). Can only be used with `>`, `<`, `>=`, `<=`, `Between`, `BetweenExcludeBounds`, `BetweenExcludeLeft`, `BetweenExcludeRight`, and `startsWith` queries. | `orderBy: [['normalizedLabel', 'asc']]` | | `startAt` | Returns records beginning with the document ID provided | `startAt: ''` | | `startAfter` | Returns records beginning after the document ID provided | `startAfter: ''` | | `offset` | Skips the first N matching results (available at the CBOR/DAPI layer; not exposed in the JS SDK) | `offset: 10` | From bcfef38d80d3f77d7e6ca10739ef19a512e2d399 Mon Sep 17 00:00:00 2001 From: thephez Date: Mon, 6 Jul 2026 13:59:50 -0400 Subject: [PATCH 8/8] docs: align reference, protocol, and resources docs with Platform v4.0.0 (#156) * docs(reference): update version annotations from 3.1.0 to 4.0.0 Dash Platform v4.0 was released (originally slated as 3.1). Update non-link versionadded/versionchanged directives and prose annotations to reflect the actual release version. Source-code links are left unchanged pending separate verification. Co-Authored-By: Claude Opus 4.8 (1M context) * docs(protocol-ref): migrate source links from v3.1-dev to v4.0.0 tag Migrate all dashpay/platform source-code links from the v3.1-dev branch ref to the immutable v4.0.0 release tag. Every file path was confirmed to exist at v4.0.0, and every line anchor was verified individually against the v4.0.0 source: line anchors that had drifted were corrected to point at the intended definition, and one moved file (shielded/mod.rs -> shielded/sighash.rs) was repathed. Link text and documented values are unchanged. Co-Authored-By: Claude Opus 4.8 (1M context) * docs(intro): list Tokens on testnet and clarify DAPI protocols Add a Tokens entry to the testnet feature list. Rework the DAPI overview so Platform application data is attributed to the gRPC endpoints and JSON-RPC is scoped to layer 1 (Dash Core) information, matching the DAPI explanation page. Co-Authored-By: Claude Opus 4.8 (1M context) * docs(explanations): correct token trade mode, data trigger, and source links Align docs/explanations with Dash Platform v4.0.0: - tokens: remove the nonexistent TradeableOnMarketplace trade mode; NotTradeable is the only defined value - data-trigger: withdrawal document has REPLACE/DELETE triggers only, not CREATE; note the binding list as the authoritative action-to-trigger map - document: repoint the removed documentBase.json link to src/document/fields.rs - data-contract: fix the DashPay schema link path and list all three document types Co-Authored-By: Claude Opus 4.8 (1M context) * docs: document shielded pool state transitions and the type 20 identity create Add the shielded pool transitions (types 15-20) enabled in Protocol Version 12 across the explanation and protocol reference docs: - state transition lists: add rows 15-20, linking each to its shielded-pool reference section - shielded-pool explanation: add the identity-create-from-shielded-pool exit path, name Halo 2 (no trusted setup) instead of zk-SNARK, and distinguish the 16-action consensus cap from the binding ~20 KiB size budget - shielded-pool reference: add the Identity Create From Shielded Pool section with its field table - state-transition reference: add type 20 to the payload-type table and the Shielded (Orchard) signing-method row Co-Authored-By: Claude Opus 4.8 (1M context) * docs(protocol-ref): correct reference against Platform v4.0.0 source Update the document meta-schema to v1, fix shielded-pool storage and signing details, correct token distribution and control-group fields, add missing basic error codes, and refresh signing security levels, version labels, and source links. Co-Authored-By: Claude Opus 4.8 (1M context) * docs(reference): correct data contract, glossary, and gRPC details for v4.0.0 Document the contract-level groups, keywords, and description fields and the document-level tokenCost option, add the v4.0.0 aggregate-query flags, and note that a contract may define documents and/or tokens. Fix the index property sort order to asc only (the meta-schema rejects desc) and correct the contested index element description, which duplicated the unique element's text. Generalize the glossary State Transition and Platform State definitions to cover the identity, token, transfer, withdrawal, and masternode voting operations tracked in v4.0.0. Rename the getTransaction response fields to isInstantLocked and isChainLocked to match the proto. Co-Authored-By: Claude Opus 4.8 * docs(resources): correct DPNS FAQ details against Platform v4.0.0 Fix contested-name resolution: ties and no-vote contests are resolved deterministically by the protocol (document creation order), not awarded to the first requester. Correct the contested-name length to 3-19 characters, drop the stale "v1" qualifier from the locked-names answer, fix the DashPay-section tip that mislabeled its links as DPNS, and point the JavaScript SDK link at the in-repo tutorial. Co-Authored-By: Claude Opus 4.8 (1M context) * docs(reference): rewrite platform proofs for GroveDB proof model Replace the obsolete pre-GroveDB proof documentation (rootTreeProof/storeTreeProof structure, five per-store proof types, Merk binary-format table, and the getStoreProofData parser) with the current v4.0.0 Proof message: a single grovedb_proof plus the quorum signature fields (quorumHash, signature, round, blockIdHash, quorumType). Add the page to the Reference toctree so it is no longer orphaned. Co-Authored-By: Claude Opus 4.8 (1M context) * docs(protocol-ref): apply CodeRabbit fixes for v4.0.0 review Point the document schema reference at the v1 meta-schema, clarify that shielded transitions omit only the identity-signed signature fields (Shield from Asset Lock still carries its asset-lock ECDSA signature), use the exact 20 KiB / 20,480-byte state-transition limit, and restore the leading pipe on the token price row. Also fix the Shield actions description to match source: actions are spend-output pairs, but Shield's value comes from transparent inputs so its actions create new notes rather than consuming prior pool notes. Co-Authored-By: Claude Opus 4.8 (1M context) * docs(reference): make platform proof example internally consistent Add the missing round field to the proof JSON example and use the camelCase grovedbProof name in the verification description to match the field table and the rest of the page. Co-Authored-By: Claude Opus 4.8 (1M context) --------- Co-authored-by: Claude Opus 4.8 (1M context) --- _templates/sidebar-main.html | 5 + .../platform-protocol-data-contract.md | 2 +- .../platform-protocol-data-trigger.md | 4 +- .../platform-protocol-document.md | 2 +- .../platform-protocol-state-transition.md | 6 + docs/explanations/shielded-pool.md | 12 +- docs/explanations/tokens.md | 11 +- docs/index.md | 1 + docs/intro/testnet.md | 1 + docs/intro/what-is-dash-platform.md | 2 +- docs/protocol-ref/address-system.md | 20 +- docs/protocol-ref/data-contract-document.md | 54 ++-- docs/protocol-ref/data-contract-token.md | 51 ++-- docs/protocol-ref/data-contract.md | 151 ++++++++-- docs/protocol-ref/data-trigger.md | 16 +- docs/protocol-ref/document.md | 28 +- docs/protocol-ref/errors.md | 8 +- docs/protocol-ref/identity.md | 32 +-- docs/protocol-ref/protocol-constants.md | 260 +++++++++--------- docs/protocol-ref/shielded-pool.md | 53 +++- docs/protocol-ref/state-transition.md | 59 ++-- docs/protocol-ref/token.md | 44 +-- .../dapi-endpoints-core-grpc-endpoints.md | 4 +- .../dapi-endpoints-platform-endpoints.md | 12 +- docs/reference/dapi-endpoints.md | 4 +- docs/reference/data-contracts.md | 33 ++- docs/reference/glossary.md | 4 +- docs/reference/platform-proofs.md | 166 +++-------- docs/reference/query-syntax.md | 2 +- docs/resources/faq.md | 16 +- 30 files changed, 588 insertions(+), 475 deletions(-) diff --git a/_templates/sidebar-main.html b/_templates/sidebar-main.html index 71eb257e9..254439a01 100644 --- a/_templates/sidebar-main.html +++ b/_templates/sidebar-main.html @@ -447,6 +447,11 @@
  • +
  • + + Platform Proofs + +
  • Query Syntax diff --git a/docs/explanations/platform-protocol-data-contract.md b/docs/explanations/platform-protocol-data-contract.md index fe7c03ba0..0d5ffb58f 100644 --- a/docs/explanations/platform-protocol-data-contract.md +++ b/docs/explanations/platform-protocol-data-contract.md @@ -75,7 +75,7 @@ For more detailed information, see the [Platform Protocol Reference - Data Contr ## Example Contract -The [DashPay contract](https://github.com/dashpay/platform/blob/master/packages/dashpay-contract/schema/dashpay.schema.json) is included below for reference. It defines a `contact` document and a `profile` document. Each of these documents then defines the properties and indices they require: +The [DashPay contract](https://github.com/dashpay/platform/blob/master/packages/dashpay-contract/schema/v1/dashpay.schema.json) is included below for reference. It defines a `contactRequest` document, a `profile` document, and a `contactInfo` document. Each of these documents then defines the properties and indices they require: :::{dropdown} DashPay contract ```json diff --git a/docs/explanations/platform-protocol-data-trigger.md b/docs/explanations/platform-protocol-data-trigger.md index b3ac7d9b2..69aaa37d7 100644 --- a/docs/explanations/platform-protocol-data-trigger.md +++ b/docs/explanations/platform-protocol-data-trigger.md @@ -18,6 +18,8 @@ Given a number of technical considerations (security, masternode processing capa Since all application data is submitted in the form of documents, data triggers are defined in the context of documents. To provide even more granularity, they also incorporate the document `action` so separate triggers can be created for the `CREATE`, `REPLACE`, or `DELETE` actions. +Which trigger runs for a given contract, document type, and action is defined in the data trigger [binding list](https://github.com/dashpay/platform/blob/master/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/bindings/list/v0/mod.rs). The trigger implementations linked in the tables below (for example the shared `reject` trigger) are generic and do not name the contracts that use them - the binding list is what associates each action with its trigger. + As an example, DPP contains several [data triggers for DPNS](https://github.com/dashpay/platform/tree/master/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/dpns). The `domain` document has added constraints for creation, replacing, deleting, transferring, purchasing, and updating prices: | Data Contract | Document | Action(s) | Trigger Description | @@ -40,6 +42,6 @@ In addition to DPNS, DPP ships data triggers for a small set of other system con | - | - | - | - | | DashPay | `contactRequest` | [`CREATE`](https://github.com/dashpay/platform/tree/master/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/dashpay) | Enforces DashPay-specific rules on outgoing contact requests | | ---- | ---- | ---- | ---- | -| Withdrawals | `withdrawal` | [`CREATE`/`REPLACE`/`DELETE`](https://github.com/dashpay/platform/tree/master/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/withdrawals) | Enforces withdrawal status transitions and prevents direct external mutation of withdrawal documents | +| Withdrawals | `withdrawal` | [`REPLACE`/`DELETE`](https://github.com/dashpay/platform/tree/master/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/withdrawals) | Enforces withdrawal status transitions and prevents direct external mutation of withdrawal documents | When document state transitions are received, DPP checks if there is a trigger associated with the document type and action. If a trigger is found, DPP executes the trigger logic. Successful execution of the trigger logic is necessary for the document to be accepted and applied to the [platform state](../explanations/drive-platform-state.md). diff --git a/docs/explanations/platform-protocol-document.md b/docs/explanations/platform-protocol-document.md index 27b9c6fb1..6485cb077 100644 --- a/docs/explanations/platform-protocol-document.md +++ b/docs/explanations/platform-protocol-document.md @@ -14,7 +14,7 @@ Documents are defined in an application's [Data Contract](../explanations/platfo ### Base Fields -Dash Platform Protocol (DPP) defines a set of base fields that must be present in all documents. For the [reference implementation](https://github.com/dashpay/platform/tree/master/packages/rs-dpp), the base fields shown below are defined in the [document base schema](https://github.com/dashpay/platform/blob/master/packages/rs-dpp/src/schema/document/v0/documentBase.json). +Dash Platform Protocol (DPP) defines a set of base fields that must be present in all documents. For the [reference implementation](https://github.com/dashpay/platform/tree/master/packages/rs-dpp), the base fields shown below are defined in the [document base fields](https://github.com/dashpay/platform/blob/master/packages/rs-dpp/src/document/fields.rs). | Field Name | Description | | - | - | diff --git a/docs/explanations/platform-protocol-state-transition.md b/docs/explanations/platform-protocol-state-transition.md index 46b2f4e2c..4885d98f8 100644 --- a/docs/explanations/platform-protocol-state-transition.md +++ b/docs/explanations/platform-protocol-state-transition.md @@ -51,6 +51,12 @@ The following table contains a list of currently defined payload types: | [Address Funds Transfer](../protocol-ref/address-system.md#address-funds-transfer) (`12`) | Transfer funds between Platform addresses | | [Address Funding From Asset Lock](../protocol-ref/address-system.md#address-funding-from-asset-lock) (`13`) | Fund a Platform address using an asset lock proof | | [Address Credit Withdrawal](../protocol-ref/address-system.md#address-credit-withdrawal) (`14`) | Withdraw credits from a Platform address | +| [Shield](../protocol-ref/shielded-pool.md#shield) (`15`) | Move transparent Platform funds into the [shielded pool](../explanations/shielded-pool.md) | +| [Shielded Transfer](../protocol-ref/shielded-pool.md#shielded-transfer) (`16`) | Transfer value privately between shielded notes | +| [Unshield](../protocol-ref/shielded-pool.md#unshield) (`17`) | Move funds from the shielded pool back to a Platform address | +| [Shield From Asset Lock](../protocol-ref/shielded-pool.md#shield-from-asset-lock) (`18`) | Fund the shielded pool directly from an asset lock proof | +| [Shielded Withdrawal](../protocol-ref/shielded-pool.md#shielded-withdrawal) (`19`) | Withdraw funds from the shielded pool to Dash Core (L1) | +| [Identity Create From Shielded Pool](../protocol-ref/shielded-pool.md#identity-create-from-shielded-pool) (`20`) | Create a new identity funded from the shielded pool | ### Application Usage diff --git a/docs/explanations/shielded-pool.md b/docs/explanations/shielded-pool.md index 489ec95dc..a4454ef06 100644 --- a/docs/explanations/shielded-pool.md +++ b/docs/explanations/shielded-pool.md @@ -6,9 +6,9 @@ ## 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 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, a shielded withdrawal, or by funding a newly created identity. 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. +The pool uses the [Orchard](https://zips.z.cash/protocol/protocol.pdf) shielded protocol — the same zero-knowledge design (Halo 2 proofs, with no trusted setup) 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 @@ -40,11 +40,11 @@ When a note is created for a recipient, the platform stores an **encrypted note ### 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. +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. The consensus rules cap a single shielded transition at **16 actions**. In practice the ~20 KiB (20,480-byte) state-transition size budget is the binding limit: because the Halo 2 proof grows with each action, a real transition fits only around 6 actions well before it reaches the 16-action cap. ## 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). +Six 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 @@ -66,6 +66,10 @@ Moves credits *out of* the pool to a [Platform address](../protocol-ref/address- 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. +### Identity create from shielded pool + +Creates a new identity funded directly from the pool by spending one or more notes. Like an unshield, this moves credits *out of* the pool — here into a freshly created identity rather than a Platform address. The new identity's ID is derived from the sorted set of spend nullifiers, making it unique and single-use. + ## 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. diff --git a/docs/explanations/tokens.md b/docs/explanations/tokens.md index 73f21af07..812dd6ec7 100644 --- a/docs/explanations/tokens.md +++ b/docs/explanations/tokens.md @@ -107,8 +107,8 @@ When creating a token, you define its configuration using the following paramete |:------------------------|:------------------|:--------| | Description | Yes | None | | [Conventions](#display-conventions) | Yes | N/A. Depends on implementation | -| [Decimal precision](#display-conventions)| Yes | [8](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/data_contract/associated_token/token_configuration_convention/v0/mod.rs#L46) | -| [Base supply](#token-supply) | **No** | [100000](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/mod.rs#L498) | +| [Decimal precision](#display-conventions)| Yes | [8](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/data_contract/associated_token/token_configuration_convention/v0/mod.rs#L47) | +| [Base supply](#token-supply) | **No** | [100000](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/mod.rs#L498) | | [Maximum supply](#token-supply) | Yes | None | | [Keep history](#history) | Yes | True (all history types) | | [Start paused](#initial-state) | Yes | False | @@ -290,9 +290,8 @@ When enabled, the authorized party can set the token price using a state transit ### Marketplace -Token contracts already expose marketplace rules in their configuration, which declares a trade mode that governs how tokens may be traded on Platform. The currently supported trade modes are: +Token contracts already expose marketplace rules in their configuration, which declares a trade mode that governs how tokens may be traded on Platform. The only trade mode currently defined is: -- **`NotTradeable`** - the token cannot be traded on Platform (default). -- **`TradeableOnMarketplace`** - the token is eligible for trading via Platform's marketplace mechanism. +- **`NotTradeable`** - the token cannot be traded on Platform. This is the default and, at present, the only available value. -The protocol-level marketplace rules are in place, but broader client tooling and user-facing marketplace experiences are expected to continue evolving in future releases. +A dedicated marketplace trade mode is reserved for a future release. The protocol-level marketplace rules exist to support this, but the trade mode itself, along with broader client tooling and user-facing marketplace experiences, is expected to continue evolving in future releases. diff --git a/docs/index.md b/docs/index.md index 875e97d6a..f0a3670d0 100644 --- a/docs/index.md +++ b/docs/index.md @@ -149,6 +149,7 @@ explanations/query reference/dapi-endpoints reference/query-syntax reference/data-contracts +reference/platform-proofs reference/glossary ``` diff --git a/docs/intro/testnet.md b/docs/intro/testnet.md index 368ce3948..fe41ae872 100644 --- a/docs/intro/testnet.md +++ b/docs/intro/testnet.md @@ -24,6 +24,7 @@ The Dash Platform features available on testnet include: - [Data Contracts](../explanations/platform-protocol-data-contract.md): creation of data contracts - [Documents](../explanations/platform-protocol-document.md): used to store/update/delete data associated with data contracts - [DashPay](../explanations/dashpay.md): a data contract enabling a decentralized application that creates bidirectional direct settlement payment channels between identities and supports contact (name) based payments +- [Tokens](../explanations/tokens.md): creation and management of tokens (similar to ERC-20 style assets) using data contracts, without writing smart contracts ## Getting involved diff --git a/docs/intro/what-is-dash-platform.md b/docs/intro/what-is-dash-platform.md index cfa9952cf..08629eb6e 100644 --- a/docs/intro/what-is-dash-platform.md +++ b/docs/intro/what-is-dash-platform.md @@ -61,7 +61,7 @@ verification, making it practical for light clients and user-facing applications ### DAPI - A decentralized API -DAPI is a _decentralized_ HTTP API exposing [JSON-RPC](https://www.jsonrpc.org/) and [gRPC](https://grpc.io/) endpoints. Through these endpoints, developers can send and retrieve application data and query the Dash blockchain. +DAPI is a _decentralized_ HTTP API exposing [gRPC](https://grpc.io/) and [JSON-RPC](https://www.jsonrpc.org/) endpoints. Developers send and retrieve Dash Platform application data over the gRPC endpoints, while the JSON-RPC endpoints expose some layer 1 (Dash Core blockchain) information. DAPI provides developers the same access and security as running their own Dash node without the cost and maintenance overhead. Unlike traditional APIs which have a single point of failure, DAPI allows clients to connect to different instances depending on resource availability in the Dash network. diff --git a/docs/protocol-ref/address-system.md b/docs/protocol-ref/address-system.md index cd078e609..c45056f93 100644 --- a/docs/protocol-ref/address-system.md +++ b/docs/protocol-ref/address-system.md @@ -5,7 +5,7 @@ # Platform Address System :::{attention} -Address-based state transitions were [enabled in Protocol Version 11](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-platform-version/src/version/feature_initial_protocol_versions.rs). These transitions enable direct operations using Platform addresses without requiring a pre-existing identity for some operations. +Address-based state transitions were [enabled in Protocol Version 11](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-platform-version/src/version/feature_initial_protocol_versions.rs). These transitions enable direct operations using Platform addresses without requiring a pre-existing identity for some operations. ::: ## Overview @@ -38,7 +38,7 @@ Platform addresses are derived from standard Bitcoin/Dash address formats and en A `PlatformAddress` has two distinct byte encodings depending on context. The type bytes above (`0xb0` / `0x80`) apply to the user-facing bech32m encoding — what appears in address strings like `dash1k...`. Internal GroveDB storage keys use bincode variant indices `0x00` / `0x01` instead. Decoding one through the other's code path will fail. ::: -See the [Platform address implementation in rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/address_funds/platform_address.rs). +See the [Platform address implementation in rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/address_funds/platform_address.rs). ### Address Witness @@ -63,7 +63,7 @@ Witnesses provide cryptographic proof of address ownership. Each input in an add 3. Double-SHA256 hash the signable bytes (reused for all signatures) 4. Match M signatures to N public keys in order -See the [witness implementation in rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/address_funds/witness.rs). +See the [witness implementation in rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/address_funds/witness.rs). ### Fee Strategy @@ -78,7 +78,7 @@ The fee strategy specifies how transaction fees are deducted from inputs or outp Fee strategy cannot be empty. Maximum steps: 4 (`max_address_fee_strategies`). No duplicate steps allowed. Steps are processed in sequence until the fee is fully covered. ::: -See the [fee strategy implementation in rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/address_funds/fee_strategy/mod.rs). +See the [fee strategy implementation in rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/address_funds/fee_strategy/mod.rs). ### Common Type Aliases @@ -107,7 +107,7 @@ Transfer credits from an existing identity to one or more Platform addresses. Minimum recipients: 1. Maximum recipients: `max_address_outputs`. Minimum per recipient: 500,000 credits. Fee: 500,000 credits base + 6,000,000 credits per recipient (example: 1 recipient = 6,500,000 credits minimum fee). ::: -See the [implementation in rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_transfer_to_addresses_transition/). +See the [implementation in rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_transfer_to_addresses_transition/). ### Identity Create from Addresses @@ -128,7 +128,7 @@ Create a new identity funded from Platform address balances. **Cost:** Base cost 2,000,000 + 6,500,000 per key. Example: 2 keys = 15,000,000 credits. ::: -See the [implementation in rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_create_from_addresses_transition/). +See the [implementation in rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_create_from_addresses_transition/). ### Identity Top-Up from Addresses @@ -149,7 +149,7 @@ Add credits to an existing identity from Platform address balances. **Fee:** Base top-up cost: 500,000 credits. ::: -See the [implementation in rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_topup_from_addresses_transition/). +See the [implementation in rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_topup_from_addresses_transition/). ### Address Funds Transfer @@ -173,7 +173,7 @@ Unlike other address transitions, fund transfers enforce strict balance preserva **Fee:** 500,000 credits per input + 6,000,000 credits per output. ::: -See the [implementation in rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/state_transition/state_transitions/address_funds/address_funds_transfer_transition/). +See the [implementation in rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/state_transition/state_transitions/address_funds/address_funds_transfer_transition/). ### Address Funding from Asset Lock @@ -199,7 +199,7 @@ Exactly one output must have a `None` value. This remainder output receives what **Constraints:** Minimum outputs: 1. Maximum inputs: `max_address_inputs`. Maximum outputs: `max_address_outputs`. Minimum per input: 100,000 credits. Minimum per explicit output: 500,000 credits. No output can also be an input. ::: -See the [implementation in rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/state_transition/state_transitions/address_funds/address_funding_from_asset_lock_transition/). +See the [implementation in rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/state_transition/state_transitions/address_funds/address_funding_from_asset_lock_transition/). ### Address Credit Withdrawal @@ -222,7 +222,7 @@ Withdraw credits from Platform addresses back to the Core chain. **Fee:** 400,000,000 credits. Withdrawal fees are significantly higher due to the complexity and finality of moving funds back to the Core chain. ::: -See the [implementation in rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/state_transition/state_transitions/address_funds/address_credit_withdrawal_transition/). +See the [implementation in rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/state_transition/state_transitions/address_funds/address_credit_withdrawal_transition/). ### Address State Transition Signing diff --git a/docs/protocol-ref/data-contract-document.md b/docs/protocol-ref/data-contract-document.md index 6aca6f486..c0df7bc76 100644 --- a/docs/protocol-ref/data-contract-document.md +++ b/docs/protocol-ref/data-contract-document.md @@ -5,7 +5,7 @@ The `documents` object defines each type of document in the data contract. At a minimum, a document must consist of 1 or more properties. The `additionalProperties` properties keyword must be included as described in the [constraints](./data-contract.md#additional-properties) section and each property must be [assigned a position](#assigning-position). :::{note} -The `$schema` property is required for each document type but is automatically injected by the platform during [contract enrichment](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/data_contract/document_type/schema/enrich_with_base_schema/v0/mod.rs). Do not include it in user-submitted document type definitions — providing it will result in a validation error. +The `$schema` property is required for each document type but is automatically injected by the platform during [contract enrichment](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/data_contract/document_type/schema/enrich_with_base_schema/v0/mod.rs). Do not include it in user-submitted document type definitions — providing it will result in a validation error. ::: The following example shows a minimal `documents` object defining a single document (`note`) with one property (`message`). @@ -121,10 +121,10 @@ There are a variety of constraints currently defined for performance and securit | Description | Value | | ----------- | ----- | -| Minimum number of properties | [1](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/schema/meta_schemas/document/v0/document-meta.json#L22) | -| Maximum number of properties | [100](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/schema/meta_schemas/document/v0/document-meta.json#L23) | -| Minimum property name length | [1](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/schema/meta_schemas/document/v0/document-meta.json#L20) | -| Maximum property name length | [64](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/schema/meta_schemas/document/v0/document-meta.json#L20) | +| Minimum number of properties | [1](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/schema/meta_schemas/document/v1/document-meta.json#L23) | +| Maximum number of properties | [100](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/schema/meta_schemas/document/v1/document-meta.json#L24) | +| Minimum property name length | [1](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/schema/meta_schemas/document/v1/document-meta.json#L21) | +| Maximum property name length | [64](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/schema/meta_schemas/document/v1/document-meta.json#L21) | | Property name characters | Alphanumeric (`A-Z`, `a-z`, `0-9`)
    Hyphen (`-`)
    Underscore (`_`) | ## Document Indices @@ -213,15 +213,15 @@ For performance and security reasons, indices have the following constraints. Th | Description | Value | | ----------- | ----- | -| Minimum/maximum length of index `name` | [1](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/schema/meta_schemas/document/v0/document-meta.json#L357) / [32](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/schema/meta_schemas/document/v0/document-meta.json#L358) | -| Maximum number of indices | [10](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/schema/meta_schemas/document/v0/document-meta.json#L438) | -| Maximum number of unique indices | [10](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-platform-version/src/version/dpp_versions/dpp_validation_versions/v2.rs#L27) | -| Maximum number of contested indices | [1](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-platform-version/src/version/dpp_versions/dpp_validation_versions/v2.rs#L26) | -| Maximum number of properties in a single index | [10](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/schema/meta_schemas/document/v0/document-meta.json#L377) | -| Maximum length of indexed string property | [63](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/data_contract/document_type/class_methods/try_from_schema/mod.rs#L22) | +| Minimum/maximum length of index `name` | [1](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/schema/meta_schemas/document/v1/document-meta.json#L358) / [32](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/schema/meta_schemas/document/v1/document-meta.json#L359) | +| Maximum number of indices | [10](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/schema/meta_schemas/document/v1/document-meta.json#L482) | +| Maximum number of unique indices | [10](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-platform-version/src/version/dpp_versions/dpp_validation_versions/v2.rs#L27) | +| Maximum number of contested indices | [1](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-platform-version/src/version/dpp_versions/dpp_validation_versions/v2.rs#L26) | +| Maximum number of properties in a single index | [10](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/schema/meta_schemas/document/v1/document-meta.json#L378) | +| Maximum length of indexed string property | [63](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/data_contract/document_type/class_methods/try_from_schema/mod.rs#L24) | | Usage of `$id` in an index [disallowed](https://github.com/dashpay/platform/pull/178) | N/A | -| **Note: Dash Platform [does not allow indices for arrays](https://github.com/dashpay/platform/pull/225).**
    Maximum length of indexed byte array property | [255](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/data_contract/document_type/class_methods/try_from_schema/mod.rs#L24) | -| **Note: Dash Platform [does not allow indices for arrays](https://github.com/dashpay/platform/pull/225).**
    Maximum number of indexed array items | [1024](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/data_contract/document_type/class_methods/try_from_schema/mod.rs#L25) | +| **Note: Dash Platform [does not allow indices for arrays](https://github.com/dashpay/platform/pull/225).**
    Maximum length of indexed byte array property | [255](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/data_contract/document_type/class_methods/try_from_schema/mod.rs#L25) | +| **Note: Dash Platform [does not allow indices for arrays](https://github.com/dashpay/platform/pull/225).**
    Maximum number of indexed array items | [1024](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/data_contract/document_type/class_methods/try_from_schema/mod.rs#L26) | :::{seealso} For all protocol constants, see [Protocol Constants](protocol-constants.md). @@ -256,7 +256,6 @@ Documents support the following configuration options to provide flexibility in | `transferable` | integer | Transferable without a marketplace sell:
    `0` - Never
    `1` - Always
    See the [NFT page](../explanations/nft.md#transfer-and-trade) for more details | | `tradeMode` | integer | Built-in marketplace system:
    `0` - None
    `1` - Direct purchase (the purchaser can buy the item without requiring approval)
    See the [NFT page](../explanations/nft.md#transfer-and-trade) for more details | | `creationRestrictionMode` | integer | Restriction of document creation:
    `0` - No restrictions
    `1` - Contract owner only
    `2` - No Creation Allowed
    See the [NFT page](../explanations/nft.md#creation-restrictions) for more details | -| `keywords` | array of strings | Up to 20 strings (3–50 characters each) describing the document type for searchability | | Security option | Type | Description | |-----------------|------|-------------| @@ -266,7 +265,7 @@ Documents support the following configuration options to provide flexibility in ### Token Costs -The `tokenCost` option allows document types to require token payment for operations. When configured, users must pay a specified amount of tokens to perform each operation type. Each operation cost is defined as a [documentActionTokenCost](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/schema/meta_schemas/document/v0/document-meta.json#L293-336) object with the following properties: +The `tokenCost` option allows document types to require token payment for operations. When configured, users must pay a specified amount of tokens to perform each operation type. Each operation cost is defined as a [documentActionTokenCost](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/schema/meta_schemas/document/v0/document-meta.json#L294-L337) object with the following properties: | Property | Type | Required | Description | |----------|------|----------|-------------| @@ -289,7 +288,7 @@ The following operation types can each have an independent cost configuration: :::{dropdown} List of all usable document properties - This list of properties is defined in the [Rust DPP implementation](https://github.com/dashpay/platform/blob/master/packages/rs-dpp/src/data_contract/document_type/mod.rs#L41) and the [document meta-schema](https://github.com/dashpay/platform/blob/master/packages/rs-dpp/schema/meta_schemas/document/v0/document-meta.json). + This list of properties is defined in the [Rust DPP implementation](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/data_contract/document_type/mod.rs#L41) and the [document meta-schema](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/schema/meta_schemas/document/v1/document-meta.json). | Property Name | Type | Description | |---------------|------|-------------| @@ -309,7 +308,18 @@ The following operation types can each have an independent cost configuration: | [`properties`](#document-properties) | object | Defines the properties of the document. | | [`transient`](#transient-properties) | array | An array of strings specifying transient properties that are validated by Platform but not stored. | | `tokenCost` | object | Defines token costs for document operations (create, replace, update_price, delete, transfer, purchase) | - | `keywords` | array | Up to 20 strings (3–50 characters each) for searchability | + | [`documentsCountable`](#aggregate-query-flags) | boolean | Doctype-wide count support. See [Aggregate Query Flags](#aggregate-query-flags). | + | [`rangeCountable`](#aggregate-query-flags) | boolean | Per-index range counts. See [Aggregate Query Flags](#aggregate-query-flags). | + | [`documentsSummable`](#aggregate-query-flags) | string | Doctype-wide sums of the named integer property. See [Aggregate Query Flags](#aggregate-query-flags). | + | [`rangeSummable`](#aggregate-query-flags) | boolean | Per-index range sums. See [Aggregate Query Flags](#aggregate-query-flags). | + | [`documentsAverageable`](#aggregate-query-flags) | string | Doctype-wide averages of the named integer property. See [Aggregate Query Flags](#aggregate-query-flags). | + | [`rangeAverageable`](#aggregate-query-flags) | boolean | Per-index range averages. See [Aggregate Query Flags](#aggregate-query-flags). | + | `required` | array | Standard JSON Schema keyword listing required property names. | + | `description` | string | Standard JSON Schema keyword describing the document type. | + | `$comment` | string | Standard JSON Schema keyword for a schema comment. | + | `minProperties` | integer | Standard JSON Schema keyword bounding the minimum number of properties. | + | `maxProperties` | integer | Standard JSON Schema keyword bounding the maximum number of properties. | + | `dependentRequired` | object | Standard JSON Schema keyword declaring conditionally required properties. | | [`additionalProperties`](./data-contract.md#additional-properties) | boolean | Specifies whether additional properties are allowed. Must be set to false, meaning no additional properties are allowed beyond those defined. | ::: @@ -332,7 +342,7 @@ The following example (from the [DPNS contract's `domain` document](https://gith ## Aggregate Query Flags -:::{versionadded} 3.1.0 +:::{versionadded} 4.0.0 ::: Document types can opt into aggregate query support (count / sum / average) by setting flags at the document-type level. These flags control the underlying storage layout — once set on a published contract they cannot be changed by a contract update. @@ -340,7 +350,7 @@ Document types can opt into aggregate query support (count / sum / average) by s There are two axes: * **Doctype-wide** (`documents*`) — applies the aggregate over the entire document type. Set at the document type root, alongside other doctype options like `documentsKeepHistory`. -* **Per-index range** (`range*`) — extends the corresponding aggregate to range queries on indexed properties. Set on the index's property entry. Requires the matching base flag. +* **Per-index range** (`range*`) — extends the corresponding aggregate to range queries on indexed properties. Set on the index object (alongside `name`, `properties`, `unique`, and `contested`), using the index-level `countable`/`summable`/`averageable` flags and their `range*` variants — not on the individual `{ "field": "asc" }` property entry. Requires the matching base flag. | Flag | Type | Purpose | Required for | | - | - | - | - | @@ -353,7 +363,7 @@ There are two axes: The averageable flags desugar to the underlying count + sum flags during contract parsing — same on-disk layout — so authors who think in terms of averages get a single flag and downstream code paths (insert, query, estimation) stay unchanged. If both `documentsAverageable` and `documentsSummable` are set, they must name the same property. -These flags are validated against the v1 document meta-schema and are rejected when applied to pre-v12 contracts. The full v1 meta-schema, including these flags, is defined [in rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/schema/meta_schemas/document/v1/document-meta.json). +These flags are validated against the v1 document meta-schema and are rejected when applied to pre-v12 contracts. The full v1 meta-schema, including these flags, is defined [in rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/schema/meta_schemas/document/v1/document-meta.json). See the [`getDocuments` reference](../reference/dapi-endpoints-platform-endpoints.md#getdocuments) for the request/response shapes that consume these flags. @@ -362,7 +372,7 @@ See the [`getDocuments` reference](../reference/dapi-endpoints-platform-endpoint There are a variety of keyword constraints currently defined for performance and security reasons. The following constraints apply to document definitions. Unless otherwise noted, these constraints are defined in the platform's JSON Schema rules (e.g., [rs-dpp document meta -schema](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/schema/meta_schemas/document/v0/document-meta.json)). +schema](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/schema/meta_schemas/document/v0/document-meta.json)). | Keyword | Constraint | | ------- | ---------- | @@ -433,4 +443,4 @@ This example syntax shows the structure of a documents object that defines two d ## Document Schema -See full document schema details in the [rs-dpp document meta schema](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/schema/meta_schemas/document/v0/document-meta.json). +See full document schema details in the [rs-dpp document meta schema](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/schema/meta_schemas/document/v1/document-meta.json). diff --git a/docs/protocol-ref/data-contract-token.md b/docs/protocol-ref/data-contract-token.md index 59f9fa6e6..a1a087502 100644 --- a/docs/protocol-ref/data-contract-token.md +++ b/docs/protocol-ref/data-contract-token.md @@ -48,10 +48,10 @@ Token creation incurs specific fees based on which token features are used: | Operation | Fee (DASH)| Description | |-----------|-----------|-------------| -| Token registration | [0.1](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-platform-version/src/version/fee/data_contract_registration/v2.rs#L11)| Base fee for adding a token to a contract | -| Perpetual distribution | [0.1](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-platform-version/src/version/fee/data_contract_registration/v2.rs#L12) | Fee for enabling perpetual distribution | -| Pre-programmed distribution | [0.1](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-platform-version/src/version/fee/data_contract_registration/v2.rs#L13) | Fee for enabling pre-programmed distribution | -| Search keyword fee | [0.1](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-platform-version/src/version/fee/data_contract_registration/v2.rs#L14) | Per keyword fee for including search keywords | +| Token registration | [0.1](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-platform-version/src/version/fee/data_contract_registration/v2.rs#L11)| Base fee for adding a token to a contract | +| Perpetual distribution | [0.1](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-platform-version/src/version/fee/data_contract_registration/v2.rs#L12) | Fee for enabling perpetual distribution | +| Pre-programmed distribution | [0.1](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-platform-version/src/version/fee/data_contract_registration/v2.rs#L13) | Fee for enabling pre-programmed distribution | +| Search keyword fee | [0.1](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-platform-version/src/version/fee/data_contract_registration/v2.rs#L14) | Per keyword fee for including search keywords | ## Assigning Position @@ -144,7 +144,7 @@ Token configuration controls behavioral aspects of token operations, including s | Property | Type | Description | |----------|------|-------------| | `mainControlGroup` | unsigned integer | Position assigned to the main control group | -| `mainControlGroupCanBeModified` | string | Authorization level for modifying the main control group | +| `mainControlGroupCanBeModified` | string | Who is authorized to modify the main control group. Valid values are listed in the [authorized parties table](#authorized-parties). | **Example:** @@ -165,7 +165,7 @@ Change control rules define authorization requirements for modifying various asp ### Authorized Parties -Rules can authorize no one, specific identities, or multiparty groups. The complete set of options [defined by DPP](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/data_contract/change_control_rules/authorized_action_takers.rs#L15-L22) is: +Rules can authorize no one, specific identities, or multiparty groups. The complete set of options [defined by DPP](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/data_contract/change_control_rules/authorized_action_takers.rs#L15-L22) is: | Authorized Party | Description | |----------------------|-------------| @@ -177,7 +177,7 @@ Rules can authorize no one, specific identities, or multiparty groups. The compl ### Change Rule Structure -Each rule consists of the following parameters [defined in DPP](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/data_contract/change_control_rules/v0/mod.rs) that control its behavior: +Each rule consists of the following parameters [defined in DPP](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/data_contract/change_control_rules/v0/mod.rs) that control its behavior: | Field | Description | | - | - | @@ -279,11 +279,11 @@ The `distributionType` field accepts one of three schedule types: | Type | Interval Unit | Description | |------|---------------|-------------| -| `BlockBasedDistribution` | Block height | Emits tokens every N blocks. If `start` is not set, begins at the block when the data contract is registered. | -| `TimeBasedDistribution` | Milliseconds | Emits tokens every N milliseconds. If `start` is not set, begins at the time of the block when the data contract is registered. | -| `EpochBasedDistribution` | Epochs | Emits tokens every N epochs. If `start` is not set, begins at the epoch of the block when the data contract is registered. Distribution happens at the start of the following epoch. Required when using `EvonodesByParticipation` as the distribution recipient. | +| `BlockBasedDistribution` | Block height | Emits tokens every N blocks. By default begins at the block when the data contract is registered. | +| `TimeBasedDistribution` | Milliseconds | Emits tokens every N milliseconds. By default begins at the time of the block when the data contract is registered. | +| `EpochBasedDistribution` | Epochs | Emits tokens every N epochs. By default begins at the epoch of the block when the data contract is registered. Distribution happens at the start of the following epoch. Required when using `EvonodesByParticipation` as the distribution recipient. | -Each type wraps an `interval` (the period length) and a `function` (the emission pattern from the options below). +Each type wraps an `interval` (the period length) and a `function` (the emission pattern from the options below). There is no separate `start` field on the distribution type; the schedule begins at contract registration by default and a later start can be set through the function's start offset parameter (`start_step`, `start_moment`, or `start_decreasing_offset`, depending on the function). #### Perpetual Distribution Options @@ -315,6 +315,10 @@ Emits a constant (fixed) number of tokens for every period. Emits a random number of tokens within a specified range. +:::{note} +The Random distribution function is not supported in the current release. Contract validation rejects it with an `UnsupportedFeatureError`, so a contract using it cannot be registered. +::: + - **Formula**: `f(x) ∈ [min, max]` - Constraints: - `min` must be ≤ `max`, otherwise the function is invalid. @@ -355,7 +359,7 @@ Emits tokens that decrease in discrete steps at fixed intervals. - `decrease_per_interval_denominator` (u16): reduction factor denominator - `start_decreasing_offset` (optional u64): start period offset. If not provided, the contract creation start is used. Before this offset, `distribution_start_amount` is emitted every interval. - `distribution_start_amount` (TokenAmount): initial token emission amount - - `max_interval_count` (optional u16): maximum number of decreasing intervals. **Defaults to 128 if not set.** After this many cycles, `trailing_distribution_interval_amount` is emitted per interval. Maximum value: 1024. + - `max_interval_count` (optional u16): maximum number of decreasing intervals. **Defaults to 128 if not set.** After this many cycles, `trailing_distribution_interval_amount` is emitted per interval. When provided, it must be between 2 and 1024 inclusive. - `trailing_distribution_interval_amount` (TokenAmount): token emission after all decreasing intervals are exhausted - `min_value` (optional u64): minimum emission floor - **Use Case:** Reward systems with predictable decay—ideal for Bitcoin-style halvings or Dash-style gradual reductions @@ -583,7 +587,6 @@ The distribution functions use the following parameters defined across various i |-----------|------|---------|-------------| | `a` | integer | - | Coefficient/scaling factor | | `b` | integer | - | Base offset or constant term | -| `c` | integer | - | Additional offset | | `d` | integer | 1 | Divisor for precision control | | `m` | integer | - | Exponent numerator | | `n` | integer | 1 | Exponent denominator | @@ -594,10 +597,12 @@ The distribution functions use the following parameters defined across various i | `step_count` | integer | - | Periods between steps | | `numerator` | integer | - | Reduction factor numerator | | `denominator` | integer | - | Reduction factor denominator | -| `interval` | integer | - | Time interval in milliseconds | +| `interval` | integer | - | Period length; unit depends on the distribution type (blocks, milliseconds, or epochs) | :::{note} Parameter sign types vary by function: `a` is unsigned (u64) for `Exponential` but signed (i64) for all other functions. `m` is unsigned (u64) for `Logarithmic` and `InvertedLogarithmic` but signed (i64) for `Polynomial` and `Exponential`. + +The **Default** column shows typical values rather than code-enforced defaults. In the underlying structs, `a`, `b`, `d`, `m`, `n`, and `o` are required fields with no default — they must be supplied for the functions that use them. Only the start offset (`s`) and the emission bounds (`min_value`, `max_value`) are optional; the start offset defaults to contract registration. ::: ### Distribution Recipients @@ -620,27 +625,27 @@ For performance and security reasons, tokens have the following constraints: | Parameter | Value | |-----------|-------| -| Maximum number of keywords | [50](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/data_contract/methods/validate_update/v0/mod.rs#L272-L277) | -| Keyword length | [3 to 50 characters](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/data_contract/methods/validate_update/v0/mod.rs#L279-L287) | -| Description length | [3 to 100 characters](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/data_contract/methods/validate_update/v0/mod.rs#L312-L323) | -| Maximum note length | [2048 bytes](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/tokens/mod.rs#L19) | +| Maximum number of keywords | [50](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/data_contract/methods/validate_update/v0/mod.rs#L272-L277) | +| Keyword length | [3 to 50 characters](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/data_contract/methods/validate_update/v0/mod.rs#L279-L287) | +| Description length | [3 to 100 characters](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/data_contract/methods/validate_update/v0/mod.rs#L312-L323) | +| Maximum note length | [2048 bytes](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/tokens/mod.rs#L19) | | Maximum number of tokens per contract | Only limited by [maximum contract size](./data-contract.md#data-size) | ### Convention Constraints | Parameter | Value | |-----------|-------| -| Language code length | [2 to 12 characters](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/data_contract/associated_token/token_configuration_convention/methods/validate_localizations/v0/mod.rs#L97-L101) | -| Token name length (singular) | [3 to 25 characters](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/data_contract/associated_token/token_configuration_convention/methods/validate_localizations/v0/mod.rs#L84-L89) | -| Token name length (plural) | [3 to 25 characters](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/data_contract/associated_token/token_configuration_convention/methods/validate_localizations/v0/mod.rs#L90-L95) | -| Decimal places | [0 to 16](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/data_contract/associated_token/token_configuration_convention/methods/validate_localizations/v0/mod.rs#L31-L36) | +| Language code length | [2 to 12 characters](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/data_contract/associated_token/token_configuration_convention/methods/validate_localizations/v0/mod.rs#L97-L101) | +| Token name length (singular) | [3 to 25 characters](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/data_contract/associated_token/token_configuration_convention/methods/validate_localizations/v0/mod.rs#L84-L89) | +| Token name length (plural) | [3 to 25 characters](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/data_contract/associated_token/token_configuration_convention/methods/validate_localizations/v0/mod.rs#L90-L95) | +| Decimal places | [0 to 16](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/data_contract/associated_token/token_configuration_convention/methods/validate_localizations/v0/mod.rs#L31-L36) | | Maximum localization entries | Only limited by [maximum contract size](./data-contract.md#data-size) | ### Supply Constraints | Parameter | Value | |-----------|-------| -| Maximum token amount | [i64::MAX (2^63 - 1 = 9,223,372,036,854,775,807)](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/errors/consensus/basic/data_contract/invalid_token_base_supply_error.rs#L12-L16) | +| Maximum token amount | [i64::MAX (2^63 - 1 = 9,223,372,036,854,775,807)](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/errors/consensus/basic/data_contract/invalid_token_base_supply_error.rs#L12-L16) | ## Example Syntax diff --git a/docs/protocol-ref/data-contract.md b/docs/protocol-ref/data-contract.md index c2c351576..203968f1c 100644 --- a/docs/protocol-ref/data-contract.md +++ b/docs/protocol-ref/data-contract.md @@ -45,9 +45,9 @@ There are a variety of constraints currently defined for performance and securit | Parameter | Size | | - | - | -| Estimated maximum serialized data contract size | [16384 bytes (16 KB)](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-platform-version/src/version/system_limits/v1.rs#L4) | -| Maximum field value size | [5120 bytes (5 KB)](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-platform-version/src/version/system_limits/v1.rs#L5) | -| Maximum state transition size | [20480 bytes (20 KB)](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-platform-version/src/version/system_limits/v1.rs#L6) | +| Estimated maximum serialized data contract size | [16384 bytes (16 KB)](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-platform-version/src/version/system_limits/v1.rs#L4) | +| Maximum field value size | [5120 bytes (5 KB)](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-platform-version/src/version/system_limits/v1.rs#L5) | +| Maximum state transition size | [20480 bytes (20 KB)](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-platform-version/src/version/system_limits/v1.rs#L6) | A document cannot exceed the maximum state transition size in any case. For example, although it is possible to define a data contract with 10 document fields that each support the maximum field size @@ -67,7 +67,7 @@ Include the following at the same level as the `properties` keyword to ensure pr ## Data Contract Object -The data contract object consists of the following fields as defined in the Rust reference client ([rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/data_contract/v1/data_contract.rs#L77-L121)): +The data contract object consists of the following fields as defined in the Rust reference client ([rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/data_contract/v1/data_contract.rs#L77-L121)): | Property | Type | Size | Description | | --------------- | -------------- | ---- | ----------- | @@ -92,14 +92,15 @@ The data contract object consists of the following fields as defined in the Rust ### Document type meta-schema -Each document type defined within a data contract is validated against the document meta-schema. The full schema is [defined in rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/data_contract/document_type/schema/enrich_with_base_schema/v0/mod.rs#L6-L7), hosted on [GitHub](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/schema/meta_schemas/document/v0/document-meta.json), and can be viewed by expanding this dropdown: +Each document type defined within a data contract is validated against the document meta-schema. This page reflects the v1 meta-schema used since protocol version 12 (Dash Platform v4.0.0); earlier protocol versions validated against the v0 meta-schema. The full schema is [defined in rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/schema/meta_schemas/document/v1/document-meta.json), hosted on [GitHub](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/schema/meta_schemas/document/v1/document-meta.json), and can be viewed by expanding this dropdown: ::: {dropdown} Full schema ```json { "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://github.com/dashpay/platform/blob/master/packages/rs-dpp/schema/meta_schemas/document/v0/document-meta.json", + "$id": "https://github.com/dashpay/platform/blob/master/packages/rs-dpp/schema/meta_schemas/document/v1/document-meta.json", + "$comment": "EDITABLE UNTIL 3.1 RELEASE — FROZEN AFTER. This v1 document meta-schema activates with protocol v12 (CONTRACT_VERSIONS_V4) and admits every v12+ contract written to disk. Once Platform 3.1 ships, mutating it would change historical validation results and break consensus replay. After release, any new top-level property or rule MUST go in a newer meta-schema version (v2+).", "type": "object", "$defs": { "documentProperties": { @@ -441,7 +442,7 @@ Each document type defined within a data contract is validated against the docum }, "$schema": { "type": "string", - "const": "https://github.com/dashpay/platform/blob/master/packages/rs-dpp/schema/meta_schemas/document/v0/document-meta.json" + "const": "https://github.com/dashpay/platform/blob/master/packages/rs-dpp/schema/meta_schemas/document/v1/document-meta.json" }, "$defs": { "$ref": "#/$defs/documentProperties" @@ -525,12 +526,55 @@ Each document type defined within a data contract is validated against the docum "resolution" ], "additionalProperties": false + }, + "countable": { + "oneOf": [ + { + "type": "boolean", + "description": "Legacy form. true == \"countable\", false == \"notCountable\". Kept for back-compat with contracts written before the enum form was introduced." + }, + { + "type": "string", + "enum": ["notCountable", "countable", "countableAllowingOffset"], + "description": "\"countable\" — index uses a CountTree (O(1) totals). \"countableAllowingOffset\" — index uses a ProvableCountTree (totals + future O(log n) range / offset queries). \"notCountable\" — plain NormalTree (no count fast path)." + } + ], + "description": "Whether and how the index supports count fast paths. Adds extra storage cost for non-default values." + }, + "rangeCountable": { + "type": "boolean", + "description": "When true, the property-name level becomes a ProvableCountTree and value trees become CountTrees so range-count queries on the indexed property are O(log n). Requires `countable` to be \"countable\" or \"countableAllowingOffset\"." + }, + "summable": { + "type": "string", + "minLength": 1, + "maxLength": 64, + "description": "Name of an integer document property whose values are aggregated into a sum at the index. When set, the index's value trees become SumTrees and each per-document index reference is a ReferenceWithSumItem contributing the named property's value to ancestor sum-bearing trees. The property must exist on the document type, be in `required`, and have an integer type." + }, + "rangeSummable": { + "type": "boolean", + "description": "When true, the property-name level becomes a ProvableSumTree (or ProvableCountProvableSumTree when paired with `rangeCountable: true`) so range-sum queries on the indexed property are O(log n) via the `AggregateSumOnRange` proof primitive. Requires `summable` to be set." + }, + "averageable": { + "type": "string", + "minLength": 1, + "maxLength": 64, + "description": "Syntactic sugar: `averageable: \"\"` is shorthand for `countable: \"countable\"` + `summable: \"\"`. Enables average queries (which return `(count, sum)` pairs the client divides) without forcing authors to think in terms of count + sum. Same on-disk layout as setting both underlying flags. If you set both `averageable` and `summable`, they must name the same property." + }, + "rangeAverageable": { + "type": "boolean", + "description": "Syntactic sugar: `rangeAverageable: true` is shorthand for `rangeCountable: true` + `rangeSummable: true`. Requires `averageable` to be set." } }, "required": [ "properties", "name" ], + "dependentRequired": { + "rangeCountable": ["countable"], + "rangeSummable": ["summable"], + "rangeAverageable": ["averageable"] + }, "additionalProperties": false }, "minItems": 1, @@ -600,6 +644,34 @@ Each document type defined within a data contract is validated against the docum ], "description": "Key requirements. 0 - Unique Non Replaceable, 1 - Multiple, 2 - Multiple with reference to latest key." }, + "documentsCountable": { + "type": "boolean", + "description": "When true, the primary key tree uses a CountTree enabling O(1) total document count queries." + }, + "rangeCountable": { + "type": "boolean", + "description": "When true, the primary key tree uses a ProvableCountTree enabling range countable. Implies documentsCountable." + }, + "documentsSummable": { + "type": "string", + "minLength": 1, + "maxLength": 64, + "description": "Name of an integer document property aggregated into the primary-key SumTree (one sum per document type). Stores documents as `ItemWithSumItem` so the primary-key tree's root sum is the total of the named property across all docs of this type. Property must exist on the document type, be in `required`, and have an integer type. Composes with `documentsKeepHistory: true` — keep-history doctypes get a `SumTree` per-document subtree with a `ReferenceWithSumItem` on the `0`-key carrying the current version's value, so the doctype-level root aggregate reflects current versions only (historical versions don't double-count)." + }, + "rangeSummable": { + "type": "boolean", + "description": "When true, the primary key tree uses a ProvableSumTree (or ProvableCountProvableSumTree paired with rangeCountable: true) enabling O(log n) range-sum queries over the primary axis. Requires `documentsSummable` to be set. Rarely useful — range-sum on the primary key with no where-clause filter is unusual; most callers want per-index `rangeSummable` instead. Set this only when you need a provable global range-sum tree." + }, + "documentsAverageable": { + "type": "string", + "minLength": 1, + "maxLength": 64, + "description": "Syntactic sugar: `documentsAverageable: \"\"` is shorthand for `documentsCountable: true` + `documentsSummable: \"\"`. Enables doctype-wide average queries (returns `(count, sum)` the client divides) without authors having to compose the count + sum flags. Same on-disk layout. If you set both `documentsAverageable` and `documentsSummable`, they must name the same property. Composes with `documentsKeepHistory: true` via the per-doc SumTree + ReferenceWithSumItem layout described under `documentsSummable`." + }, + "rangeAverageable": { + "type": "boolean", + "description": "Syntactic sugar: `rangeAverageable: true` is shorthand for `rangeCountable: true` + `rangeSummable: true`. Requires `documentsAverageable` to be set. Same caveat as `rangeSummable` — rarely useful on the primary key; per-index `rangeAverageable` is what most callers want." + }, "tokenCost": { "type": "object", "properties": { @@ -683,20 +755,40 @@ Each document type defined within a data contract is validated against the docum "type": "string" } }, - "keywords": { + "additionalProperties": { + "type": "boolean", + "const": false + }, + "required": { "type": "array", - "description": "List of up to 20 descriptive keywords for the contract, used in the Keyword Search contract", "items": { - "type": "string", - "minLength": 3, - "maxLength": 50 + "type": "string" }, - "maxItems": 20, "uniqueItems": true }, - "additionalProperties": { - "type": "boolean", - "const": false + "$comment": { + "type": "string" + }, + "description": { + "type": "string" + }, + "minProperties": { + "type": "integer", + "minimum": 0 + }, + "maxProperties": { + "type": "integer", + "minimum": 0 + }, + "dependentRequired": { + "type": "object", + "additionalProperties": { + "type": "array", + "items": { + "type": "string" + }, + "uniqueItems": true + } } }, "required": [ @@ -704,19 +796,24 @@ Each document type defined within a data contract is validated against the docum "type", "properties", "additionalProperties" - ] + ], + "dependentRequired": { + "rangeSummable": ["documentsSummable"], + "rangeAverageable": ["documentsAverageable"] + }, + "additionalProperties": false } ``` ::: :::{note} -The `keywords` field appears at two levels with different limits. The document meta-schema above defines per-document-type keywords with a maximum of 20. The contract-level `keywords` field (shown in the [data contract object table](#data-contract-object)) has a separate maximum of 50 enforced by Rust validation. +`keywords` is a contract-level field (shown in the [data contract object table](#data-contract-object)), with a maximum of 50 enforced by Rust validation. It is not a document-type property. ::: ### Data Contract id -The data contract `id` is a hash of the `ownerId` and `identity_nonce` as shown in the [rs-dpp implementation](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/data_contract/generate_data_contract.rs). +The data contract `id` is a hash of the `ownerId` and `identity_nonce` as shown in the [rs-dpp implementation](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/data_contract/generate_data_contract.rs). ```rust // From the Rust reference implementation (rs-dpp) @@ -744,7 +841,7 @@ See the [data contract documents](./data-contract-document.md) page for details, ### Data Contract config -The data contract config defines configuration options for data contracts, controlling their lifecycle, mutability, history management, and encryption requirements. Data contracts support three categories of configuration options to provide flexibility in contract design. It is only necessary to include them in a data contract when non-default values are used. The default values for these configuration options are defined in the [Rust DPP implementation](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/data_contract/config/fields.rs). +The data contract config defines configuration options for data contracts, controlling their lifecycle, mutability, history management, and encryption requirements. Data contracts support three categories of configuration options to provide flexibility in contract design. It is only necessary to include them in a data contract when non-default values are used. The default values for these configuration options are defined in the [Rust DPP implementation](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/data_contract/config/fields.rs). | Contract option | Default | Description | |-----------------------------------------|---------|-------------| @@ -774,7 +871,7 @@ These security options can be set at the root level of the data contract or the **Example** -The following example (from the [DashPay contract's `contactRequest` document](https://github.com/dashpay/platform/blob/v3.1-dev/packages/dashpay-contract/schema/v1/dashpay.schema.json#L142-L146)) demonstrates the use of both key-related options at the document level: +The following example (from the [DashPay contract's `contactRequest` document](https://github.com/dashpay/platform/blob/v4.0.0/packages/dashpay-contract/schema/v1/dashpay.schema.json#L142-L146)) demonstrates the use of both key-related options at the document level: ``` json "contactRequest": { @@ -783,7 +880,7 @@ The following example (from the [DashPay contract's `contactRequest` document](h } ``` -See the data contract [config implementation in rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/data_contract/config/v1/mod.rs#L21-L48) for more details. +See the data contract [config implementation in rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/data_contract/config/v1/mod.rs#L21-L48) for more details. ### Data Contract groups @@ -800,9 +897,9 @@ Groups can be used to distribute contract configuration and update authorization | Constant | Value | Description | |----------|-------|-------------| -| Minimum group size | [2](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/data_contract/group/v0/mod.rs#L107-L110) | Minimum members per group | +| Minimum group size | [2](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/data_contract/group/v0/mod.rs#L107-L110) | Minimum members per group | | `max_contract_group_size` | 256 | Maximum members per group | -| Maximum member power | 65,535 (u32; cap enforced at u16::MAX) | Maximum voting power per member. Each member's power must also not exceed the group's [`requiredPower`](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/data_contract/group/v0/mod.rs#L129-L134) value. | +| Maximum member power | 65,535 (u32; cap enforced at u16::MAX) | Maximum voting power per member. Each member's power must also not exceed the group's [`requiredPower`](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/data_contract/group/v0/mod.rs#L129-L134) value. | | Maximum required power | 65,535 (u32; cap enforced at u16::MAX) | Maximum threshold power | #### Group Action Info @@ -840,7 +937,7 @@ When submitting a group-authorized action, the transition includes: In this example, any two of the three members can authorize an action. -See the [groups implementation in rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/data_contract/group/v0/mod.rs#L36-L39) for more details. +See the [groups implementation in rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/data_contract/group/v0/mod.rs#L36-L39) for more details. ### Data Contract tokens @@ -869,7 +966,7 @@ Data contracts are created on the platform by submitting the [data contract obje | signaturePublicKeyId | unsigned integer | 32 bits | The `id` of the [identity public key](../protocol-ref/identity.md#identity-publickeys) that signed the state transition (`=> 0`) | | signature | array of bytes | 65 bytes | Signature of state transition data | -See the [data contract create implementation in rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/state_transition/state_transitions/contract/data_contract_create_transition/v0/mod.rs#L40-L48) for more details. +See the [data contract create implementation in rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/state_transition/state_transitions/contract/data_contract_create_transition/v0/mod.rs#L40-L48) for more details. ### Data Contract Update @@ -893,7 +990,7 @@ object](#data-contract-object) in a data contract update state transition consis | signaturePublicKeyId | unsigned integer | 32 bits | The `id` of the [identity public key](../protocol-ref/identity.md#identity-publickeys) that signed the state transition (`=> 0`) | | signature | array of bytes | 65 bytes | Signature of state transition data | -See the [data contract update implementation in rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/state_transition/state_transitions/contract/data_contract_update_transition/v0/mod.rs#L35-L47) for more details. +See the [data contract update implementation in rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/state_transition/state_transitions/contract/data_contract_update_transition/v0/mod.rs#L35-L47) for more details. ### Data Contract State Transition Signing diff --git a/docs/protocol-ref/data-trigger.md b/docs/protocol-ref/data-trigger.md index a37603ece..5b4698c06 100644 --- a/docs/protocol-ref/data-trigger.md +++ b/docs/protocol-ref/data-trigger.md @@ -10,7 +10,7 @@ Although [data contracts](../protocol-ref/data-contract.md) provide much needed ## Details -Since all application data is submitted in the form of documents, data triggers are defined in the context of documents. To provide even more granularity, they also incorporate the [document transition action](../protocol-ref/document.md#document-transition-action) so separate triggers can be created for the CREATE, REPLACE, or DELETE actions. +Since all application data is submitted in the form of documents, data triggers are defined in the context of documents. To provide even more granularity, they also incorporate the [document transition action](../protocol-ref/document.md#document-transition-action) so separate triggers can be created for any document transition action (for example, CREATE, REPLACE, DELETE, TRANSFER, PURCHASE, or UPDATE_PRICE). When document state transitions are received, DPP checks if there is a trigger associated with the document transition type and action. If there is, it then executes the trigger logic. @@ -18,17 +18,17 @@ When document state transitions are received, DPP checks if there is a trigger a ### Example -As an example, DPP contains several data triggers for DPNS as defined in the [data trigger bindings](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/bindings/list/v0/mod.rs). The `domain` document has added constraints for creation, replacement or deletion: +As an example, DPP contains several data triggers for DPNS as defined in the [data trigger bindings](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/bindings/list/v0/mod.rs). The `domain` document has added constraints for creation, replacement or deletion: | Data Contract | Document | Action(s) | Trigger Description | | ------------- | ------------------ | ------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------- | -| DPNS | `domain` | [`CREATE`](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/dpns/v0/mod.rs#L48) | Enforces DNS compatibility, validates provided hashes, and restricts top-level domain (TLD) registration | +| DPNS | `domain` | [`CREATE`](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/dpns/v1/mod.rs#L48) | Enforces DNS compatibility, validates provided hashes, and restricts top-level domain (TLD) registration | | ---- | ---- | ---- | ---- | -| DPNS | `domain` | [`REPLACE`](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/reject/v0/mod.rs#L25) | Prevents updates to existing documents | -| DPNS | `domain` | [`DELETE`](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/reject/v0/mod.rs#L25) | Prevents deletion of existing documents | -| DPNS | `domain` | [`TRANSFER`](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/reject/v0/mod.rs#L25) | Prevents transfer of existing documents | -| DPNS | `domain` | [`PURCHASE`](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/reject/v0/mod.rs#L25) | Prevents purchase of existing documents | -| DPNS | `domain` | [`UPDATE_PRICE`](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/reject/v0/mod.rs#L25) | Prevents updating price of existing documents | +| DPNS | `domain` | [`REPLACE`](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/reject/v0/mod.rs#L25) | Prevents updates to existing documents | +| DPNS | `domain` | [`DELETE`](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/reject/v0/mod.rs#L25) | Prevents deletion of existing documents | +| DPNS | `domain` | [`TRANSFER`](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/reject/v0/mod.rs#L25) | Prevents transfer of existing documents | +| DPNS | `domain` | [`PURCHASE`](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/reject/v0/mod.rs#L25) | Prevents purchase of existing documents | +| DPNS | `domain` | [`UPDATE_PRICE`](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/reject/v0/mod.rs#L25) | Prevents updating price of existing documents | **DPNS Trigger Constraints** diff --git a/docs/protocol-ref/document.md b/docs/protocol-ref/document.md index 6da973652..0e0b5f679 100644 --- a/docs/protocol-ref/document.md +++ b/docs/protocol-ref/document.md @@ -24,11 +24,11 @@ The following fields are included in all document transitions. Note that `$actio | $dataContractId | array | 32 bytes | Data contract ID [generated](../protocol-ref/data-contract.md#data-contract-id) from the data contract's `ownerId` and `identity nonce` | | [$tokenPaymentInfo](#token-payment-info) | object | Varies | (Optional, V1+) Token-based fee payment information for this transition | -Each document transition must comply with the [document base transition defined in rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_base_transition/v1/mod.rs#L38-L56). +Each document transition must comply with the [document base transition defined in rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_base_transition/v1/mod.rs#L38-L56). #### Document id -The document `$id` is created by double sha256 hashing the document's `dataContractId`, `ownerId`, `type`, and `entropy` as shown in [rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/document/generate_document_id.rs). +The document `$id` is created by double sha256 hashing the document's `dataContractId`, `ownerId`, `type`, and `entropy` as shown in [rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/document/generate_document_id.rs). ```rust // From the Rust reference implementation (rs-dpp) @@ -52,7 +52,7 @@ pub fn generate_document_id_v0( #### Token Payment Info -When a document type requires token payment (configured via [`tokenCost`](./data-contract-document.md#token-costs) in the data contract), the `$tokenPaymentInfo` object specifies which token to use and the cost limits the client is willing to accept. The object is defined in [rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/tokens/token_payment_info/v0/mod.rs#L36-L56). +When a document type requires token payment (configured via [`tokenCost`](./data-contract-document.md#token-costs) in the data contract), the `$tokenPaymentInfo` object specifies which token to use and the cost limits the client is willing to accept. The object is defined in [rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/tokens/token_payment_info/v0/mod.rs#L36-L56). | Field | Type | Size | Description | | - | - | - | - | @@ -68,7 +68,7 @@ The `gasFeesPaidBy` value must match what the data contract's `tokenCost` config #### Entropy Generation -Dash Platform uses the following entropy generator found in [rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/util/entropy_generator.rs#L9-L14): +Dash Platform uses the following entropy generator found in [rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/util/entropy_generator.rs#L9-L14): ```rust // From the Rust reference implementation (rs-dpp) @@ -83,7 +83,7 @@ fn generate(&self) -> anyhow::Result<[u8; 32]> { #### Document Transition Action -Document transition actions indicate what operation platform should perform with the provided transition data. Documents provide CRUD functionality, ownership transfer, and NFT features as [defined in rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_transition_action_type.rs#L6-L14). +Document transition actions indicate what operation platform should perform with the provided transition data. Documents provide CRUD functionality, ownership transfer, and NFT features as [defined in rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_transition_action_type.rs#L6-L14). | Action | Name | Description | | :-: | - | - | @@ -105,7 +105,7 @@ The document create transition extends the [base transition](#document-base-tran | data | | Varies | Document data being submitted. | | $prefundedVotingBalance | | Varies | (Optional) Prefunded amount of credits reserved for unique index conflict resolution voting (e.g., [premium DPNS name](../explanations/dpns.md#conflict-resolution)).| -Each document create transition must comply with the structure defined in [rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_create_transition/v0/mod.rs#L57-L78) (in addition to the [document base transition](#document-base-transition) that is required for all document transitions). +Each document create transition must comply with the structure defined in [rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_create_transition/v0/mod.rs#L57-L78) (in addition to the [document base transition](#document-base-transition) that is required for all document transitions). ::: {note} The document create transition data field must include all [required document properties](./data-contract-document.md#required-properties) specified in the data contract. @@ -143,7 +143,7 @@ The document replace transition extends the [base transition](#document-base-tra | $revision | unsigned integer | 64 bits | Document revision (=> 1) | | data | | Varies | Document data being updated | -Each document replace transition must comply with the structure defined in [rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_replace_transition/v0/mod.rs#L35-L42) (in addition to the [document base transition](#document-base-transition) that is required for all document transitions). +Each document replace transition must comply with the structure defined in [rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_replace_transition/v0/mod.rs#L35-L42) (in addition to the [document base transition](#document-base-transition) that is required for all document transitions). ::: {note} The document replace transition data field must include all [required document properties](./data-contract-document.md#required-properties) specified in the data contract. @@ -174,7 +174,7 @@ The following example document replace transition and subsequent table demonstra ### Document Delete Transition -The document delete transition only requires the fields found in the [base document transition](#document-base-transition). See the [implementation in rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_delete_transition/v0/mod.rs#L21-L24) for details. +The document delete transition only requires the fields found in the [base document transition](#document-base-transition). See the [implementation in rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_delete_transition/v0/mod.rs#L21-L24) for details. ### Document Transfer Transition @@ -185,7 +185,7 @@ The document transfer transition allows a document owner to transfer document ow | $revision | unsigned integer | 64 bits | Document revision (=> 1) | | recipientOwnerId | array of bytes | 32 bytes | Identifier of the recipient (new owner). See the [NFT page](../explanations/nft.md#transfer-and-trade) for more details. | -Each document transfer transition must comply with the structure defined in [rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_transfer_transition/v0/mod.rs#L33-L40) (in addition to the [document base transition](#document-base-transition) that is required for all document transitions). +Each document transfer transition must comply with the structure defined in [rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_transfer_transition/v0/mod.rs#L33-L40) (in addition to the [document base transition](#document-base-transition) that is required for all document transitions). ### Document Purchase Transition @@ -196,7 +196,7 @@ The document purchase transition allows an identity to purchase a document previ | $revision | unsigned integer | 64 bits | Document revision (=> 1) | | price | unsigned integer | 64 bits | Number of credits being offered for the purchase. See the [NFT page](../explanations/nft.md#transfer-and-trade) for more details. | -Each document purchase transition must comply with the structure defined in [rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_purchase_transition/v0/mod.rs#L23-L30) (in addition to the [document base transition](#document-base-transition) that is required for all document transitions). +Each document purchase transition must comply with the structure defined in [rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_purchase_transition/v0/mod.rs#L23-L30) (in addition to the [document base transition](#document-base-transition) that is required for all document transitions). ### Document Update Price Transition @@ -207,18 +207,18 @@ The document update price transition allows a document owner to set or update th | $revision | unsigned integer | 64 bits | Document revision (=> 1) | | $price | unsigned integer | 64 bits | Updated price for the document. Can only be set by the current document owner. See the [NFT page](../explanations/nft.md#transfer-and-trade) for more details. | -Each document update price transition must comply with the structure defined in [rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_update_price_transition/v0/mod.rs#L27-L34) (in addition to the [document base transition](#document-base-transition) that is required for all document transitions). +Each document update price transition must comply with the structure defined in [rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_update_price_transition/v0/mod.rs#L27-L34) (in addition to the [document base transition](#document-base-transition) that is required for all document transitions). ## Document Object -The document object represents the data provided by the platform in response to a query. Responses consist of an array of these objects containing the following fields as defined in the Rust reference client ([rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/document/v0/mod.rs#L39-L124)): +The document object represents the data provided by the platform in response to a query. Responses consist of an array of these objects containing the following fields as defined in the Rust reference client ([rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/document/v0/mod.rs#L39-L124)): | Property | Type | Required | Description | | - | - | - | - | | $id | array | Yes | The [document ID](#document-id) (32 bytes)| -| $type | string | Yes | Document type defined in the referenced contract (1-64 characters) | +| $type | string | Yes | Document type defined in the referenced contract (1-64 characters). Supplied by the query context; not a stored field of the `DocumentV0` struct. | | $revision | unsigned integer (64 bits) | No | Document revision (=>1) if the document is mutable | -| $dataContractId | array | Yes | Data contract ID [generated](../protocol-ref/data-contract.md#data-contract-id) from the data contract's `ownerId` and `identity nonce` (32 bytes) | +| $dataContractId | array | Yes | Data contract ID [generated](../protocol-ref/data-contract.md#data-contract-id) from the data contract's `ownerId` and `identity nonce` (32 bytes). Supplied by the query context; not a stored field of the `DocumentV0` struct. | | $ownerId | array | Yes | [Identity](../protocol-ref/identity.md) of the user submitting the document (32 bytes) | | $createdAt | unsigned integer (64 bits) | No | Time (in milliseconds) at document creation, if required by the document type schema | | $updatedAt | unsigned integer (64 bits) | No | Last document update time in milliseconds, if required by the document type schema | diff --git a/docs/protocol-ref/errors.md b/docs/protocol-ref/errors.md index 11c238dd8..9b865ea7a 100644 --- a/docs/protocol-ref/errors.md +++ b/docs/protocol-ref/errors.md @@ -6,7 +6,7 @@ ## Platform Error Codes -Dash Platform Protocol implements a comprehensive set of consensus error codes. Refer to the tables below for a list of the codes as specified in [codes.rs](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/errors/consensus/codes.rs) of the consensus source code. +Dash Platform Protocol implements a comprehensive set of consensus error codes. Refer to the tables below for a list of the codes as specified in [codes.rs](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/errors/consensus/codes.rs) of the consensus source code. Platform error codes are organized into four categories. Each category may be further divided into sub-categories. The four categories and their error code ranges are: @@ -189,6 +189,7 @@ Code range: 10450-10499 | 10458 | InvalidTokenAmountError | | | 10459 | InvalidTokenNoteTooBigError | | | 10460 | TokenNoteOnlyAllowedWhenProposerError | | +| 10461 | TokenPricingScheduleEmptyError | | ### Identity @@ -230,6 +231,7 @@ Code range: 10500-10599 | 10531 | IdentityAssetLockStateTransitionReplayError | | | 10532 | WithdrawalOutputScriptNotAllowedWhenSigningWithOwnerKeyError | | | 10533 | InvalidKeyPurposeForContractBoundsError | | +| 10534 | IdentityAssetLockTransactionTooManyInputsError | | ### State Transition @@ -279,9 +281,11 @@ Code range: 10800-10899 | 10820 | ShieldedEmptyProofError | | | 10821 | ShieldedZeroAnchorError | | | 10822 | ShieldedInvalidValueBalanceError | | -| 10823 | *(reserved/unassigned)* | | +| 10823 | ShieldedEncryptedNoteSizeMismatchError | | | 10824 | *(reserved/unassigned)* | | | 10825 | ShieldedTooManyActionsError | | +| 10826 | ShieldedImplicitFeeCapExceededError | | +| 10827 | ShieldedInvalidDenominationError | | ## Signature Errors diff --git a/docs/protocol-ref/identity.md b/docs/protocol-ref/identity.md index bbdc019d9..4b4df2ae8 100644 --- a/docs/protocol-ref/identity.md +++ b/docs/protocol-ref/identity.md @@ -17,7 +17,7 @@ Identities consist of multiple objects that are described in the following secti | [balance](#identity-balance) | unsigned integer (64-bit) | Credit balance associated with the identity | | revision | integer | Identity update revision | -See the [identity implementation in rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/identity/v0/mod.rs#L36-L45) for more details. +See the [identity implementation in rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/identity/v0/mod.rs#L36-L45) for more details. **Example Identity** @@ -46,17 +46,17 @@ The identity `id` is a unique identifier created from the double sha256 hash of `id = base58(sha256(sha256()))` :::{note} -The identity `id` uses the Dash Platform specific `application/x.dash.dpp.identifier` content media type. For additional information, please refer to the [js-dpp PR 252](https://github.com/dashevo/js-dpp/pull/252) that introduced it and [identifier.rs](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-platform-value/src/types/identifier.rs). +The identity `id` uses the Dash Platform specific `application/x.dash.dpp.identifier` content media type. For additional information, please refer to the [js-dpp PR 252](https://github.com/dashevo/js-dpp/pull/252) that introduced it and [identifier.rs](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-platform-value/src/types/identifier.rs). ::: -See rs-dpp for examples of using [InstantSend](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/instant/instant_asset_lock_proof.rs#L146) or [ChainLocks](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/chain/chain_asset_lock_proof.rs#L54) to create the identity id. +See rs-dpp for examples of using [InstantSend](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/instant/instant_asset_lock_proof.rs#L146) or [ChainLocks](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/chain/chain_asset_lock_proof.rs#L54) to create the identity id. ### Identity publicKeys The identity `publicKeys` array stores information regarding each public key associated with the identity. Multiple identities may use the same public key. :::{note} -Each identity must have exactly one master key ([security level](#public-key-securitylevel) `0`) used for updating the identity. Having an additional key ([security level](#public-key-securitylevel) `1` or `2`) for signing state transitions is strongly recommended but not enforced by the protocol. The maximum number of keys is 15000 as [defined by rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/identity/fields.rs#L7). +Each identity must have exactly one master key ([security level](#public-key-securitylevel) `0`) used for updating the identity. Having an additional key ([security level](#public-key-securitylevel) `1` or `2`) for signing state transitions is strongly recommended but not enforced by the protocol. The maximum number of keys is 15000 as [defined by rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/identity/fields.rs#L7). ::: Each item in the `publicKeys` array consists of an object containing: @@ -73,7 +73,7 @@ Each item in the `publicKeys` array consists of an object containing: | [disabledAt](#public-key-disabledat) | integer | Timestamp indicating that the key was disabled at a specified time | | signature | array of bytes | Signature of the signable identity create or topup state transition by the private key associated with this public key | -See the [public key implementation in rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/identity/identity_public_key/v0/mod.rs#L42-L53) for more details. +See the [public key implementation in rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/identity/identity_public_key/v0/mod.rs#L42-L53) for more details. #### Public Key `id` @@ -81,7 +81,7 @@ Each public key in an identity's `publicKeys` array must be assigned a unique in #### Public Key `type` -The `type` field indicates the algorithm used to derive the key. Available key types [defined in rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/identity/identity_public_key/key_type.rs#L46-L53) include: +The `type` field indicates the algorithm used to derive the key. Available key types [defined in rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/identity/identity_public_key/key_type.rs#L46-L53) include: | Type | Size (bytes) | Description | | :--: | :----------: | ----------- | @@ -97,7 +97,7 @@ The `data` field contains the compressed public key. #### Public Key `purpose` -The `purpose` field describes which operations are supported by the key. Please refer to [DIP11 - Identities](https://github.com/dashpay/dips/blob/master/dip-0011.md#keys) for additional information regarding this. Keys for some purposes must meet certain the security level criteria [defined by rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/state_transition/state_transitions/identity/public_key_in_creation/methods/validate_identity_public_keys_structure/v0/mod.rs#L22-L37) as detailed below: +The `purpose` field describes which operations are supported by the key. Please refer to [DIP11 - Identities](https://github.com/dashpay/dips/blob/master/dip-0011.md#keys) for additional information regarding this. Keys for some purposes must meet certain the security level criteria [defined by rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/state_transition/state_transitions/identity/public_key_in_creation/methods/validate_identity_public_keys_structure/v0/mod.rs#L22-L37) as detailed below: | Type | Description | Allowed Security Level(s) | | :--: | -------------- | ------------------------- | @@ -205,7 +205,7 @@ Identities are created on the platform by submitting the identity information in | signature | array of bytes | Signature of state transition data by the single-use key from the asset lock (65 bytes) | | identityId | array of bytes | An [identity id](#identity-id) for the identity being created (32 bytes). Computed from the asset lock proof outpoint and excluded from the serialized payload. | -See the [identity create implementation in rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_create_transition/v0/mod.rs#L47-L58) for more details. +See the [identity create implementation in rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_create_transition/v0/mod.rs#L47-L58) for more details. ### Identity TopUp @@ -220,7 +220,7 @@ Identity credit balances are increased by submitting the topup information in an | userFeeIncrease | integer | Extra fee to prioritize processing if the mempool is full. Typically set to zero. | | signature | array of bytes | Signature of state transition data by the single-use key from the asset lock (65 bytes) | -See the [identity topup implementation in rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_topup_transition/v0/mod.rs#L43-L50) for more details. +See the [identity topup implementation in rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_topup_transition/v0/mod.rs#L43-L50) for more details. ### Identity Update @@ -239,7 +239,7 @@ Identities are updated on the platform by submitting the identity information in | signaturePublicKeyId | integer | The ID of public key used to sign the state transition | | signature | array of bytes | Signature of state transition data (65 bytes) | -See the [identity update implementation in rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_update_transition/v0/mod.rs#L43-L72) for more details. +See the [identity update implementation in rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_update_transition/v0/mod.rs#L43-L72) for more details. ### Identity Credit Transfer @@ -257,7 +257,7 @@ Identities can transfer credits on the platform by submitting an identity credit | signaturePublicKeyId | integer | The ID of public key used to sign the state transition | | signature | array of bytes | Signature of state transition data (65 bytes) | -See the [identity credit transfer implementation in rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_transfer_transition/v0/mod.rs#L42-L53) for more details. +See the [identity credit transfer implementation in rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_transfer_transition/v0/mod.rs#L42-L53) for more details. ### Identity Credit Withdrawal @@ -265,7 +265,7 @@ Credits can be withdrawn from an identity to an external Core wallet using an id | Field | Type | Description | | -------------------- | -------------- | ----------- | -| $version | integer | The protocol version (currently `1`) | +| $version | integer | The state transition format version (currently `1`) | | type | integer | State transition type (`6` for identity credit withdrawal) | | identityId | array of bytes | An [identity id](#identity-id) (32 bytes) | | amount | integer | The amount of credits to withdraw (64 bits) | @@ -277,17 +277,17 @@ Credits can be withdrawn from an identity to an external Core wallet using an id | signaturePublicKeyId | integer | The ID of public key used to sign the state transition | | signature | array of bytes | Signature of state transition data (65 bytes) | -See the [identity credit withdrawal implementation in rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_withdrawal_transition/v1/mod.rs#L35-L48) for more details. +See the [identity credit withdrawal implementation in rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_withdrawal_transition/v1/mod.rs#L35-L52) for more details. ### Asset Lock The [identity create](#identity-create) and [identity topup](#identity-topup) state transitions both include an asset lock proof object. This object references the Core chain [asset lock transaction](inv:user:std#ref-txs-assetlocktx) and includes proof that the transaction is locked. -Currently there are two types of asset lock proofs [defined by rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/mod.rs#L135-L138): InstantSend and ChainLock. Transactions almost always receive InstantSend locks, so the InstantSend asset lock proof is the predominate type. See rs-dpp for examples of using [InstantSend](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/instant/instant_asset_lock_proof.rs) or [ChainLocks](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/chain/chain_asset_lock_proof.rs) as the asset lock proof. +Currently there are two types of asset lock proofs [defined by rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/mod.rs#L40-L43): InstantSend and ChainLock. Transactions almost always receive InstantSend locks, so the InstantSend asset lock proof is the predominate type. See rs-dpp for examples of using [InstantSend](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/instant/instant_asset_lock_proof.rs) or [ChainLocks](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/chain/chain_asset_lock_proof.rs) as the asset lock proof. #### InstantSend Asset Lock Proof -The InstantSend asset lock proof is used for transactions that have received an InstantSend lock. Asset locks using an InstantSend lock as proof must comply with this structure established in [rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/instant/instant_asset_lock_proof.rs#L38-L45). +The InstantSend asset lock proof is used for transactions that have received an InstantSend lock. Asset locks using an InstantSend lock as proof must comply with this structure established in [rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/instant/instant_asset_lock_proof.rs#L38-L45). | Field | Type | Description | | ----------- | -------------- | ----------- | @@ -298,7 +298,7 @@ The InstantSend asset lock proof is used for transactions that have received an #### ChainLock Asset Lock Proof -The ChainLock asset lock proof is used for transactions that have not received an InstantSend lock, but have been included in a block that has received a ChainLock. Asset locks using a ChainLock as proof must comply with this structure established in [rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/chain/chain_asset_lock_proof.rs#L24-L29). +The ChainLock asset lock proof is used for transactions that have not received an InstantSend lock, but have been included in a block that has received a ChainLock. Asset locks using a ChainLock as proof must comply with this structure established in [rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/chain/chain_asset_lock_proof.rs#L24-L29). | Field | Type | Description | | --------------------- | -------------- | ----------- | diff --git a/docs/protocol-ref/protocol-constants.md b/docs/protocol-ref/protocol-constants.md index a5a620808..404ada52d 100644 --- a/docs/protocol-ref/protocol-constants.md +++ b/docs/protocol-ref/protocol-constants.md @@ -12,18 +12,18 @@ Maximum sizes and limits for various platform components. | Limit | Value | Description | Source | |-------|-------|-------------|--------| -| Max contract size | 16,384 bytes (16 KiB) | Maximum serialized data contract | [rs-platform-version](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-platform-version/src/version/system_limits/v1.rs#L4) | -| Max field value size | 5,120 bytes (5 KiB) | Maximum single field value | [rs-platform-version](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-platform-version/src/version/system_limits/v1.rs#L5) | -| Max state transition size | 20,480 bytes (20 KiB) | Maximum serialized state transition | [rs-platform-version](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-platform-version/src/version/system_limits/v1.rs#L6) | -| Max transitions in documents batch | 1 | Maximum document 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#L7) | -| Withdrawals per block | 4 | Maximum withdrawal transactions per block | [rs-platform-version](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-platform-version/src/version/system_limits/v1.rs#L8) | -| Retry signing expired withdrawals per block | 1 | Max expired withdrawal retries per block | [rs-platform-version](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-platform-version/src/version/system_limits/v1.rs#L9) | -| 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 | 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) | +| Max contract size | 16,384 bytes (16 KiB) | Maximum serialized data contract | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-platform-version/src/version/system_limits/v1.rs#L4) | +| Max field value size | 5,120 bytes (5 KiB) | Maximum single field value | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-platform-version/src/version/system_limits/v1.rs#L5) | +| Max state transition size | 20,480 bytes (20 KiB) | Maximum serialized state transition | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-platform-version/src/version/system_limits/v1.rs#L6) | +| Max transitions in documents batch | 1 | Maximum document transitions per batch | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-platform-version/src/version/system_limits/v1.rs#L20) | +| Withdrawals per block | 4 | Maximum withdrawal transactions per block | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-platform-version/src/version/system_limits/v1.rs#L21) | +| Retry signing expired withdrawals per block | 1 | Max expired withdrawal retries per block | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-platform-version/src/version/system_limits/v1.rs#L22) | +| Max withdrawal amount | 50,000,000,000,000 credits | 500 Dash maximum per withdrawal | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-platform-version/src/version/system_limits/v1.rs#L23) | +| Max contract group size | 256 | Maximum members per group | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-platform-version/src/version/system_limits/v1.rs#L27) | +| Max token redemption cycles | 128 | Maximum redemption cycles | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-platform-version/src/version/system_limits/v1.rs#L28) | +| Max shielded transition actions | 16 | Maximum [actions](shielded-pool.md#actions) per shielded transition | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-platform-version/src/version/system_limits/v1.rs#L36) | +| Max CBOR encoded length | 16,384 bytes (16 KiB) | Maximum CBOR encoding size | [rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/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/v4.0.0/packages/rs-dpp/src/data_contract/serialized_version/mod.rs#L38) | ## Credit System @@ -31,8 +31,8 @@ Credits are the unit of account for fees on Dash Platform. They are created from | Constant | Value | Description | Source | |----------|-------|-------------|--------| -| `CREDITS_PER_DUFF` | 1,000 | Credits created per duff (satoshi) | [rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/balances/credits.rs#L42) | -| `MAX_CREDITS` | 9,223,372,036,854,775,807 | Maximum credit value (i64::MAX) | [rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/balances/credits.rs#L40) | +| `CREDITS_PER_DUFF` | 1,000 | Credits created per duff (satoshi) | [rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/balances/credits.rs#L42) | +| `MAX_CREDITS` | 9,223,372,036,854,775,807 | Maximum credit value (i64::MAX) | [rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/balances/credits.rs#L40) | **Conversion:** 1 Dash = 100,000,000 duffs = 100,000,000,000 credits @@ -44,13 +44,13 @@ These constants define the base costs for state transition processing. | Constant | Value (Credits) | Description | Source | |----------|-----------------|-------------|--------| -| `BASE_ST_PROCESSING_FEE` | 10,000 | Base state transition processing fee | [rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/fee/default_costs/constants.rs#L3) | -| `DEFAULT_USER_TIP` | 0 | Default priority tip | [rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/fee/default_costs/constants.rs#L4) | -| `STORAGE_CREDIT_PER_BYTE` | 5,000 | Storage cost per byte | [rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/fee/default_costs/constants.rs#L5) | -| `PROCESSING_CREDIT_PER_BYTE` | 12 | Processing cost per byte | [rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/fee/default_costs/constants.rs#L6) | -| `DELETE_BASE_PROCESSING_COST` | 2,000 | Base deletion cost | [rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/fee/default_costs/constants.rs#L7) | -| `READ_BASE_PROCESSING_COST` | 8,400 | Base read cost | [rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/fee/default_costs/constants.rs#L8) | -| `WRITE_BASE_PROCESSING_COST` | 6,000 | Base write cost | [rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/fee/default_costs/constants.rs#L9) | +| `BASE_ST_PROCESSING_FEE` | 10,000 | Base state transition processing fee | [rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/fee/default_costs/constants.rs#L3) | +| `DEFAULT_USER_TIP` | 0 | Default priority tip | [rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/fee/default_costs/constants.rs#L4) | +| `STORAGE_CREDIT_PER_BYTE` | 5,000 | Storage cost per byte | [rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/fee/default_costs/constants.rs#L5) | +| `PROCESSING_CREDIT_PER_BYTE` | 12 | Processing cost per byte | [rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/fee/default_costs/constants.rs#L6) | +| `DELETE_BASE_PROCESSING_COST` | 2,000 | Base deletion cost | [rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/fee/default_costs/constants.rs#L7) | +| `READ_BASE_PROCESSING_COST` | 8,400 | Base read cost | [rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/fee/default_costs/constants.rs#L8) | +| `WRITE_BASE_PROCESSING_COST` | 6,000 | Base write cost | [rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/fee/default_costs/constants.rs#L9) | ### State Transition Pricing @@ -58,20 +58,20 @@ These constants define minimum values required for a state transition to be cons | State Transition | Min Fee (Credits) | Min Fee (Dash) | Source | |------------------|-------------------|----------------|--------| -| Credit Transfer | 100,000 | 0.000001 | [rs-platform-version](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-platform-version/src/version/fee/state_transition_min_fees/v1.rs#L4) | -| Credit Transfer to Addresses | 500,000 | 0.000005 | [rs-platform-version](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-platform-version/src/version/fee/state_transition_min_fees/v1.rs#L5) | -| Credit Withdrawal | 400,000,000 | 0.004 | [rs-platform-version](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-platform-version/src/version/fee/state_transition_min_fees/v1.rs#L6) | -| Identity Update | 100,000 | 0.000001 | [rs-platform-version](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-platform-version/src/version/fee/state_transition_min_fees/v1.rs#L7) | -| Document Batch (per sub-transition) | 100,000 | 0.000001 | [rs-platform-version](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-platform-version/src/version/fee/state_transition_min_fees/v1.rs#L8) | -| Contract Create | 100,000 | 0.000001 | [rs-platform-version](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-platform-version/src/version/fee/state_transition_min_fees/v1.rs#L9) | -| Contract Update | 100,000 | 0.000001 | [rs-platform-version](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-platform-version/src/version/fee/state_transition_min_fees/v1.rs#L10) | -| Masternode Vote | 100,000 | 0.000001 | [rs-platform-version](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-platform-version/src/version/fee/state_transition_min_fees/v1.rs#L11) | -| Address Credit Withdrawal | 400,000,000 | 0.004 | [rs-platform-version](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-platform-version/src/version/fee/state_transition_min_fees/v1.rs#L13) | -| Address Funds Transfer (per input) | 500,000 | 0.000005 | [rs-platform-version](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-platform-version/src/version/fee/state_transition_min_fees/v1.rs#L14) | -| Address Funds Transfer (per output) | 6,000,000 | 0.00006 | [rs-platform-version](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-platform-version/src/version/fee/state_transition_min_fees/v1.rs#L15) | -| Identity Create (base) | 2,000,000 | 0.00002 | [rs-platform-version](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-platform-version/src/version/fee/state_transition_min_fees/v1.rs#L16) | -| Identity Key (per key at creation) | 6,500,000 | 0.000065 | [rs-platform-version](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-platform-version/src/version/fee/state_transition_min_fees/v1.rs#L17) | -| Identity TopUp (base) | 500,000 | 0.000005 | [rs-platform-version](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-platform-version/src/version/fee/state_transition_min_fees/v1.rs#L18) | +| Credit Transfer | 100,000 | 0.000001 | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-platform-version/src/version/fee/state_transition_min_fees/v1.rs#L4) | +| Credit Transfer to Addresses | 500,000 | 0.000005 | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-platform-version/src/version/fee/state_transition_min_fees/v1.rs#L5) | +| Credit Withdrawal | 400,000,000 | 0.004 | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-platform-version/src/version/fee/state_transition_min_fees/v1.rs#L6) | +| Identity Update | 100,000 | 0.000001 | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-platform-version/src/version/fee/state_transition_min_fees/v1.rs#L7) | +| Document Batch (per sub-transition) | 100,000 | 0.000001 | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-platform-version/src/version/fee/state_transition_min_fees/v1.rs#L8) | +| Contract Create | 100,000 | 0.000001 | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-platform-version/src/version/fee/state_transition_min_fees/v1.rs#L9) | +| Contract Update | 100,000 | 0.000001 | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-platform-version/src/version/fee/state_transition_min_fees/v1.rs#L10) | +| Masternode Vote | 100,000 | 0.000001 | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-platform-version/src/version/fee/state_transition_min_fees/v1.rs#L11) | +| Address Credit Withdrawal | 400,000,000 | 0.004 | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-platform-version/src/version/fee/state_transition_min_fees/v1.rs#L13) | +| Address Funds Transfer (per input) | 500,000 | 0.000005 | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-platform-version/src/version/fee/state_transition_min_fees/v1.rs#L14) | +| Address Funds Transfer (per output) | 6,000,000 | 0.00006 | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-platform-version/src/version/fee/state_transition_min_fees/v1.rs#L15) | +| Identity Create (base) | 2,000,000 | 0.00002 | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-platform-version/src/version/fee/state_transition_min_fees/v1.rs#L16) | +| Identity Key (per key at creation) | 6,500,000 | 0.000065 | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-platform-version/src/version/fee/state_transition_min_fees/v1.rs#L17) | +| Identity TopUp (base) | 500,000 | 0.000005 | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-platform-version/src/version/fee/state_transition_min_fees/v1.rs#L18) | ### Execution and Resource Pricing @@ -83,16 +83,16 @@ Fees for specific operations during state transition processing. | Operation | Fee (Credits) | Source | |-----------|---------------|--------| -| Fetch identity balance | 10,000 | [rs-platform-version](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-platform-version/src/version/fee/processing/v1.rs#L4) | -| Fetch identity revision | 9,000 | [rs-platform-version](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-platform-version/src/version/fee/processing/v1.rs#L5) | -| Fetch identity balance and revision | 15,000 | [rs-platform-version](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-platform-version/src/version/fee/processing/v1.rs#L6) | -| Fetch identity key by ID | 9,000 | [rs-platform-version](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-platform-version/src/version/fee/processing/v1.rs#L7) | -| Fetch identity token balance | 10,000 | [rs-platform-version](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-platform-version/src/version/fee/processing/v1.rs#L8) | -| Fetch prefunded specialized balance | 10,000 | [rs-platform-version](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-platform-version/src/version/fee/processing/v1.rs#L9) | -| Fetch key with type, nonce and balance | 12,000 | [rs-platform-version](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-platform-version/src/version/fee/processing/v1.rs#L10) | -| Fetch single identity key | 10,000 | [rs-platform-version](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-platform-version/src/version/fee/processing/v1.rs#L11) | -| Network threshold signing | 100,000,000 | [rs-platform-version](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-platform-version/src/version/fee/processing/v1.rs#L12) | -| Validate key structure | 50 | [rs-platform-version](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-platform-version/src/version/fee/processing/v1.rs#L13) | +| Fetch identity balance | 10,000 | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-platform-version/src/version/fee/processing/v1.rs#L4) | +| Fetch identity revision | 9,000 | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-platform-version/src/version/fee/processing/v1.rs#L5) | +| Fetch identity balance and revision | 15,000 | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-platform-version/src/version/fee/processing/v1.rs#L6) | +| Fetch identity key by ID | 9,000 | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-platform-version/src/version/fee/processing/v1.rs#L7) | +| Fetch identity token balance | 10,000 | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-platform-version/src/version/fee/processing/v1.rs#L8) | +| Fetch prefunded specialized balance | 10,000 | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-platform-version/src/version/fee/processing/v1.rs#L9) | +| Fetch key with type, nonce and balance | 12,000 | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-platform-version/src/version/fee/processing/v1.rs#L10) | +| Fetch single identity key | 10,000 | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-platform-version/src/version/fee/processing/v1.rs#L11) | +| Network threshold signing | 100,000,000 | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-platform-version/src/version/fee/processing/v1.rs#L12) | +| Validate key structure | 50 | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-platform-version/src/version/fee/processing/v1.rs#L13) | #### Storage @@ -100,11 +100,11 @@ Fees related to data storage operations. | Operation | Fee (Credits) | Source | |-----------|---------------|--------| -| Storage disk usage (per byte) | 27,000 | [rs-platform-version](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-platform-version/src/version/fee/storage/v1.rs) | -| Storage processing (per byte) | 400 | [rs-platform-version](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-platform-version/src/version/fee/storage/v1.rs) | -| Storage load (per byte) | 20 | [rs-platform-version](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-platform-version/src/version/fee/storage/v1.rs) | -| Non-storage load (per byte) | 10 | [rs-platform-version](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-platform-version/src/version/fee/storage/v1.rs) | -| Storage seek | 2,000 | [rs-platform-version](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-platform-version/src/version/fee/storage/v1.rs) | +| Storage disk usage (per byte) | 27,000 | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-platform-version/src/version/fee/storage/v1.rs) | +| Storage processing (per byte) | 400 | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-platform-version/src/version/fee/storage/v1.rs) | +| Storage load (per byte) | 20 | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-platform-version/src/version/fee/storage/v1.rs) | +| Non-storage load (per byte) | 10 | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-platform-version/src/version/fee/storage/v1.rs) | +| Storage seek | 2,000 | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-platform-version/src/version/fee/storage/v1.rs) | #### Cryptographic Operations @@ -114,11 +114,11 @@ Fees for verifying different signature types. | Key Type | Verification Fee (Credits) | Source | |----------|----------------------------|--------| -| ECDSA Secp256k1 | 15,000 | [rs-platform-version](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-platform-version/src/version/fee/signature/v1.rs) | -| BLS 12-381 | 300,000 | [rs-platform-version](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-platform-version/src/version/fee/signature/v1.rs) | -| ECDSA Hash160 | 15,500 | [rs-platform-version](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-platform-version/src/version/fee/signature/v1.rs) | -| BIP13 Script Hash | 300,000 | [rs-platform-version](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-platform-version/src/version/fee/signature/v1.rs) | -| EdDSA 25519 Hash160 | 3,500 | [rs-platform-version](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-platform-version/src/version/fee/signature/v1.rs) | +| ECDSA Secp256k1 | 15,000 | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-platform-version/src/version/fee/signature/v1.rs) | +| BLS 12-381 | 300,000 | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-platform-version/src/version/fee/signature/v1.rs) | +| ECDSA Hash160 | 15,500 | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-platform-version/src/version/fee/signature/v1.rs) | +| BIP13 Script Hash | 300,000 | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-platform-version/src/version/fee/signature/v1.rs) | +| EdDSA 25519 Hash160 | 3,500 | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-platform-version/src/version/fee/signature/v1.rs) | ##### Hashing @@ -126,13 +126,13 @@ Fees for cryptographic hash operations. | Operation | Fee (Credits) | Source | |-----------|---------------|--------| -| Single SHA256 (base) | 100 | [rs-platform-version](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-platform-version/src/version/fee/hashing/v1.rs) | -| Blake3 (base) | 100 | [rs-platform-version](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-platform-version/src/version/fee/hashing/v1.rs) | -| SHA256 + RIPEMD160 (base) | 6,000 | [rs-platform-version](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-platform-version/src/version/fee/hashing/v1.rs) | -| SHA256 (per block) | 5,000 | [rs-platform-version](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-platform-version/src/version/fee/hashing/v1.rs) | -| Blake3 (per block) | 300 | [rs-platform-version](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-platform-version/src/version/fee/hashing/v1.rs) | -| RIPEMD160 (per block) | 5,000 | [rs-platform-version](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-platform-version/src/version/fee/hashing/v1.rs) | -| Sinsemilla (base) | 40,000 | [rs-platform-version](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-platform-version/src/version/fee/hashing/v1.rs) | +| Single SHA256 (base) | 100 | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-platform-version/src/version/fee/hashing/v1.rs) | +| Blake3 (base) | 100 | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-platform-version/src/version/fee/hashing/v1.rs) | +| SHA256 + RIPEMD160 (base) | 6,000 | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-platform-version/src/version/fee/hashing/v1.rs) | +| SHA256 (per block) | 5,000 | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-platform-version/src/version/fee/hashing/v1.rs) | +| Blake3 (per block) | 300 | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-platform-version/src/version/fee/hashing/v1.rs) | +| RIPEMD160 (per block) | 5,000 | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-platform-version/src/version/fee/hashing/v1.rs) | +| Sinsemilla (base) | 40,000 | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-platform-version/src/version/fee/hashing/v1.rs) | #### Data Contract Validation @@ -140,13 +140,13 @@ Fees for validating data contract structure during state transition processing. | Fee Type | Amount (Credits) | Source | |----------|------------------|--------| -| Document type base fee | 500 | [rs-platform-version](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-platform-version/src/version/fee/data_contract_validation/v1.rs#L5) | -| Schema size fee (per byte) | 10 | [rs-platform-version](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-platform-version/src/version/fee/data_contract_validation/v1.rs#L6) | -| Per property fee | 40 | [rs-platform-version](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-platform-version/src/version/fee/data_contract_validation/v1.rs#L7) | -| Non-unique index base fee | 50 | [rs-platform-version](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-platform-version/src/version/fee/data_contract_validation/v1.rs#L8) | -| Non-unique index per property fee | 30 | [rs-platform-version](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-platform-version/src/version/fee/data_contract_validation/v1.rs#L9) | -| Unique index base fee | 100 | [rs-platform-version](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-platform-version/src/version/fee/data_contract_validation/v1.rs#L10) | -| Unique index per property fee | 60 | [rs-platform-version](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-platform-version/src/version/fee/data_contract_validation/v1.rs#L11) | +| Document type base fee | 500 | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-platform-version/src/version/fee/data_contract_validation/v1.rs#L5) | +| Schema size fee (per byte) | 10 | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-platform-version/src/version/fee/data_contract_validation/v1.rs#L6) | +| Per property fee | 40 | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-platform-version/src/version/fee/data_contract_validation/v1.rs#L7) | +| Non-unique index base fee | 50 | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-platform-version/src/version/fee/data_contract_validation/v1.rs#L8) | +| Non-unique index per property fee | 30 | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-platform-version/src/version/fee/data_contract_validation/v1.rs#L9) | +| Unique index base fee | 100 | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-platform-version/src/version/fee/data_contract_validation/v1.rs#L10) | +| Unique index per property fee | 60 | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-platform-version/src/version/fee/data_contract_validation/v1.rs#L11) | ### Voting @@ -154,9 +154,9 @@ Fees related to contested document voting. | Fee Type | Amount (Credits) | Amount (Dash) | Source | |----------|------------------|---------------|--------| -| Contested document vote resolution fund | 20,000,000,000 | 0.2 | [rs-platform-version](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-platform-version/src/version/fee/vote_resolution_fund_fees/v1.rs) | -| Contested document unlock fund | 400,000,000,000 | 4.0 | [rs-platform-version](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-platform-version/src/version/fee/vote_resolution_fund_fees/v1.rs) | -| Single vote cost | 10,000,000 | 0.0001 | [rs-platform-version](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-platform-version/src/version/fee/vote_resolution_fund_fees/v1.rs) | +| Contested document vote resolution fund | 20,000,000,000 | 0.2 | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-platform-version/src/version/fee/vote_resolution_fund_fees/v1.rs) | +| Contested document unlock fund | 400,000,000,000 | 4.0 | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-platform-version/src/version/fee/vote_resolution_fund_fees/v1.rs) | +| Single vote cost | 10,000,000 | 0.0001 | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-platform-version/src/version/fee/vote_resolution_fund_fees/v1.rs) | ## Identity Model @@ -164,20 +164,20 @@ Fees related to contested document voting. | Limit | Value | Description | Source | |-------|-------|-------------|--------| -| Max public keys per identity | 15,000 | Maximum keys an identity can have | [rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/identity/fields.rs#L7) | -| Max keys in creation | 6 | Keys allowed at identity creation | [rs-platform-version](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-platform-version/src/version/dpp_versions/dpp_state_transition_versions/v1.rs#L18) | -| Identity nonce value filter | 0xFFFFFFFFFF | 40-bit nonce filter | [rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/identity/identity_nonce.rs#L13) | -| Max missing identity revisions | 24 | Maximum revision gaps | [rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/identity/identity_nonce.rs#L15) | +| Max public keys per identity | 15,000 | Maximum keys an identity can have | [rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/identity/fields.rs#L7) | +| Max keys in creation | 6 | Keys allowed at identity creation | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-platform-version/src/version/dpp_versions/dpp_state_transition_versions/v1.rs#L18) | +| Identity nonce value filter | 0xFFFFFFFFFF | 40-bit nonce filter | [rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/identity/identity_nonce.rs#L13) | +| Max missing identity revisions | 24 | Maximum revision gaps | [rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/identity/identity_nonce.rs#L15) | ### Identity Create Fees | Requirement | Value | Description | Source | |-------------|-------|-------------|--------| -| Min asset lock balance | 200,000 duffs | 0.002 Dash minimum | [rs-platform-version](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-platform-version/src/version/dpp_versions/dpp_state_transition_versions/v1.rs#L20) | -| Min top-up balance | 50,000 duffs | 0.0005 Dash minimum | [rs-platform-version](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-platform-version/src/version/dpp_versions/dpp_state_transition_versions/v1.rs#L21) | -| Min address funding balance | 50,000 duffs | 0.0005 Dash minimum | [rs-platform-version](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-platform-version/src/version/dpp_versions/dpp_state_transition_versions/v1.rs#L22) | -| Min identity funding amount | 200,000 credits | Minimum for address-based creation | [rs-platform-version](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-platform-version/src/version/dpp_versions/dpp_state_transition_versions/v1.rs#L41) | -| Max asset-lock transaction inputs | 100 | Maximum Core inputs in an asset-lock transaction used to fund an identity or top-up (introduced in protocol v3 to prevent stuck funds; v1/v2 had no effective limit) | [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) | +| Min asset lock balance | 200,000 duffs | 0.002 Dash minimum | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-platform-version/src/version/dpp_versions/dpp_state_transition_versions/v1.rs#L20) | +| Min top-up balance | 50,000 duffs | 0.0005 Dash minimum | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-platform-version/src/version/dpp_versions/dpp_state_transition_versions/v1.rs#L21) | +| Min address funding balance | 50,000 duffs | 0.0005 Dash minimum | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-platform-version/src/version/dpp_versions/dpp_state_transition_versions/v1.rs#L22) | +| Min identity funding amount | 200,000 credits | Minimum for address-based creation | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-platform-version/src/version/dpp_versions/dpp_state_transition_versions/v1.rs#L42) | +| Max asset-lock transaction inputs | 100 | Maximum Core inputs in an asset-lock transaction used to fund an identity or top-up (introduced in protocol v3 to prevent stuck funds; v1/v2 had no effective limit) | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-platform-version/src/version/dpp_versions/dpp_state_transition_versions/v3.rs#L25) | ## Document & Data Contract Model @@ -185,20 +185,20 @@ Fees related to contested document voting. | Limit | Value | Description | Source | |-------|-------|-------------|--------| -| Max indexed string length | 63 characters | Maximum indexable string | [rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/data_contract/document_type/class_methods/try_from_schema/mod.rs#L23) | -| Max indexed byte array length | 255 bytes | Maximum indexable byte array | [rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/data_contract/document_type/class_methods/try_from_schema/mod.rs#L24) | -| Max indexed array items | 1,024 | Maximum items in indexed array | [rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/data_contract/document_type/class_methods/try_from_schema/mod.rs#L25) | -| Max index size | 255 bytes | Maximum total index size | [rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/data_contract/document_type/mod.rs#L38) | -| Default hash size | 32 bytes | Standard hash size | [rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/data_contract/document_type/mod.rs#L35) | -| Default float size | 8 bytes | Standard float size | [rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/data_contract/document_type/mod.rs#L36) | -| Empty tree storage size | 33 bytes | Storage for empty tree | [rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/data_contract/document_type/mod.rs#L37) | -| Storage flags size | 2 bytes | Size of storage flags | [rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/data_contract/document_type/mod.rs#L39) | +| Max indexed string length | 63 characters | Maximum indexable string | [rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/data_contract/document_type/class_methods/try_from_schema/mod.rs#L24) | +| Max indexed byte array length | 255 bytes | Maximum indexable byte array | [rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/data_contract/document_type/class_methods/try_from_schema/mod.rs#L25) | +| Max indexed array items | 1,024 | Maximum items in indexed array | [rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/data_contract/document_type/class_methods/try_from_schema/mod.rs#L26) | +| Max index size | 255 bytes | Maximum total index size | [rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/data_contract/document_type/mod.rs#L40) | +| Default hash size | 32 bytes | Standard hash size | [rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/data_contract/document_type/mod.rs#L37) | +| Default float size | 8 bytes | Standard float size | [rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/data_contract/document_type/mod.rs#L38) | +| Empty tree storage size | 33 bytes | Storage for empty tree | [rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/data_contract/document_type/mod.rs#L39) | +| Storage flags size | 2 bytes | Size of storage flags | [rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/data_contract/document_type/mod.rs#L41) | ### Data Contract Constants | Constant | Value | Description | Source | |----------|-------|-------------|--------| -| Initial contract version | 1 | Starting version number | [rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/data_contract/mod.rs#L76) | +| Initial contract version | 1 | Starting version number | [rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/data_contract/mod.rs#L76) | ### Data Contract Registration Fees @@ -206,15 +206,15 @@ One-time fees for registering data contracts and their components. | Component | Fee (Credits) | Fee (Dash) | Source | |-----------|---------------|------------|--------| -| Base contract registration | 10,000,000,000 | 0.1 | [rs-platform-version](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-platform-version/src/version/fee/data_contract_registration/v2.rs) | -| Document type registration | 2,000,000,000 | 0.02 | [rs-platform-version](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-platform-version/src/version/fee/data_contract_registration/v2.rs) | -| Non-unique index registration | 1,000,000,000 | 0.01 | [rs-platform-version](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-platform-version/src/version/fee/data_contract_registration/v2.rs) | -| Unique index registration | 1,000,000,000 | 0.01 | [rs-platform-version](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-platform-version/src/version/fee/data_contract_registration/v2.rs) | -| Contested index registration | 100,000,000,000 | 1.0 | [rs-platform-version](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-platform-version/src/version/fee/data_contract_registration/v2.rs) | -| Token registration | 10,000,000,000 | 0.1 | [rs-platform-version](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-platform-version/src/version/fee/data_contract_registration/v2.rs) | -| Token perpetual distribution | 10,000,000,000 | 0.1 | [rs-platform-version](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-platform-version/src/version/fee/data_contract_registration/v2.rs) | -| Token pre-programmed distribution | 10,000,000,000 | 0.1 | [rs-platform-version](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-platform-version/src/version/fee/data_contract_registration/v2.rs) | -| Search keyword (per keyword) | 10,000,000,000 | 0.1 | [rs-platform-version](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-platform-version/src/version/fee/data_contract_registration/v2.rs) | +| Base contract registration | 10,000,000,000 | 0.1 | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-platform-version/src/version/fee/data_contract_registration/v2.rs) | +| Document type registration | 2,000,000,000 | 0.02 | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-platform-version/src/version/fee/data_contract_registration/v2.rs) | +| Non-unique index registration | 1,000,000,000 | 0.01 | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-platform-version/src/version/fee/data_contract_registration/v2.rs) | +| Unique index registration | 1,000,000,000 | 0.01 | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-platform-version/src/version/fee/data_contract_registration/v2.rs) | +| Contested index registration | 100,000,000,000 | 1.0 | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-platform-version/src/version/fee/data_contract_registration/v2.rs) | +| Token registration | 10,000,000,000 | 0.1 | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-platform-version/src/version/fee/data_contract_registration/v2.rs) | +| Token perpetual distribution | 10,000,000,000 | 0.1 | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-platform-version/src/version/fee/data_contract_registration/v2.rs) | +| Token pre-programmed distribution | 10,000,000,000 | 0.1 | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-platform-version/src/version/fee/data_contract_registration/v2.rs) | +| Search keyword (per keyword) | 10,000,000,000 | 0.1 | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-platform-version/src/version/fee/data_contract_registration/v2.rs) | ### Tokens @@ -224,7 +224,7 @@ Tokens are defined within data contracts and share the same lifecycle, versionin | Limit | Value | Description | Source | |-------|-------|-------------|--------| -| Max token note length | 2,048 bytes | Maximum note/memo length | [rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/tokens/mod.rs#L19) | +| Max token note length | 2,048 bytes | Maximum note/memo length | [rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/tokens/mod.rs#L19) | #### Token Distribution Function Limits @@ -232,17 +232,17 @@ These limits apply to token perpetual distribution function parameters. | Parameter | Min | Max | Source | |-----------|-----|-----|--------| -| `MAX_DISTRIBUTION_PARAM` | 1 | 281,474,976,710,655 (2^48 - 1) | [rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/data_contract/associated_token/token_perpetual_distribution/distribution_function/mod.rs#L14) | -| `MAX_DISTRIBUTION_CYCLES_PARAM` | 1 | 32,767 (2^(63-48) - 1) | [rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/data_contract/associated_token/token_perpetual_distribution/distribution_function/mod.rs#L20) | -| Linear slope A | -255 | 256 | [rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/data_contract/associated_token/token_perpetual_distribution/distribution_function/mod.rs) | -| Polynomial M | -8 | 8 | [rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/data_contract/associated_token/token_perpetual_distribution/distribution_function/mod.rs) | -| Polynomial N | 0 | 32 | [rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/data_contract/associated_token/token_perpetual_distribution/distribution_function/mod.rs) | -| Polynomial A | -255 | 256 | [rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/data_contract/associated_token/token_perpetual_distribution/distribution_function/mod.rs) | -| Log A | -32,766 | 32,767 | [rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/data_contract/associated_token/token_perpetual_distribution/distribution_function/mod.rs) | -| Exponential A | 1 | 256 | [rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/data_contract/associated_token/token_perpetual_distribution/distribution_function/mod.rs) | -| Exponential M | -8 | 8 | [rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/data_contract/associated_token/token_perpetual_distribution/distribution_function/mod.rs) | -| Exponential N | 0 | 32 | [rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/data_contract/associated_token/token_perpetual_distribution/distribution_function/mod.rs) | -| Default step decreasing max cycles | 128 | 128 | [rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/data_contract/associated_token/token_perpetual_distribution/distribution_function/mod.rs#L22) | +| `MAX_DISTRIBUTION_PARAM` | 1 | 281,474,976,710,655 (2^48 - 1) | [rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/data_contract/associated_token/token_perpetual_distribution/distribution_function/mod.rs#L14) | +| `MAX_DISTRIBUTION_CYCLES_PARAM` | 1 | 32,767 (2^(63-48) - 1) | [rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/data_contract/associated_token/token_perpetual_distribution/distribution_function/mod.rs#L20) | +| Linear slope A | -255 | 256 | [rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/data_contract/associated_token/token_perpetual_distribution/distribution_function/mod.rs) | +| Polynomial M | -8 | 8 | [rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/data_contract/associated_token/token_perpetual_distribution/distribution_function/mod.rs) | +| Polynomial N | 0 | 32 | [rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/data_contract/associated_token/token_perpetual_distribution/distribution_function/mod.rs) | +| Polynomial A | -255 | 256 | [rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/data_contract/associated_token/token_perpetual_distribution/distribution_function/mod.rs) | +| Log A | -32,766 | 32,767 | [rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/data_contract/associated_token/token_perpetual_distribution/distribution_function/mod.rs) | +| Exponential A | 1 | 256 | [rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/data_contract/associated_token/token_perpetual_distribution/distribution_function/mod.rs) | +| Exponential M | -8 | 8 | [rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/data_contract/associated_token/token_perpetual_distribution/distribution_function/mod.rs) | +| Exponential N | 0 | 32 | [rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/data_contract/associated_token/token_perpetual_distribution/distribution_function/mod.rs) | +| Default step decreasing max cycles | 128 | 128 | [rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/data_contract/associated_token/token_perpetual_distribution/distribution_function/mod.rs#L22) | ## Address System @@ -253,42 +253,42 @@ These limits apply to token perpetual distribution function parameters. | Constant | Value | Description | Source | |----------|-------|-------------|--------| -| Address hash size | 20 bytes | Size of address hash | [rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/address_funds/platform_address.rs#L22) | -| Platform HRP (mainnet) | "dash" | Human-readable prefix | [rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/address_funds/platform_address.rs#L184) | -| Platform HRP (non-mainnet) | "tdash" | Human-readable prefix used for testnet, devnet, and regtest | [rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/address_funds/platform_address.rs#L186) | -| P2PKH address type (bech32m) | 0xb0 (176) | Pay-to-public-key-hash bech32m encoding type byte | [rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/address_funds/platform_address.rs#L190) | -| P2SH address type (bech32m) | 0x80 (128) | Pay-to-script-hash bech32m encoding type byte | [rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/address_funds/platform_address.rs#L192) | +| Address hash size | 20 bytes | Size of address hash | [rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/address_funds/platform_address.rs#L22) | +| Platform HRP (mainnet) | "dash" | Human-readable prefix | [rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/address_funds/platform_address.rs#L184) | +| Platform HRP (non-mainnet) | "tdash" | Human-readable prefix used for testnet, devnet, and regtest | [rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/address_funds/platform_address.rs#L186) | +| P2PKH address type (bech32m) | 0xb0 (176) | Pay-to-public-key-hash bech32m encoding type byte | [rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/address_funds/platform_address.rs#L205) | +| P2SH address type (bech32m) | 0x80 (128) | Pay-to-script-hash bech32m encoding type byte | [rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/address_funds/platform_address.rs#L207) | ### Transaction Limits | Limit | Value | Description | Source | |-------|-------|-------------|--------| -| Min output amount | 500,000 credits | Minimum output per address | [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#L39) | -| Min input amount | 100,000 credits | Minimum input per address | [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#L40) | -| 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) | +| Min output amount | 500,000 credits | Minimum output per address | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-platform-version/src/version/dpp_versions/dpp_state_transition_versions/v3.rs#L40) | +| Min input amount | 100,000 credits | Minimum input per address | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-platform-version/src/version/dpp_versions/dpp_state_transition_versions/v3.rs#L41) | +| Max fee strategies | 4 | Maximum fee strategy steps | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-platform-version/src/version/dpp_versions/dpp_state_transition_versions/v3.rs#L46) | +| Max address inputs | 16 | Maximum input addresses per address-based transition | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-platform-version/src/version/dpp_versions/dpp_state_transition_versions/v3.rs#L44) | +| Max address outputs | 128 | Maximum output addresses per address-based transition | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-platform-version/src/version/dpp_versions/dpp_state_transition_versions/v3.rs#L45) | +| Max asset lock transaction inputs | 100 | Maximum L1 transaction inputs in an asset lock proof | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-platform-version/src/version/dpp_versions/dpp_state_transition_versions/v3.rs#L25) | ## Epoch and Time Constants | Constant | Value | Description | Source | |----------|-------|-------------|--------| -| Genesis epoch index | 0 | First epoch number | [rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/fee/epoch/mod.rs#L45) | -| Perpetual storage eras | 50 | Number of storage eras (~50 years) | [rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/fee/epoch/mod.rs#L49) | -| Default epochs per era | 40 | Epochs in each era (~1 year) | [rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/fee/epoch/mod.rs#L51) | -| Epoch key offset | 256 | Offset for epoch keys | [rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/block/epoch/mod.rs#L6) | -| Max epoch | 65,279 | Maximum epoch number (u16::MAX - 256) | [rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/block/epoch/mod.rs#L9) | +| Genesis epoch index | 0 | First epoch number | [rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/fee/epoch/mod.rs#L45) | +| Perpetual storage eras | 50 | Number of storage eras (~50 years) | [rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/fee/epoch/mod.rs#L49) | +| Default epochs per era | 40 | Epochs in each era (~1 year) | [rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/fee/epoch/mod.rs#L51) | +| Epoch key offset | 256 | Offset for epoch keys | [rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/block/epoch/mod.rs#L6) | +| Max epoch | 65,279 | Maximum epoch number (u16::MAX - 256) | [rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/block/epoch/mod.rs#L9) | ## Refund Constants | Constant | Value | Description | Source | |----------|-------|-------------|--------| -| Min refund limit | 32 bytes | Minimum bytes for refund | [rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/fee/fee_result/refunds.rs#L23) | +| Min refund limit | 32 bytes | Minimum bytes for refund | [rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/fee/fee_result/refunds.rs#L23) | ## Withdrawal Constants | Constant | Value | Description | Source | |----------|-------|-------------|--------| -| Min withdrawal amount | 190,000 credits | ASSET_UNLOCK_TX_SIZE (190) × MIN_CORE_FEE_PER_BYTE (1) × CREDITS_PER_DUFF (1,000) | [rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_withdrawal_transition/mod.rs#L44-L45) | -| Min core fee per byte | 1 | Must be Fibonacci number | [rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_withdrawal_transition/mod.rs#L41) | +| Min withdrawal amount | 190,000 credits | ASSET_UNLOCK_TX_SIZE (190) × MIN_CORE_FEE_PER_BYTE (1) × CREDITS_PER_DUFF (1,000) | [rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_withdrawal_transition/mod.rs#L48-L49) | +| Min core fee per byte | 1 | Must be Fibonacci number | [rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_withdrawal_transition/mod.rs#L41) | diff --git a/docs/protocol-ref/shielded-pool.md b/docs/protocol-ref/shielded-pool.md index c4b10cfa3..a43b6f802 100644 --- a/docs/protocol-ref/shielded-pool.md +++ b/docs/protocol-ref/shielded-pool.md @@ -5,14 +5,14 @@ # Shielded Pool :::{attention} -Shielded state transitions were [enabled in Protocol Version 12](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-platform-version/src/version/feature_initial_protocol_versions.rs#L4). They use the [Orchard](https://zips.z.cash/protocol/protocol.pdf) shielded protocol to move credits into, within, and out of a pool that hides amounts, senders, and recipients. +Shielded state transitions were [enabled in Protocol Version 12](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-platform-version/src/version/feature_initial_protocol_versions.rs#L4). They use the [Orchard](https://zips.z.cash/protocol/protocol.pdf) shielded protocol to move credits into, within, and out of a pool that hides amounts, senders, and recipients. For the conceptual overview of how the pool works and when to use it, see [Shielded Pool](../explanations/shielded-pool.md). ::: ## Overview -The shielded pool is implemented through five state transition types that share a common Orchard bundle structure: +The shielded pool is implemented through state transition types that share a common Orchard bundle structure: | Type | Name | Description | | --- | --- | --- | @@ -21,8 +21,9 @@ The shielded pool is implemented through five state transition types that share | 17 | [Unshield](#unshield) | Move credits from the pool to a Platform address | | 18 | [Shield from Asset Lock](#shield-from-asset-lock) | Move credits from an L1 asset lock directly into the pool | | 19 | [Shielded Withdrawal](#shielded-withdrawal) | Move credits from the pool back to Dash Core (L1) | +| 20 | [Identity Create From Shielded Pool](#identity-create-from-shielded-pool) | Create a new identity funded from the shielded pool | -All five transitions share a common Orchard bundle (anchor, actions, proof, binding signature). Transitions that touch the transparent side (Shield, Unshield, Shield from Asset Lock, Shielded Withdrawal) layer the transparent fields on top of that bundle. Shielded Transfer has no transparent surface beyond the bundle itself. +All transitions share a common Orchard bundle (anchor, actions, proof, binding signature). Transitions that touch the transparent side (Shield, Unshield, Shield from Asset Lock, Shielded Withdrawal, Identity Create From Shielded Pool) layer the transparent fields on top of that bundle. Shielded Transfer has no transparent surface beyond the bundle itself. ## Common Components @@ -37,7 +38,7 @@ Every shielded transition includes an Orchard bundle proving that a set of note | proof | array of bytes | Varies | Halo 2 zero-knowledge proof that the actions are valid | | bindingSignature | array of bytes | 64 bytes | RedPallas signature binding the bundle's actions to its net value balance | -See the [Orchard bundle primitives in rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/shielded/mod.rs). +See the [Orchard bundle primitives in rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/shielded/mod.rs). ### Actions @@ -54,9 +55,9 @@ Each action publishes: | cvNet | array of bytes | 32 bytes | Net value commitment (Pedersen commitment to the action's value contribution) | | spendAuthSig | array of bytes | 64 bytes | Per-action spend authorization signature — see [Shielded Transition Signing](#shielded-transition-signing) | -Permanent storage cost per action is [312 bytes](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/shielded/mod.rs#L13-L16) (280 bytes in the note commitment tree + 32 bytes in the nullifier tree). +Permanent storage cost per action is [344 bytes](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/shielded/mod.rs#L32-L58) (312 bytes in the note commitment tree + 32 bytes in the nullifier tree). -See the [serialized action implementation in rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/shielded/mod.rs). +See the [serialized action implementation in rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/shielded/mod.rs). ### Anchors @@ -70,7 +71,7 @@ Transitions with transparent fields (Unshield, Shielded Withdrawal, etc.) bind t SHA-256(SIGHASH_DOMAIN || bundle_commitment || extra_data) ``` -This prevents replay attacks where an attacker substitutes transparent fields while reusing a valid Orchard bundle. See the [platform sighash implementation in rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/shielded/mod.rs#L20-L40). +This prevents replay attacks where an attacker substitutes transparent fields while reusing a valid Orchard bundle. See the [platform sighash implementation in rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/shielded/sighash.rs#L21-L41). ## Shielded State Transition Details @@ -81,7 +82,7 @@ Move credits from one or more [Platform addresses](address-system.md#platform-ad | Field | Type | Size | Description | | --- | --- | --- | --- | | inputs | map | Varies | Map of source [Platform addresses](address-system.md#platform-address) to (`AddressNonce`, max contribution in credits) pairs | -| actions | array | Varies | Orchard [actions](#actions) (output-only — Shield creates new notes without consuming prior ones) | +| actions | array | Varies | Orchard [actions](#actions) (spend-output pairs). Shield brings value in from the transparent inputs, so its actions create new notes rather than consuming prior pool notes | | amount | unsigned integer | 64 bits | Credits entering the shielded pool | | anchor | array of bytes | 32 bytes | [Anchor](#anchors) | | proof | array of bytes | Varies | Halo 2 proof | @@ -94,7 +95,7 @@ Move credits from one or more [Platform addresses](address-system.md#platform-ad Maximum actions per transition: [`max_shielded_transition_actions`](protocol-constants.md). Address witness signatures are excluded from the signable bytes used by the platform sighash. ::: -See the [implementation in rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/state_transition/state_transitions/shielded/shield_transition/). +See the [implementation in rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/state_transition/state_transitions/shielded/shield_transition/). ### Shielded Transfer @@ -112,7 +113,7 @@ Move credits within the pool between notes. There is no transparent surface — Maximum actions per transition: [`max_shielded_transition_actions`](protocol-constants.md). ::: -See the [implementation in rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/state_transition/state_transitions/shielded/shielded_transfer_transition/). +See the [implementation in rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/state_transition/state_transitions/shielded/shielded_transfer_transition/). ### Unshield @@ -131,7 +132,7 @@ Move credits from the pool to a [Platform address](address-system.md#platform-ad The `outputAddress` is bound to the Orchard bundle through the [platform sighash](#platform-sighash) to prevent substitution attacks. Maximum actions per transition: [`max_shielded_transition_actions`](protocol-constants.md). ::: -See the [implementation in rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/state_transition/state_transitions/shielded/unshield_transition/). +See the [implementation in rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/state_transition/state_transitions/shielded/unshield_transition/). ### Shield from Asset Lock @@ -145,13 +146,14 @@ Move credits from a Dash Core (L1) asset-lock transaction directly into the shie | anchor | array of bytes | 32 bytes | [Anchor](#anchors) | | proof | array of bytes | Varies | Halo 2 proof | | bindingSignature | array of bytes | 64 bytes | RedPallas binding signature | +| surplusOutput | Platform address | Varies | (Optional) Platform address that receives the asset-lock surplus (`asset_lock_value − value_balance − fee`). When omitted, the surplus is added to the fee pools, capped at `shielded_implicit_fee_cap`. Bound to the ECDSA signature so it cannot be redirected | | signature | array of bytes | 65 bytes | ECDSA signature over the signable bytes proving control of the asset-locked output | :::{note} `valueBalance` must be greater than zero and at most `i64::MAX`. The ECDSA signature is excluded from the signable bytes used by the platform sighash. Maximum actions per transition: [`max_shielded_transition_actions`](protocol-constants.md). ::: -See the [implementation in rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/state_transition/state_transitions/shielded/shield_from_asset_lock_transition/). +See the [implementation in rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/state_transition/state_transitions/shielded/shield_from_asset_lock_transition/). ### Shielded Withdrawal @@ -172,11 +174,32 @@ Move credits from the pool back to Dash Core (L1). The funds leave Platform enti Transparent fields (`coreFeePerByte`, `pooling`, `outputScript`) are bound to the Orchard bundle through the [platform sighash](#platform-sighash). Maximum actions per transition: [`max_shielded_transition_actions`](protocol-constants.md). ::: -See the [implementation in rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/state_transition/state_transitions/shielded/shielded_withdrawal_transition/). +See the [implementation in rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/state_transition/state_transitions/shielded/shielded_withdrawal_transition/). + +### Identity Create From Shielded Pool + +Create a new identity funded directly from the shielded pool. The spend nullifiers fund a fixed exit denomination; any change re-enters the pool as an ordinary output note. The new identity carries the same public keys as an ordinary [Identity Create](identity.md#identity-create). + +| Field | Type | Size | Description | +| --- | --- | --- | --- | +| publicKeys | array | Varies | The public keys of the new identity (1..=`max_public_keys_in_creation`), carried exactly as in [Identity Create](identity.md#identity-create) | +| denomination | unsigned integer | 64 bits | The fixed exit denomination (in credits) leaving the pool. Must equal the Orchard bundle's value balance exactly and be a member of the versioned denomination set | +| actions | array | Varies | Orchard [actions](#actions) (spend-output pairs); the spend nullifiers fund the exit | +| anchor | array of bytes | 32 bytes | [Anchor](#anchors) | +| proof | array of bytes | Varies | Halo 2 proof | +| bindingSignature | array of bytes | 64 bytes | RedPallas binding signature | +| sendToAddressOnCreationFailure | Platform address | Varies | Fallback [Platform address](address-system.md#platform-address) credited (minus a penalty) if identity creation fails a stateful check. The spend is still final — the denomination leaves the pool regardless | +| identityId | array of bytes | 32 bytes | The id of the new identity, derived as `double_sha256` over the sorted spend nullifiers, then re-derived and checked at consensus | + +:::{note} +The new identity's id is derived from the sorted set of spend nullifiers, making it unique and single-use. The public keys, `denomination`, `sendToAddressOnCreationFailure`, and `identityId` are committed into the Orchard bundle (via `extra_sighash_data`), so the bundle cannot be redirected to a different identity. Maximum actions per transition: [`max_shielded_transition_actions`](protocol-constants.md). +::: + +See the [implementation in rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/state_transition/state_transitions/shielded/identity_create_from_shielded_pool_transition/). ## Shielded Transition Signing -Shielded transitions are not signed by an identity public key. The 65-byte `signature` and the `signaturePublicKeyId` fields listed in the [common fields](state-transition.md#common-fields) for identity-signed transitions do not appear on Unshield, Shielded Transfer, or Shielded Withdrawal. Authorization is instead carried by cryptographic primitives attached to the Orchard bundle and, where applicable, to the transparent side of the transition. +Shielded transitions are not signed by an identity public key. The identity-signed `signature` and `signaturePublicKeyId` fields listed in the [common fields](state-transition.md#common-fields) for identity-signed transitions do not appear on any shielded transition. Authorization is instead carried by cryptographic primitives attached to the Orchard bundle and, where applicable, to the transparent side of the transition. This includes the asset-lock ECDSA `signature` carried by [Shield from Asset Lock](#shield-from-asset-lock) described below. ### Orchard bundle signatures @@ -187,7 +210,7 @@ Every shielded transition includes: ### Platform sighash -Transitions that include transparent fields (Shield, Unshield, Shield from Asset Lock, Shielded Withdrawal) bind those fields to the Orchard bundle through the [platform sighash](#platform-sighash). Any modification to the transparent fields invalidates the Orchard signatures, preventing replay attacks that substitute transparent fields while reusing a valid bundle. +Unshield, Shielded Withdrawal, and Identity Create From Shielded Pool bind their transparent fields to the Orchard bundle through the [platform sighash](#platform-sighash) (non-empty `extra_sighash_data`). Any modification to those transparent fields invalidates the Orchard signatures, preventing replay attacks that substitute transparent fields while reusing a valid bundle. Shield and Shield from Asset Lock use empty `extra_sighash_data`; their transparent side is authorized by address witnesses (Shield) or the asset-lock ECDSA signature (Shield from Asset Lock) over the signable bytes instead. ### Transparent signatures (Shield, Shield from Asset Lock) diff --git a/docs/protocol-ref/state-transition.md b/docs/protocol-ref/state-transition.md index e52209e7e..74d9b82f7 100644 --- a/docs/protocol-ref/state-transition.md +++ b/docs/protocol-ref/state-transition.md @@ -13,20 +13,20 @@ ### Fees -State transition fees are paid via the credits established when an identity is created. Credits are created at a rate of [1000 credits/satoshi](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/balances/credits.rs#L42). Fees for actions vary based on parameters related to storage and computational effort that are defined in [rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/fee/default_costs/constants.rs). +State transition fees are paid via the credits established when an identity is created. Credits are created at a rate of [1000 credits/satoshi](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/balances/credits.rs#L42). Fees for actions vary based on parameters related to storage and computational effort that are defined in [rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/fee/default_costs/constants.rs). ### Size -State transitions are limited to a maximum size of [20 KB](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-platform-version/src/version/system_limits/v1.rs#L6). +State transitions are limited to a maximum size of [20 KiB / 20,480 bytes](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-platform-version/src/version/system_limits/v1.rs#L6). ### Common Fields -The list of common fields used by multiple state transitions is defined in [rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/state_transition/state_transitions/common_fields.rs). All state transitions include the following fields: +The list of common fields used by multiple state transitions is defined in [rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/state_transition/state_transitions/common_fields.rs). All state transitions include the following fields: | Field | Type | Size | Description | | --------------- | -------------- | ---- | ----------- | | $version | unsigned integer | 16 bits | The state transition format version (FeatureVersion). Currently `0` for most transitions, `1` for Batch. This is not the global platform protocol version, which is negotiated separately. | -| type | unsigned integer | 8 bits | State transition type discriminator (defined in [rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/state_transition/state_transition_types.rs#L21)). See [State Transition Types](#state-transition-types) for the full list. | +| type | unsigned integer | 8 bits | State transition type discriminator (defined in [rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/state_transition/state_transition_types.rs#L21)). See [State Transition Types](#state-transition-types) for the full list. | | userFeeIncrease | unsigned integer | 16 bits | Extra fee to prioritize processing if the mempool is full. Typically set to zero. | | signature | array of bytes | 65 bytes |Signature of state transition data | @@ -42,7 +42,7 @@ Additionally, all state transitions except the identity create and topup state t ## State Transition Types -Dash Platform Protocol defines the following [state transition types](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/state_transition/state_transition_types.rs#L21-L43). Most are documented in detail on the protocol reference page for the feature they operate on. Batch and Masternode Vote do not have a dedicated feature page; their formats are documented inline below. +Dash Platform Protocol defines the following [state transition types](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/state_transition/state_transition_types.rs#L21-L44). Most are documented in detail on the protocol reference page for the feature they operate on. Batch and Masternode Vote do not have a dedicated feature page; their formats are documented inline below. | Type | Name | Documented in | | --- | --- | --- | @@ -66,15 +66,16 @@ Dash Platform Protocol defines the following [state transition types](https://gi | 17 | Unshield | [Unshield](shielded-pool.md#unshield) | | 18 | Shield from Asset Lock | [Shield from Asset Lock](shielded-pool.md#shield-from-asset-lock) | | 19 | Shielded Withdrawal | [Shielded Withdrawal](shielded-pool.md#shielded-withdrawal) | +| 20 | Identity Create From Shielded Pool | [Identity Create From Shielded Pool](shielded-pool.md#identity-create-from-shielded-pool) | ### Batch | Field | Type | Size | Description | | ----------- | -------------- | ---- | ----------- | | ownerId | array of bytes | 32 bytes | [Identity](../protocol-ref/identity.md) submitting the document(s) or token action(s) | -| transitions | array of transition objects | Varies | A batch of [document](../protocol-ref/document.md#document-overview) or token actions (currently limited to [1 object per batch](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-platform-version/src/version/system_limits/v1.rs#L7)) | +| transitions | array of transition objects | Varies | A batch of [document](../protocol-ref/document.md#document-overview) or token actions (currently limited to [1 object per batch](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-platform-version/src/version/system_limits/v1.rs#L20)) | -More detailed information about the `transitions` array can be found in the [document section](../protocol-ref/document.md). See the implementation in [rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v1/mod.rs#L31-L39). +More detailed information about the `transitions` array can be found in the [document section](../protocol-ref/document.md). See the implementation in [rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v1/mod.rs#L31-L39). ### Masternode Vote @@ -82,10 +83,10 @@ More detailed information about the `transitions` array can be found in the [doc | --------------- | -------------- | ---- | ----------- | | proTxHash | array of bytes | 32 bytes | An identifier based on a masternode or evonode's [provider registration transaction](inv:user:std#ref-txs-proregtx) hash | | voterIdentityId | array of bytes | 32 bytes | The voter's [Identity ID](../protocol-ref/identity.md#identity-id). This will be a masternode identity based on the protx hash. | -| vote | [Vote](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/voting/votes/mod.rs#L25-L27) | Varies | Vote information | +| vote | [Vote](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/voting/votes/mod.rs#L25-L27) | Varies | Vote information | | nonce | unsigned integer | 64 bits | Identity nonce for this transition to prevent replay attacks | -See the implementation in [rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/state_transition/state_transitions/identity/masternode_vote_transition/v0/mod.rs#L43-L53). +See the implementation in [rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/state_transition/state_transitions/identity/masternode_vote_transition/v0/mod.rs#L43-L53). ## State Transition Signing @@ -99,7 +100,7 @@ transition type: | [Identity](#signing-with-identity) | Batch, Contract create, Contract update, Identity update, Identity credit transfer, Identity credit transfer to addresses, Identity credit withdrawal, Masternode vote | | [Asset lock](#signing-with-asset-lock) | Identity create, Identity topup, Address funding from asset lock\*, Shield from asset lock\*\* | | [Address witness](#signing-with-address-witness) | Identity create from addresses, Identity topup from addresses, Address funds transfer, Address credit withdrawal, Address funding from asset lock\*, Shield\*\* | -| [Shielded (Orchard)](shielded-pool.md#shielded-transition-signing) | Shield\*\*, Shielded transfer, Unshield, Shield from asset lock\*\*, Shielded withdrawal | +| [Shielded (Orchard)](shielded-pool.md#shielded-transition-signing) | Shield\*\*, Shielded transfer, Unshield, Shield from asset lock\*\*, Shielded withdrawal, Identity create from shielded pool | \* Address funding from asset lock requires both an asset lock signature and address witnesses (`input_witnesses`). @@ -126,11 +127,21 @@ process consists of the following steps: ### Signing with Identity Most state transitions must be signed by a private key associated with the identity creating the -state transition. Each identity must have at least two keys: a primary key ([security -level](./identity.md#public-key-securitylevel) `0`) that is only used when signing [identity -update](identity.md#identity-update) state transitions and an additional key ([security -level](./identity.md#public-key-securitylevel) `2`) that is used to sign all other state -transitions. +state transition. Each transition requires a key of a minimum [security +level](./identity.md#public-key-securitylevel); some accept a range of levels. Only [identity +update](identity.md#identity-update) requires a MASTER key (level `0`); every other transition +requires at least a CRITICAL key (level `1`). + +| State transition | Accepted security level(s) | +| ---------------- | -------------------------- | +| Identity update | MASTER (`0`) | +| Identity credit transfer, Identity credit withdrawal, Data contract update | CRITICAL (`1`) | +| Data contract create | CRITICAL or HIGH (`1`-`2`) | +| Batch (document/token), Masternode vote | CRITICAL, HIGH, or MEDIUM (`1`-`3`) | + +Within a batch, token transfers are restricted to a CRITICAL (`1`) key. An identity must therefore +hold a MASTER key for identity updates and, for the other transitions it will sign, a key meeting +that transition's minimum level. The process to sign state transitions using an identity consists of the following steps: @@ -184,15 +195,15 @@ This table shows the fields that must be excluded when creating state transition | State transition | Signature | Signature public key ID | Identity ID | Identity public key signature(s) | | - | :-: | :-: | :-: | :-: | -| [Batch](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v1/mod.rs#L35-L38) | Exclude | Exclude | N/A | N/A | -| [Contract create](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/state_transition/state_transitions/contract/data_contract_create_transition/v0/mod.rs#L44-L47) | Exclude | Exclude | N/A | N/A | -| [Contract update](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/state_transition/state_transitions/contract/data_contract_update_transition/v0/mod.rs#L43-L46) | Exclude | Exclude | N/A | N/A | -| [Identity create](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_create_transition/v0/mod.rs#L53-L57) | Exclude | N/A | Exclude | [Exclude](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/state_transition/state_transitions/identity/public_key_in_creation/v0/mod.rs#L50-L51) | -| [Identity topup](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_topup_transition/v0/mod.rs#L48-L49) | Exclude | N/A | N/A | N/A | -| [Identity update](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_update_transition/v0/mod.rs#L67-L71) | Exclude | Exclude | N/A | [Exclude for any keys being added by the state transition](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/state_transition/state_transitions/identity/public_key_in_creation/v0/mod.rs#L50-L51) | -| [Identity credit transfer](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_transfer_transition/v0/mod.rs#L49-L52) | Exclude | Exclude | N/A | N/A | -| [Identity credit withdrawal](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_withdrawal_transition/v1/mod.rs#L44-L47) | Exclude | Exclude | N/A | N/A | -| [Masternode vote](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/state_transition/state_transitions/identity/masternode_vote_transition/v0/mod.rs#L49-L52) | Exclude | Exclude | N/A | N/A | +| [Batch](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v1/mod.rs#L35-L38) | Exclude | Exclude | N/A | N/A | +| [Contract create](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/state_transition/state_transitions/contract/data_contract_create_transition/v0/mod.rs#L44-L47) | Exclude | Exclude | N/A | N/A | +| [Contract update](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/state_transition/state_transitions/contract/data_contract_update_transition/v0/mod.rs#L43-L46) | Exclude | Exclude | N/A | N/A | +| [Identity create](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_create_transition/v0/mod.rs#L53-L57) | Exclude | N/A | Exclude | [Exclude](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/state_transition/state_transitions/identity/public_key_in_creation/v0/mod.rs#L50-L51) | +| [Identity topup](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_topup_transition/v0/mod.rs#L48-L49) | Exclude | N/A | N/A | N/A | +| [Identity update](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_update_transition/v0/mod.rs#L67-L71) | Exclude | Exclude | N/A | [Exclude for any keys being added by the state transition](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/state_transition/state_transitions/identity/public_key_in_creation/v0/mod.rs#L50-L51) | +| [Identity credit transfer](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_transfer_transition/v0/mod.rs#L49-L52) | Exclude | Exclude | N/A | N/A | +| [Identity credit withdrawal](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_withdrawal_transition/v1/mod.rs#L48-L51) | Exclude | Exclude | N/A | N/A | +| [Masternode vote](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/state_transition/state_transitions/identity/masternode_vote_transition/v0/mod.rs#L49-L52) | Exclude | Exclude | N/A | N/A | :::{note} The table above does not cover shielded transitions, which do not carry transition-level `signature` or `signaturePublicKeyId` fields. See [Signing Shielded Transitions](#signing-shielded-transitions). diff --git a/docs/protocol-ref/token.md b/docs/protocol-ref/token.md index 26cd390b0..6e214d961 100644 --- a/docs/protocol-ref/token.md +++ b/docs/protocol-ref/token.md @@ -39,13 +39,13 @@ The following fields are included in all token transitions: | $tokenContractPosition | unsigned integer | 16 bits | Position of the token within the contract | | $dataContractId | array | 32 bytes | Data contract ID [generated](../protocol-ref/data-contract.md#data-contract-id) from the data contract's `ownerId` and `entropy` | | [$tokenId](#token-id) | array | 32 bytes | Token ID generated from the data contract ID and the token position | -| usingGroupInfo | [GroupStateTransitionInfo object](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/group/mod.rs#L42-L50) | Varies | Optional field indicating group multi-party authentication rules | +| usingGroupInfo | [GroupStateTransitionInfo object](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/group/mod.rs#L42-L50) | Varies | Optional field indicating group multi-party authentication rules | -Each token transition must comply with the [token base transition defined in rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_base_transition/v0/mod.rs#L42-L60). +Each token transition must comply with the [token base transition defined in rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_base_transition/v0/mod.rs#L42-L60). #### Token id -The `$tokenId` is created by double sha256 hashing the token `$dataContractId` and `$tokenContractPosition` with a byte vector of the string "dash_token" as shown in [rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/tokens/mod.rs#L27-L32). +The `$tokenId` is created by double sha256 hashing the token `$dataContractId` and `$tokenContractPosition` with a byte vector of the string "dash_token" as shown in [rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/tokens/mod.rs#L27-L32). ```rust // From the Rust reference implementation (rs-dpp) @@ -60,7 +60,7 @@ pub fn calculate_token_id(contract_id: &[u8; 32], token_pos: TokenContractPositi #### Token Transition Action -The token transition actions [defined in rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transition_action_type.rs#L15-L48) indicate what operation platform should perform with the provided transition data. +The token transition actions [defined in rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transition_action_type.rs#L15-L48) indicate what operation platform should perform with the provided transition data. | Action | Name | Description | | :-: | - | - | @@ -82,7 +82,7 @@ The numeric action codes above are for client-side reference ordering only. `Tok ### Token Notes -Some token transitions include optional notes fields. The maximum note length for these fields is [2048 bytes](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/tokens/mod.rs#L19). +Some token transitions include optional notes fields. The maximum note length for these fields is [2048 bytes](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/tokens/mod.rs#L19). ### Token Burn Transition @@ -93,7 +93,7 @@ The token burn transition extends the [base transition](#token-base-transition) | burnAmount | unsigned integer | 64 bits | Number of tokens to be burned | | publicNote | string | [<= 2048 bytes](#token-notes) | Optional public note | -Each token burn transition must comply with the [token burn transition defined in rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_burn_transition/v0/mod.rs#L22-L32). +Each token burn transition must comply with the [token burn transition defined in rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_burn_transition/v0/mod.rs#L22-L32). ### Token Mint Transition @@ -105,7 +105,7 @@ The token mint transition extends the [base transition](#token-base-transition) | amount | unsigned integer | 64 bits | Number of tokens to mint | | publicNote | string | [<= 2048 bytes](#token-notes) | Optional public note | -Each token mint transition must comply with the [token mint transition defined in rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_mint_transition/v0/mod.rs#L23-L37). +Each token mint transition must comply with the [token mint transition defined in rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_mint_transition/v0/mod.rs#L23-L37). ### Token Transfer Transition @@ -116,10 +116,10 @@ The token transfer transition extends the [base transition](#token-base-transiti | amount | unsigned integer | 64 bits | Number of tokens to transfer | | recipientId | array | 32 bytes | Identity ID of the recipient | | publicNote | string | [<= 2048 bytes](#token-notes) | Optional public note | -| sharedEncryptedNote | [SharedEncryptedNote object](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/tokens/mod.rs#L20) | [<= 2048 bytes](#token-notes) | Optional shared encrypted note | -| privateEncryptedNote | [PrivateEncryptedNote object](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/tokens/mod.rs#L21-L25) | [<= 2048 bytes](#token-notes) | Optional private encrypted note | +| sharedEncryptedNote | [SharedEncryptedNote object](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/tokens/mod.rs#L20) | [<= 2048 bytes](#token-notes) | Optional shared encrypted note | +| privateEncryptedNote | [PrivateEncryptedNote object](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/tokens/mod.rs#L21-L25) | [<= 2048 bytes](#token-notes) | Optional private encrypted note | -Each token transfer transition must comply with the [token transfer transition defined in rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transfer_transition/v0/mod.rs#L30-L46). +Each token transfer transition must comply with the [token transfer transition defined in rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transfer_transition/v0/mod.rs#L30-L46). ### Token Freeze Transition @@ -130,7 +130,7 @@ The token freeze transition extends the [base transition](#token-base-transition | frozenIdentityId | array | 32 bytes | Identity ID of the account to be frozen | | publicNote | string | [<= 2048 bytes](#token-notes) | Optional public note | -Each token freeze transition must comply with the [token freeze transition defined in rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_freeze_transition/v0/mod.rs#L19-L29). +Each token freeze transition must comply with the [token freeze transition defined in rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_freeze_transition/v0/mod.rs#L19-L29). ### Token Unfreeze Transition @@ -141,7 +141,7 @@ The token unfreeze transition extends the [base transition](#token-base-transiti | frozenIdentityId | array | 32 bytes | Identity ID of the account to be unfrozen | | publicNote | string | [<= 2048 bytes](#token-notes) | Optional public note | -Each token unfreeze transition must comply with the [token unfreeze transition defined in rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_unfreeze_transition/v0/mod.rs#L19-L29). +Each token unfreeze transition must comply with the [token unfreeze transition defined in rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_unfreeze_transition/v0/mod.rs#L19-L29). ### Token Destroy Frozen Funds Transition @@ -152,7 +152,7 @@ The token destroy frozen funds transition extends the [base transition](#token-b | frozenIdentityId | array | 32 bytes | Identity ID of the account whose frozen balance should be destroyed | | publicNote | string | [<= 2048 bytes](#token-notes) | Optional public note | -Each token destroy frozen funds transition must comply with the [token destroy frozen funds transition defined in rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_destroy_frozen_funds_transition/v0/mod.rs#L17-L25). +Each token destroy frozen funds transition must comply with the [token destroy frozen funds transition defined in rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_destroy_frozen_funds_transition/v0/mod.rs#L17-L25). ### Token Claim Transition @@ -160,10 +160,10 @@ The token claim transition extends the [base transition](#token-base-transition) | Field | Type | Size | Description | | ----- | ---- | ---- | ----------- | -| distributionType | [TokenDistributionType enum](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/data_contract/associated_token/token_distribution_key.rs#L18-L25) | Varies | Type of [token distribution](../explanations/tokens.md#distribution-rules) targeted (`0` = PreProgrammed, `1` = Perpetual) | +| distributionType | [TokenDistributionType enum](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/data_contract/associated_token/token_distribution_key.rs#L18-L25) | Varies | Type of [token distribution](../explanations/tokens.md#distribution-rules) targeted (`0` = PreProgrammed, `1` = Perpetual) | | publicNote | string | [<= 2048 bytes](#token-notes) | Optional public note (only saved for historical contracts) | -Each token claim transition must comply with the [token claim transition defined in rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_claim_transition/v0/mod.rs#L18-L26). +Each token claim transition must comply with the [token claim transition defined in rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_claim_transition/v0/mod.rs#L18-L26). ### Token Emergency Action Transition @@ -171,10 +171,10 @@ The token emergency action transition extends the [base transition](#token-base- | Field | Type | Size | Description | | ----- | ---- | ---- | ----------- | -| emergencyAction | [TokenEmergencyAction enum](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/tokens/emergency_action.rs#L14-L18) | Varies | The emergency action to be executed (`0` = Pause, `1` = Resume) | +| emergencyAction | [TokenEmergencyAction enum](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/tokens/emergency_action.rs#L14-L18) | Varies | The emergency action to be executed (`0` = Pause, `1` = Resume) | | publicNote | string | [<= 2048 bytes](#token-notes) | Optional public note | -Each token emergency action transition must comply with the [token emergency action transition defined in rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_emergency_action_transition/v0/mod.rs#L16-L24). +Each token emergency action transition must comply with the [token emergency action transition defined in rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_emergency_action_transition/v0/mod.rs#L16-L24). ### Token Config Update Transition @@ -182,10 +182,10 @@ The token config update transition extends the [base transition](#token-base-tra | Field | Type | Size | Description | | ----- | ---- | ---- | ----------- | -| updateTokenConfigurationItem | [TokenConfigurationChangeItem object](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/data_contract/associated_token/token_configuration_item.rs#L33-L67) | Varies | Updated token configuration item | +| updateTokenConfigurationItem | [TokenConfigurationChangeItem object](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/data_contract/associated_token/token_configuration_item.rs#L33-L67) | Varies | Updated token configuration item | | publicNote | string | [<= 2048 bytes](#token-notes) | Optional public note | -Each token configuration update transition must comply with the [token config update transition defined in rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_config_update_transition/v0/mod.rs#L19-L27). +Each token configuration update transition must comply with the [token config update transition defined in rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_config_update_transition/v0/mod.rs#L19-L27). ### Token Set Purchase Price Transition @@ -197,10 +197,10 @@ This transition extends the [base transition](#token-base-transition) to include | Field | Type | Size | Description | | ----- | ---- | ---- | ----------- | -price | Optional [TokenPricingSchedule](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/tokens/token_pricing_schedule.rs#L29-L45) | Variable | (Optional) Set the fixed price or tiered price. Tiered pricing entries consists of a *minimum token amount* (unsigned 64-bit) and a *price in credits* (unsigned 64-bit) applicable for purchases of that size or greater. The smallest amount tier also defines the *minimum purchasable amount*. If the lowest tier has amount > 1, users cannot buy less than that amount in a single purchase. If multiple tiers are provided, they should be ordered by ascending minimum amount.
    **Note:** Setting price to null disables direct purchases for the token. | +| price | Optional [TokenPricingSchedule](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/tokens/token_pricing_schedule.rs#L29-L45) | Variable | (Optional) Set the fixed price or tiered price. Tiered pricing entries consists of a *minimum token amount* (unsigned 64-bit) and a *price in credits* (unsigned 64-bit) applicable for purchases of that size or greater. The smallest amount tier also defines the *minimum purchasable amount*. If the lowest tier has amount > 1, users cannot buy less than that amount in a single purchase. If multiple tiers are provided, they should be ordered by ascending minimum amount.
    **Note:** Setting price to null disables direct purchases for the token. | | publicNote | string | [<= 2048 bytes](#token-notes) | Optional public note | -Each token set purchase price transition must comply with the [token set purchase price transition defined in rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_set_price_for_direct_purchase_transition/v0/mod.rs#L18-L29). +Each token set purchase price transition must comply with the [token set purchase price transition defined in rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_set_price_for_direct_purchase_transition/v0/mod.rs#L18-L29). ### Token Purchase Transition @@ -215,4 +215,4 @@ This transition extends the [base transition](#token-base-transition) to include | tokenCount | unsigned integer | 64 bits | Number of tokens the user is purchasing. Must be at least the minimum purchase amount defined by the current pricing and cannot exceed any available supply limits. | | totalAgreedPrice | unsigned integer | 64 bits | Maximum total price (in credits) the purchaser agrees to pay. Must be at least the unit price (or tiered price) times `tokenCount` according to the current pricing schedule. | -Each token purchase transition must comply with the [token direct purchase transition defined in rs-dpp](https://github.com/dashpay/platform/blob/v3.1-dev/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_direct_purchase_transition/v0/mod.rs#L20-L31). +Each token purchase transition must comply with the [token direct purchase transition defined in rs-dpp](https://github.com/dashpay/platform/blob/v4.0.0/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_direct_purchase_transition/v0/mod.rs#L20-L31). diff --git a/docs/reference/dapi-endpoints-core-grpc-endpoints.md b/docs/reference/dapi-endpoints-core-grpc-endpoints.md index 89ae2dcfd..58ff793cd 100644 --- a/docs/reference/dapi-endpoints-core-grpc-endpoints.md +++ b/docs/reference/dapi-endpoints-core-grpc-endpoints.md @@ -366,8 +366,8 @@ GetTransactionResponse { ], height: 416450, confirmations: 386421, - instantLocked: false, - chainLocked: true + isInstantLocked: false, + isChainLocked: true } ``` ::: diff --git a/docs/reference/dapi-endpoints-platform-endpoints.md b/docs/reference/dapi-endpoints-platform-endpoints.md index d0bb66622..c16dc8d20 100644 --- a/docs/reference/dapi-endpoints-platform-endpoints.md +++ b/docs/reference/dapi-endpoints-platform-endpoints.md @@ -984,7 +984,7 @@ grpcurl -proto protos/platform/v0/platform.proto \ ### getDocuments -:::{versionchanged} 3.1.0 +:::{versionchanged} 4.0.0 Adds a typed v1 request surface (`WhereClause` / `OrderClause` / `Select`) and four aggregate modes — `DOCUMENTS`, `COUNT`, `SUM`, `AVG`. The legacy v0 CBOR surface is still supported. ::: @@ -992,7 +992,7 @@ Adds a typed v1 request surface (`WhereClause` / `OrderClause` / `Select`) and f The request envelope is `oneof version { v0; v1; }`. Pick a version per call: -- **v1** (default for new code, v3.1+) — typed request fields and aggregate `select` modes. +- **v1** (default for new code, v4.0+) — typed request fields and aggregate `select` modes. - **v0** (legacy) — CBOR-encoded `where` / `order_by` byte strings. Fetch only. **Common request fields** (apply to every variant below) @@ -1185,7 +1185,7 @@ client.platform.getDataContract(contractId).then((contractResponse) => { #### Count documents -:::{versionadded} 3.1.0 +:::{versionadded} 4.0.0 ::: Returns one aggregate count, or per-group counts when `group_by` is set. Requires the doctype to set `documentsCountable: true` (and `rangeCountable: true` for range-grouped queries). See [aggregate query flags](../protocol-ref/data-contract-document.md#aggregate-query-flags). @@ -1253,7 +1253,7 @@ Count values use `[jstype = JS_STRING]` on the proto, so JavaScript clients rece #### Sum documents -:::{versionadded} 3.1.0 +:::{versionadded} 4.0.0 ::: Returns the sum of an integer field across matched documents, or per-group sums when `group_by` is set. Requires the doctype to set `documentsSummable: ""` (and `rangeSummable: true` for range-grouped queries). See [aggregate query flags](../protocol-ref/data-contract-document.md#aggregate-query-flags). @@ -1317,7 +1317,7 @@ grpcurl -proto protos/platform/v0/platform.proto \ #### Average documents -:::{versionadded} 3.1.0 +:::{versionadded} 4.0.0 ::: Returns a `(count, sum)` pair the client divides to compute the average, or per-group `(count, sum)` pairs when `group_by` is set. Requires the doctype to set `documentsAverageable: ""` (and `rangeAverageable: true` for range-grouped queries). See [aggregate query flags](../protocol-ref/data-contract-document.md#aggregate-query-flags). @@ -4579,7 +4579,7 @@ grpcurl -proto protos/platform/v0/platform.proto \ ## Shielded Transaction Endpoints -:::{versionadded} 3.1.0 +:::{versionadded} 4.0.0 ::: ### getShieldedEncryptedNotes diff --git a/docs/reference/dapi-endpoints.md b/docs/reference/dapi-endpoints.md index 252892e1a..188789b23 100644 --- a/docs/reference/dapi-endpoints.md +++ b/docs/reference/dapi-endpoints.md @@ -34,7 +34,7 @@ without introducing issues for endpoint consumers. | [`getDataContract`](../reference/dapi-endpoints-platform-endpoints.md#getdatacontract) | Returns the requested data contract | | [`getDataContracts`](../reference/dapi-endpoints-platform-endpoints.md#getdatacontracts) | Returns the requested data contracts | | [`getDataContractHistory`](../reference/dapi-endpoints-platform-endpoints.md#getdatacontracthistory) | Returns the requested data contract history | -| [`getDocuments`](../reference/dapi-endpoints-platform-endpoints.md#getdocuments) | **Updated in Dash Platform v3.1.0**
    Returns the requested document(s), or an aggregate count/sum/average over the matched document set. | +| [`getDocuments`](../reference/dapi-endpoints-platform-endpoints.md#getdocuments) | **Updated in Dash Platform v4.0.0**
    Returns the requested document(s), or an aggregate count/sum/average over the matched document set. | ### Identities @@ -126,7 +126,7 @@ Security groups provide a way to distribute token configuration and update autho Shielded Transaction endpoints are defined in the protocol but are not yet available on public nodes. ::: -:::{versionadded} 3.1.0 +:::{versionadded} 4.0.0 ::: | Endpoint | Description | diff --git a/docs/reference/data-contracts.md b/docs/reference/data-contracts.md index 5f38d1c62..4302afb7d 100644 --- a/docs/reference/data-contracts.md +++ b/docs/reference/data-contracts.md @@ -24,7 +24,7 @@ Data contracts define the schema (structure) of data an application will store o } ::: -The following sections provide details that developers need to configure and construct valid contracts. All data contracts must define one or more [documents](#documents) that conform to the [general data contract constraints](#general-constraints). Additionally, several contract-level [configuration parameters](#contract-configuration) can be set to modify the mutability, retention, and security behavior of the contract and its documents. +The following sections provide details that developers need to configure and construct valid contracts. All data contracts must define at least one [document](#documents) or token, each conforming to the [general data contract constraints](#general-constraints). Additionally, several contract-level [configuration parameters](#contract-configuration) can be set to modify the mutability, retention, and security behavior of the contract and its documents. ## Contract Configuration @@ -42,6 +42,14 @@ Data contracts support three categories of configuration options to provide flex | `documentsMutable`
    `ContractDefault` | `true` | Sets the default mutability of documents within the contract | | `documentsCanBeDeleted`
    `ContractDefault` | `true` | Sets the default behavior for whether documents within the contract can be deleted| +Data contracts may also define the following top-level fields: + +| Contract field | Type | Description | +|----------------|------|-------------| +| `groups` | object | (Optional) Groups that allow for specific multiparty actions on the contract. See [Data Contract groups](../protocol-ref/data-contract.md#data-contract-groups). | +| `keywords` | array of strings | (Optional) Keywords associated with the contract to improve searchability via the `search` system contract. Maximum of 50 unique keywords. | +| `description` | string | (Optional) Brief human-readable description of the contract (3-100 characters). Also added to the `search` system contract. | + ## Key Management Dash Platform provides an advanced level of security and control by enabling the isolation of encryption and decryption keys on a contract-specific or document-specific basis. This granular approach to key management enables developers to configure their applications for whatever level of security they require. @@ -105,6 +113,12 @@ Documents support the following configuration options to provide flexibility in | [`requiresIdentity`
    `DecryptionBoundedKey`](#key-management) | integer | Key requirements for identity decryption:
    `0` - Unique non-replaceable
    `1` - Multiple
    `2` - Multiple with reference to latest key | | `signatureSecurity`
    `LevelRequirement` | integer | Public key security level:
    `1` - Critical
    `2` - High
    `3` - Medium. Default is High if none specified. | +Document types may also define a `tokenCost` object requiring token payment per operation. See [Token Costs](../protocol-ref/data-contract-document.md#token-costs) in the protocol reference for the full schema. + +:::{versionadded} 4.0.0 +Document types can opt into aggregate queries with the flags `documentsCountable`, `documentsSummable`, `documentsAverageable`, and their `range*` variants, which enable `COUNT`/`SUM`/`AVG` support. See [Aggregate Query Flags](../protocol-ref/data-contract-document.md#aggregate-query-flags) in the protocol reference for the full schema. +::: + :::{dropdown} List of all usable document properties This list of properties is defined in the [Rust DPP implementation](https://github.com/dashpay/platform/blob/master/packages/rs-dpp/src/data_contract/document_type/mod.rs#L31) and the [document meta-schema](https://github.com/dashpay/platform/blob/master/packages/rs-dpp/schema/meta_schemas/document/v0/document-meta.json). @@ -126,6 +140,13 @@ Documents support the following configuration options to provide flexibility in | [`requiresIdentity`
    `DecryptionBoundedKey`](#key-management) | integer | Key requirements for identity decryption:
    `0` - Unique non-replaceable
    `1` - Multiple
    `2` - Multiple with reference to latest key | | [`properties`](#document-properties) | object | Defines the properties of the document. | | [`transient`](#transient-properties) | array | An array of strings specifying transient properties that are validated by Platform but not stored. | + | `tokenCost` | object | Defines token costs for document operations (create, replace, update_price, delete, transfer, purchase). See [Token Costs](../protocol-ref/data-contract-document.md#token-costs). | + | [`documentsCountable`](../protocol-ref/data-contract-document.md#aggregate-query-flags) | boolean | Doctype-wide count support. See [Aggregate Query Flags](../protocol-ref/data-contract-document.md#aggregate-query-flags). | + | [`rangeCountable`](../protocol-ref/data-contract-document.md#aggregate-query-flags) | boolean | Per-index range counts. See [Aggregate Query Flags](../protocol-ref/data-contract-document.md#aggregate-query-flags). | + | [`documentsSummable`](../protocol-ref/data-contract-document.md#aggregate-query-flags) | string | Doctype-wide sums of the named integer property. See [Aggregate Query Flags](../protocol-ref/data-contract-document.md#aggregate-query-flags). | + | [`rangeSummable`](../protocol-ref/data-contract-document.md#aggregate-query-flags) | boolean | Per-index range sums. See [Aggregate Query Flags](../protocol-ref/data-contract-document.md#aggregate-query-flags). | + | [`documentsAverageable`](../protocol-ref/data-contract-document.md#aggregate-query-flags) | string | Doctype-wide averages of the named integer property. See [Aggregate Query Flags](../protocol-ref/data-contract-document.md#aggregate-query-flags). | + | [`rangeAverageable`](../protocol-ref/data-contract-document.md#aggregate-query-flags) | boolean | Per-index range averages. See [Aggregate Query Flags](../protocol-ref/data-contract-document.md#aggregate-query-flags). | | [`additionalProperties`](#additional-properties) | boolean | Specifies whether additional properties are allowed. Must be set to false, meaning no additional properties are allowed beyond those defined. | ::: @@ -247,7 +268,7 @@ The `indices` array consists of one or more objects that each contain: ::: * An optional `unique` element that determines if duplicate values are allowed for the document * An optional `nullSearchable` element that indicates whether the index allows searching for NULL values. If nullSearchable is false (default: true) and all properties of the index are null then no reference is added. -* An optional `contested` element that determines if duplicate values are allowed for the document +* An optional `contested` element that configures a masternode-voting contest over documents whose field values match a defined pattern (see [Contested indices](#contested-indices)). It is an object composed of `fieldMatches` (field and `regexPattern` conditions) and a `resolution` method. :::{code-block} json :force: @@ -256,8 +277,8 @@ The `indices` array consists of one or more objects that each contain: { "name": "", "properties": [ - { "": "" }, - { "": "" } + { "": "asc" }, + { "": "asc" } ], "unique": true|false, "nullSearchable": true|false, @@ -274,7 +295,7 @@ The `indices` array consists of one or more objects that each contain: { "name": "", "properties": [ - { "": "" }, + { "": "asc" }, ], } ] @@ -377,7 +398,7 @@ This example syntax shows the structure of a document object including all optio { "name": "", "properties": [ - { "": "" }, + { "": "asc" }, ], "unique": true|false, "nullSearchable": true|false, diff --git a/docs/reference/glossary.md b/docs/reference/glossary.md index b46737a92..d19e2b896 100644 --- a/docs/reference/glossary.md +++ b/docs/reference/glossary.md @@ -146,7 +146,7 @@ Layer 2 blockchain that propagates platform data among masternodes, propagates p ## Platform State -All layer 2 data including contracts, documents (user data), credit balance, identity (username) +All layer 2 data including contracts, documents (user data), tokens, groups, credit balance, identity (username), and masternode voting/contested resource state ## practical Byzantine Fault Tolerance (pBFT) @@ -186,7 +186,7 @@ The application that validates state transitions and updates state in Drive ## State Transition -The change a user does to the application and platforms states. Consists of an array of documents _or_ one data contract, the id of the application to which the change is made, and a user signature +A signed change to platform state submitted by an identity. State transitions cover a range of operations, including data contract creation and updates, document and token changes (batched), identity lifecycle operations (create, top-up, update), credit transfers and withdrawals, and masternode voting (cast by masternode and evonode operators) ## Tenderdash diff --git a/docs/reference/platform-proofs.md b/docs/reference/platform-proofs.md index 9bb23259c..2061862de 100644 --- a/docs/reference/platform-proofs.md +++ b/docs/reference/platform-proofs.md @@ -4,144 +4,66 @@ # Platform Proofs -Platform proofs are an important part of Dash Platform's trust model. When a response is requested -with `prove: true`, Platform can return proof data that allows clients to verify that the response -matches consensus state. +Platform proofs are an important part of Dash Platform's trust model. A proof is a self-contained +cryptographic object that lets anyone verify a piece of platform state is authentic and was +agreed upon by the validator network -- without trusting whoever supplied the data. -Since data verification is a critical aspect of Dash Platform, all [Platform endpoints](../reference/dapi-endpoints-platform-endpoints.md) can provide an optional proof that the response is correct. Set the optional `prove` parameter (`"prove": true`) in the request to receive a proof that contains the requested data. +The most common way to obtain a proof is to request one over [DAPI](../explanations/dapi.md): set +the optional `"prove": true` parameter on a [Platform gRPC +endpoint](../reference/dapi-endpoints-platform-endpoints.md) and the response carries a `Proof` +message instead of the plain result. A proof does not depend on how it was retrieved, though -- +it can be verified independently by any party that holds it. -## Proof Structure +For the concepts behind proofs -- the two-layer GroveDB + consensus trust model, the verification +flow, what can be proven, and asset lock proofs -- see [Proofs](../explanations/proofs.md). -Each proof consists of four parts: +## Proof structure + +A `Proof` is a single unified [GroveDB](https://github.com/dashpay/grovedb) proof plus the +consensus signature that authenticates it. It has six fields: | Field | Type | Description | -|-|-|-| -| rootTreeProof | Bytes (base64) | Merkle path to the `storeTreeProof` | -| [storeTreeProof](#store-tree-proof) | Object | Object containing data and proofs from one or more store trees. Currently there are 5 types of trees: identities, public key hash to identity IDs, data contracts, documents, and state transitions. The merk tree proofs contain the store root hash, the merkle path, and the requested data | -| signatureLlmqHash | Bytes (base64) | Hash of the LLMQ that created the `signature` | -| signature | Bytes (base64) | Signature of the merkle root of the `rootTreeProof` | +| - | - | - | +| `grovedbProof` | Bytes (base64) | The GroveDB proof for the requested data. An opaque blob that a verifier decodes to recover the data and the state root hash. | +| `quorumHash` | Bytes (base64) | Hash of the validator quorum that signed the state. | +| `signature` | Bytes (base64) | BLS threshold signature over the signed block, proving the quorum agreed on this state. | +| `round` | Integer | Consensus round the block was finalized in. | +| `blockIdHash` | Bytes (base64) | Hash of the block ID the proof is anchored to. | +| `quorumType` | Integer | Type of the quorum that produced the signature. | ```json { "proof": { - "rootTreeProof": "v+99FytmaUPDP65HthQllBL1JDXt2Zu/kzFEQRw66rT6QF8LYwKmAP6fEaXLaSVPe/OHfTDEG2+KoLxjyirQIDmDy4lNl4yhJE5stQZGO2G/74H4MxN/a/luSWkqE1vF", - "storeTreeProofs": { - "identitiesProof": "AeFWk/kp1HXlJMzA4Wwov+NifjrocHebDU8863BDtp4aAlHeCG7lcVi52OSo+U5LlykSjARXJ5Rv6hE+mui+RnUFEAGJ24nuRAkAZMjcRp1sbzLPwYxxagTD12YTLksNN+y1cAKxpoxQdHpC/RQN7cq7fE/z6+0ccpoVQbobRPGtfCSj4hABjDZM5byc2NbfTNb7NGWDKm0bAoZjaAHx+C7Gn2cKmfsCIyWhRVW4QDdnoxTDvJuHCKJeK8dWzsrfVuUYTejcw6MQAX4HE7Y1WuXPPAG6uU9vewbilQnhjLzSTYNVLsdkxmLfAmwhTWaLg5A+tuxnzvdPhNU+bmbyMHr4PIL8Z+ScbyikEAFtCRA34Yl9tuEzqAF1EdiY0U9/jNoyEpU2vkPLO7xUYAJEmc3z/snpNWPXQdMrrAAHqWNhwddPRSMrF0epC75qThADIHwTzudaE/98V8XvldeYDIpe0yZOW3s6iK0jdqsoOJz3AIABAAAApGJpZFggfBPO51oT/3xXxe+V15gMil7TJk5bezqIrSN2qyg4nPdnYmFsYW5jZRoAp8O4aHJldmlzaW9uAGpwdWJsaWNLZXlzgaNiaWQAZGRhdGFYIQOF51gOnYk5T+0EdR4DSKUkDo5TmEDMoMxdxOy7FnqKjmR0eXBlABEREQL0H2yuZyiMzKzHmrXCwp/W7DuDkZYlEx7JE5xlYGhJxhABJt9KcGPXHnE7hzz3aQ9PpYDhvILZCDUOu5BBwV66RPYRERECyX/3Cih/TZdB9cVOX8Xmo2UEPNvt9iOufQ4oCmoytwsQAU14wPdQ7t7FfsfXx9fGnwbZk8h1uxoWd0MroZRO0YVXEQ==", - "publicKeyHashesToIdentityIdsProof": "Afe33zbtlgXiPzJ1+zSjjVttIBmiKHy1iEc7uOKqxVUGAjs/C8gAlTwbVhnRBqbhGFkz0Kg/0Cr8mAV41WXxocBpEAGVsw8werVp7Cka+OSMj3GgkX2Da0FMMGGIJx4aZxPwPhE=" - }, - "signatureLlmqHash": "AAACBMSv9TakRGNdP+yvxw/+VCgIbALhn314jLOpgcY=", - "signature": "Fhl8Md9MDlB0Tlekgjoj+Qe5PdKeUDyL6svVmcP9ttRu1UB7oeAGaSMAyqJI+k/HA/jAfPFb9+q9gepdZDhj8zHrl5BRSaAiBPEtM6CTQ+eCWUvqOlDENVQfubrXLLdk" - }, - "metadata": { - "height": "7986", - "coreChainLockedHeight": 57585 + "grovedbProof": "APsA/wGQtKE8gXoPHBaBJWO/39M63DsnEkx4Lah9...", + "quorumHash": "AAAAN0ggLzkGuHl7bJM48baKuEs/b3rhSMSF5kIw14g=", + "signature": "oc8EMH7WkoZhv06iPvP4HjTlleaRLOfDRvWg30hjXL3z83DpNigk1/8mZwC1jrEDFymkkftcoE+DcPhZu/R8wlP2yxWcWo+605lLqU/FIb29nOt0q6hUbuX+eZL39mdb", + "round": 0, + "blockIdHash": "Eq24v2aaWwDXN41oCmduKOYnDRsvoAJwDk8BEHZRDaU=", + "quorumType": 6 } } ``` -### Root tree proof - -> 📘 -> -> Details regarding the root tree proofs and their verification will be provided in a future update to this page. - -### Store tree proof - -Store tree proofs are based on a modified version of [Merk](https://github.com/nomic-io/merk/). Some details from the Merk documentation are included below. Additional details are available in the [Algorithms document](https://github.com/nomic-io/merk/blob/develop/docs/algorithms.md) on the Merk repository. - -Dash Platform 0.21.0 introduced updates to support returning multiple store tree proofs. Each response that requests proofs will receive one or more of the following: - -- `identitiesProof` -- `publicKeyHashesToIdentityIdsProof` -- `dataContractsProof` -- `documentsProof` -- `stateTransitionProof` - -:::{note} -Some proof payloads include a 4-byte protocol version prefix that is not part of the CBOR-encoded -value. When decoding those values, strip the version prefix before CBOR decoding. -::: - -#### Structure - -Merk proofs are a list of stack-based operators and node data, with 3 possible operators: `Push(node)`, `Parent`, and `Child`. A stream of these operators can be processed by a verifier in order to reconstruct a sparse representation of part of the tree, in a way where the data can be verified against a known root hash. - -The value of `node` in a `Push` operation can be one of three types: - -- `Hash(hash)` - The hash of a node -- `KVHash(hash)` - The key/value hash of a node -- `KV(key, value)` - The key and value of a node - -#### Binary Format - -We can efficiently encode these proofs by encoding each operator as follows: +## Verifying proofs -| Operator | Op. Value | Size | Description | -|-|:-:|-|-| -| Push(Hash(hash)) | `0x01` | 32 bytes | Node hash | -| Push(KVHash(hash)) | `0x02` | 32 bytes | Node key/value hash | -| Push(KV(key, value)) | `0x03` | < 1-byte key length >
    < n-byte key >
    < 2-byte value length >
    < n-byte value > | Node key/value | +Clients do not parse proofs manually. Verification is performed by the +`rs-drive-proof-verifier` crate, which checks the quorum's BLS threshold signature (the +Tenderdash consensus half) and decodes the unified `grovedbProof` to recover the requested data +and the state root hash. This logic is exposed to JavaScript and browser clients through the +`wasm-drive-verify` package, so the SDKs verify proofs automatically whenever one is requested. -This results in a compact binary representation, with a very small space overhead (roughly 2 bytes per node in the proof (1 byte for the Push operator type flag, and 1 byte for a Parent or Child operator), plus 3 bytes per key/value pair (1 byte for the key length, and 2 bytes for the value length)). +See the [Proofs](../explanations/proofs.md) explanation for the step-by-step verification flow. -## Retrieving response data from proofs +## Proof internals -The function below shows a simple example of parsing a response's `storeTreeProof` to retrieve the data asked for by the request: +The `grovedbProof` value is an opaque binary blob. Its byte-level format -- the stack-based proof +operators, node types, absence proofs, the V0/V1 proof formats, and the verification algorithm -- +is documented in the [GroveDB Proof System +documentation](https://dashpay.github.io/grovedb/proof-system.html). Clients that use an SDK do +not need to work at this level. -```javascript -// Get data from base64 encoded store tree proof -function getStoreProofData(storeProof) { - const values = []; - const buf = Buffer.from(storeProof, 'base64'); +## Related topics - let x = 0; - let valueFound = false; - while (x < buf.length) { - const type = buf.readUInt8(x); - x += 1; - - switch (type) { - case 0x01: { // Hash - x += hashLength; - break; - } - - case 0x02: { // Key/value hash - x += hashLength; - break; - } - - case 0x03: { // Key / Value - const keySize = buf.readUInt8(x); - x += (1 + keySize); - - const valueSize = buf.readUInt16BE(x); - x += 2; - - // Value - // Start at x+4 because the first 4 bytes are the protocol version - // and are not part of the CBOR value - const value = buf.toString('hex', x + 4, x + valueSize); - x += valueSize; - const map = cbor.decode(value); - - valueFound = true; - values.push(map); - break; - } - - case 0x10: // Parent - break; - - case 0x11: // Child - break; - - default: - console.log(`Unknown type: ${type.toString(16)}`); - break; - } - } - console.log(`Value found: ${valueFound}`); - return values; -} -``` +- [Proofs](../explanations/proofs.md) -- the conceptual trust model, verification flow, and asset lock proofs +- [Platform gRPC endpoints](../reference/dapi-endpoints-platform-endpoints.md) -- the `prove` parameter and example responses +- [GroveDB Proof System](https://dashpay.github.io/grovedb/proof-system.html) -- proof format and verification internals diff --git a/docs/reference/query-syntax.md b/docs/reference/query-syntax.md index 1832f4cc6..63d2b35b3 100644 --- a/docs/reference/query-syntax.md +++ b/docs/reference/query-syntax.md @@ -169,7 +169,7 @@ For indices composed of multiple fields ([example from the DPNS data contract](h ## Aggregate Queries -:::{versionadded} 3.1.0 +:::{versionadded} 4.0.0 ::: The [getDocuments](../reference/dapi-endpoints-platform-endpoints.md#getdocuments) v1 surface adds an aggregate-query mode. The same `where` / `orderBy` clauses described above still apply; an additional `select` projection (and optional `groupBy`) determines whether the request returns documents or aggregate values over the matched set. diff --git a/docs/resources/faq.md b/docs/resources/faq.md index 88d907f11..1f3b0fa72 100644 --- a/docs/resources/faq.md +++ b/docs/resources/faq.md @@ -47,7 +47,7 @@ Dash Platform Name Service (DPNS). :::{dropdown} How can I register a name? Currently, names can be registered using the [DashPay Android wallet](https://play.google.com/store/apps/details?id=hashengineering.darkcoin.wallet). -Developers and other technical users may want to experiment with registering names using the [Dash Evo Tool](https://github.com/dashpay/dash-evo-tool) or the [JavaScript SDK](https://docs.dash.org/projects/platform/en/stable/docs/tutorials/identities-and-names/register-a-name-for-an-identity.html). +Developers and other technical users may want to experiment with registering names using the [Dash Evo Tool](https://github.com/dashpay/dash-evo-tool) or the [JavaScript SDK](../tutorials/identities-and-names/register-a-name-for-an-identity.md). ::: ::::{dropdown} Can I register multiple names? @@ -113,7 +113,7 @@ example, once "Alice" is registered, none of the following will be available: Any name meeting the following criteria is considered premium: -* Less than 20 characters long (i.e. "alice", "quantumexplorer") AND +* Between 3 and 19 characters long (i.e. "alice", "quantumexplorer") AND * Contain no numbers or only contain the number(s) 0 and/or 1 (i.e. "bob", "carol01") These names require a two-week waiting period during which masternodes and evonodes vote to @@ -123,7 +123,8 @@ pay a 0.2 DASH name request fee. :::{dropdown} What happens if no one votes for a contested username request? -If no one votes, the first identity requesting the name will receive it. +If no one votes, a single uncontested request receives the name. If multiple identities requested +it, the winner is resolved deterministically by the protocol (based on document creation order). ::: :::{dropdown} How do I prove my identity if requesting a contested name? @@ -145,14 +146,15 @@ not be awarded to the person requesting it. Some examples of names that may be l :::{dropdown} Can locked names be requested by someone else later? -Locked names can no longer be requested or awarded in Dash Platform v1. The plan is to change this +Locked names can no longer be requested or awarded in Dash Platform. The plan is to change this in future updates, but the exact details have not been defined. ::: :::{dropdown} What happens if there is a tie vote? -If there is a tie, the first identity requesting the name will receive it. This applies even if -there is a tie between votes for an identity and votes to lock the name. +If there is a tie, the name is awarded deterministically by the protocol (based on document +creation order) rather than to whoever requested it first. If there is a tie between votes for an +identity and votes to lock the name, the identity receives the name. ::: :::{dropdown} Can usernames be transferred? @@ -188,7 +190,7 @@ multiple usernames. :::{tip} See the [DashPay page](../explanations/dashpay.md) and the [DashPay -DIP](https://github.com/dashpay/dips/blob/master/dip-0015.md) for additional information on the Dash Platform Name Service (DPNS). +DIP](https://github.com/dashpay/dips/blob/master/dip-0015.md) for additional information on DashPay. ::: :::{dropdown} Can someone tell when Dash is sent from one username to another?