From 1268bbb4ff4c9b603048b26edf443fbba4502da2 Mon Sep 17 00:00:00 2001 From: thephez Date: Thu, 17 Sep 2026 15:23:34 -0400 Subject: [PATCH 1/3] docs(intro): minor cleanup Based on audit findings --- docs/intro/testnet.md | 2 +- docs/intro/what-is-dash-platform.md | 6 +++--- docs/intro/what-is-dash.md | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/intro/testnet.md b/docs/intro/testnet.md index fe41ae872..72f44862b 100644 --- a/docs/intro/testnet.md +++ b/docs/intro/testnet.md @@ -10,7 +10,7 @@ Testnet is the Dash testing network used for experimentation and evaluation of D ### Infrastructure -Dash Core Group provides the core Testnet infrastructure consisting of 150 masternodes running Dash Core along with the platform services that provide the [decentralized API (DAPI)](../explanations/dapi.md) and [storage (Drive)](../explanations/drive.md) functionality. +Dash Core Group provides the core Testnet infrastructure consisting of ~50 masternodes running Dash Core plus ~30 evonodes that also run the platform services that provide the [decentralized API (DAPI)](../explanations/dapi.md) and [storage (Drive)](../explanations/drive.md) functionality. Testnet also includes a [block explorer](https://insight.testnet.networks.dash.org/insight/) for the core blockchain and a [test Dash faucet](https://faucet.testnet.networks.dash.org/) that dispenses funds to users/developers experimenting on the network. diff --git a/docs/intro/what-is-dash-platform.md b/docs/intro/what-is-dash-platform.md index 08629eb6e..6fd925048 100644 --- a/docs/intro/what-is-dash-platform.md +++ b/docs/intro/what-is-dash-platform.md @@ -61,9 +61,9 @@ verification, making it practical for light clients and user-facing applications ### DAPI - A decentralized API -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 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 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. +DAPI provides access to Dash network services without the cost and maintenance overhead of running a node. Clients can verify supported Platform responses using cryptographic proofs. 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. Developers can connect to DAPI directly or use higher-level SDKs and client libraries maintained in the Dash Platform monorepo. These libraries handle connection management, data serialization, and @@ -78,7 +78,7 @@ The source for these components is available on GitHub: Drive is Dash Platform's storage component, allowing for consensus-based verification and validation of user-created data. In order for this to occur, developers create a [data contract](../explanations/platform-protocol-data-contract.md). This data contract describes the data structures that comprise an application, similar to creating a schema for a document-oriented database like MongoDB. -Data created by users of the application is validated and verified against this contract. Upon successful validation/verification, application data is submitted to Drive (via DAPI), where it is stored on the masternode network. Drive uses Dash's purpose-built database, [GroveDB](https://github.com/dashpay/grovedb/), to provide efficient proofs with query responses, so you don't have to trust the API provider to be certain your data is authentic. +Users submit application data in state transitions through DAPI. The network validates the data against its data contract before storing accepted changes in Drive. Drive uses Dash's purpose-built database, [GroveDB](https://github.com/dashpay/grovedb/), to provide efficient proofs with query responses, so you don't have to trust the API provider to be certain your data is authentic. The source is available on GitHub: diff --git a/docs/intro/what-is-dash.md b/docs/intro/what-is-dash.md index cccbfbe9e..190ecf1b1 100644 --- a/docs/intro/what-is-dash.md +++ b/docs/intro/what-is-dash.md @@ -24,15 +24,15 @@ Most of Dash's technical innovations are described in greater detail elsewhere i ### Instantly Confirmed Transactions -All transactions are automatically sent and received instantly at no extra cost. Transaction security and decentralization are not compromised, due to the ChainLocks innovation. As a result, using Dash to transact means getting the speed and fungibility of fiat currency, while simultaneously having the lower costs, privacy, and security of funds of a blockchain-based network. +Dash transactions benefit from automatic, near-instant confirmation through InstantSend at no extra cost. Transaction security and decentralization are not compromised, due to the ChainLocks innovation. As a result, using Dash to transact means getting the speed and fungibility of fiat currency, while simultaneously having the lower costs, privacy, and security of funds of a blockchain-based network. ## Key Features ### Masternodes -The most important differentiating feature of the Dash payments network is the concept of a **masternode**. On a traditional p2p network, nodes participate equally in the sharing of data and network resources. These nodes are all compensated equally for their contributions toward preserving the network. +The most important differentiating feature of the Dash payments network is the concept of a **masternode**. On a traditional p2p network, nodes participate equally in the sharing of data and network resources. -However, the Dash network has a second layer of network participants that provide enhanced functionality in exchange for greater compensation. This second layer of masternodes is the reason why Dash is the most secure payments network, and can provide industry-leading features such as instant transaction settlement and usernames. +However, the Dash network has a second layer of network participants that provide enhanced functionality in exchange for compensation. This second layer of masternodes is the reason why Dash is the most secure payments network, and can provide industry-leading features such as instant transaction settlement and usernames. ### Long-Living Masternode Quorums From 942191c2873143b14e2c00d113419cd357e953e1 Mon Sep 17 00:00:00 2001 From: thephez Date: Thu, 17 Sep 2026 16:48:07 -0400 Subject: [PATCH 2/3] docs(explanations): document protocol 14 contract groups, key limits, and DashPay shielded address Add contract groups to the data contract explanation and proofs page, and describe how non-master authentication keys can be bound to a contract, document type, or contract group and carry a credit budget and expiry. Note that identity creation from the shielded pool rejects such keys. Add the shieldedAddress profile property to the embedded DashPay contract and describe its privacy and validation behavior. Include epoch schedules in the token claim description. --- docs/explanations/dashpay.md | 17 ++++++++++++++--- docs/explanations/identity.md | 2 ++ .../platform-protocol-data-contract.md | 8 +++++++- docs/explanations/proofs.md | 7 +++++++ docs/explanations/shielded-pool.md | 2 ++ docs/explanations/tokens.md | 2 +- 6 files changed, 33 insertions(+), 5 deletions(-) diff --git a/docs/explanations/dashpay.md b/docs/explanations/dashpay.md index e7aa40a07..660d30cf4 100644 --- a/docs/explanations/dashpay.md +++ b/docs/explanations/dashpay.md @@ -43,8 +43,11 @@ The contract defines three document types: `contactRequest`, `profile` and `cont payment channels between Dash identities. * Profile documents are used to store public facing information about Dash identities including avatars and display names. Since Dash Platform v4.2, a profile can also publish optional public -payment addresses (a Core chain address and/or a Platform address). Unlike contact-based payments, -payments to these addresses are publicly linkable to the profile. +payment addresses (a Core chain address, a Platform address, and/or a shielded receiving +address). Unlike contact-based payments, payments to the Core and Platform addresses are publicly +linkable to the profile. Publishing a shielded address ties it to the profile, but shielded payments +still hide the recipient on-chain. Platform checks its schema type and length; wallets must validate +the shielded address before paying. * ContactInfo documents can be used to store private information about other Dash identities. ### Establishing a Contact @@ -83,7 +86,7 @@ contract](https://github.com/dashpay/platform/blob/master/packages/dashpay-contr Additionally, the DashPay data triggers defined in [rs-drive-abci](https://github.com/dashpay/platform/tree/master/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/dashpay) enforce additional validation rules related to the `contactRequest` document and, since Dash Platform -v4.2, the payment address fields of the `profile` document. Note: as a system data +v4.2, the Core and Platform payment address fields of the `profile` document. Note: as a system data contract, the version active on a network is determined by that network's active protocol version. :::{tip} @@ -177,6 +180,14 @@ information and complete details about the data contract. "maxItems": 21, "description": "Platform address in storage form (type byte 0x00 P2PKH / 0x01 P2SH followed by the 20-byte HASH160, i.e. RIPEMD160 of SHA256, of the public key or redeem script) for public payments. The type byte is consensus-enforced by a data trigger.", "position": 6 + }, + "shieldedAddress": { + "type": "array", + "byteArray": true, + "minItems": 43, + "maxItems": 43, + "description": "Raw Orchard receiving address: 11-byte diversifier followed by 32-byte diversified transmission key. Clients validate before payment; wallets should use a dedicated tip account.", + "position": 7 } }, "minProperties": 1, diff --git a/docs/explanations/identity.md b/docs/explanations/identity.md index 2fca4a35d..81ecc85aa 100644 --- a/docs/explanations/identity.md +++ b/docs/explanations/identity.md @@ -51,6 +51,8 @@ Since anyone can topup either their own account or any other account, applicatio Each identity key has a purpose, a security level, and a cryptographic key type. Its purpose defines how the key may be used (for example authentication, encryption, decryption, transferring credits, or voting), while its security level indicates how strongly clients should protect it and which signing requirements it can satisfy. A master key controls changes to the identity's keys, while a transfer key controls its credits. More keys can be added later through an identity update. +From protocol version 14, non-master authentication keys can be bound to a contract, a document type, or a [contract group](../explanations/platform-protocol-data-contract.md#contract-groups), restricting them to batch transitions within those bounds. They can also carry a credit budget and an expiry time. Transitions are rejected once the budget is exhausted or the block time reaches the expiry. Credits moved out of the identity, storage fees, fixed fees, and voluntary fee increases must fit in the remaining budget; metered processing fees may exceed it. + Data contracts can require a property to refer to an existing identity or, since Dash Platform v4.2, to a specific identity key. See [property references](../reference/data-contracts.md#platform-specific-property-keywords) and the [identity protocol reference](../protocol-ref/identity.md#identity-publickeys) for details. ### Identity Update Process diff --git a/docs/explanations/platform-protocol-data-contract.md b/docs/explanations/platform-protocol-data-contract.md index 6c638ff24..144d83531 100644 --- a/docs/explanations/platform-protocol-data-contract.md +++ b/docs/explanations/platform-protocol-data-contract.md @@ -39,6 +39,12 @@ Each document type's schema also determines how applications can query and relat For a practical example, see the [DashPay contract](#example-contract). +### Contract Groups + +From protocol version 14, contract groups organize contracts, document types, and tokens into an identity-owned collection. They can scope [authentication keys](../explanations/identity.md#keys) to those members. These are separate from [token groups](../explanations/tokens.md#groups), whose member identities jointly authorize token actions. + +When registering a contract, the creation transition can also register a contract group, optionally with admins, and declare memberships for the new contract, its document types, or its tokens in groups the creating identity owns or administers. + ### Registration Once a [Dash Platform Protocol](../explanations/platform-protocol.md) compliant data contract has been defined, it may be registered on the platform. Registration is completed by submitting a state transition containing the data contract to [DAPI](../explanations/dapi.md). @@ -71,7 +77,7 @@ Restricted changes include modifications that would break existing stored docume A contract update cannot remove or modify an existing token or group. Changing an existing token's configuration is done with a [token configuration update transition](../explanations/tokens.md#configuration-updates), governed by that token's own change control rules, and existing groups are immutable once the contract is registered. -Optional contract revision history storage allows contracts to retain a record of their revisions that can be retrieved and verified. Identity key access rules also allow an encryption or decryption key to be bound to a specific contract or document type for more granular key management. +Optional contract revision history storage allows contracts to retain a record of their revisions that can be retrieved and verified. Identity key access rules also allow an encryption or decryption key to be bound to a specific contract or document type for more granular key management. From protocol version 14, non-master authentication keys can also be bound to a contract, document type, or contract group, restricting them to batch transitions within those bounds. See [Identity keys](../explanations/identity.md#keys). :::{note} For more detailed information, see the [Platform Protocol Reference - Data Contract](../protocol-ref/data-contract.md) page. diff --git a/docs/explanations/proofs.md b/docs/explanations/proofs.md index 520a771dd..51399746b 100644 --- a/docs/explanations/proofs.md +++ b/docs/explanations/proofs.md @@ -68,12 +68,14 @@ Dash Platform supports proofs for all core data types: - Identity existence and full details - Identity balance and revision - Public keys associated with an identity +- Remaining credit budget of identity keys that carry one (from protocol version 14) - Identity nonces (for replay protection) **Data Contracts** - Contract existence and contents - Contract history (for contracts that track changes) +- Contract version on its own, without the contract contents, so a client can check whether a cached contract is current (from protocol version 14; earlier versions prove the whole contract) **Documents** @@ -96,6 +98,11 @@ Dash Platform supports proofs for all core data types: - Group state and member powers - Group action status and the votes recorded against it +**Contract Groups** (from protocol version 14) + +- Contract group owner, admins, name, and description +- The contracts, document types, and tokens in a contract group, and the contract groups a contract belongs to + **Address System** - [Platform address](../protocol-ref/address-system.md) balances diff --git a/docs/explanations/shielded-pool.md b/docs/explanations/shielded-pool.md index c26998632..b78966a3f 100644 --- a/docs/explanations/shielded-pool.md +++ b/docs/explanations/shielded-pool.md @@ -78,6 +78,8 @@ The funding amount cannot be chosen freely: it must be one of a small fixed set The notes being spent do not have to add up to the chosen denomination exactly - any excess is returned to the pool as a new note, so change stays shielded. If identity creation then fails a stateful check, the denomination still leaves the pool: it lands, less a penalty, at a fallback Platform address named in the transition. +From protocol version 14, keys with a budget, an expiry, or a contract group binding cannot be registered when creating an identity from the pool. Add these keys afterward through an identity update. + ### Shield from identity Moves credits *into* the pool from an identity's balance, without first moving them to a Platform address. Available from protocol version 14. diff --git a/docs/explanations/tokens.md b/docs/explanations/tokens.md index 20007ba35..86018aa78 100644 --- a/docs/explanations/tokens.md +++ b/docs/explanations/tokens.md @@ -71,7 +71,7 @@ The initial token implementation includes all actions required to create, use, a #### Claim - Claim tokens that have been allocated to an identity by a [distribution rule](#distribution-rules) but not yet credited to its balance. Claim covers both: - - **Perpetual distributions** - tokens continuously emitted on a block or time schedule that recipients must pull in order to take ownership. + - **Perpetual distributions** - tokens continuously emitted on a block, time, or epoch schedule that recipients must pull in order to take ownership. - **Pre-programmed distributions** - tokens scheduled for specific recipients at specific times that recipients must claim to receive. - Each claim collects a bounded number of unclaimed perpetual distribution intervals (128 for variable-rate distribution functions), so recipients with a long backlog may need to claim more than once to collect everything owed. From aac68d51a4ecc66c68f5ac21606530c483353874 Mon Sep 17 00:00:00 2001 From: thephez Date: Thu, 17 Sep 2026 17:46:17 -0400 Subject: [PATCH 3/3] **draft**: document protocol 14 contract groups, key limits, and withdrawal fee rules Add a contract groups section to the data contract reference covering registration, group ID derivation, admins, membership kinds, and the validation rules. Add the contractGroup and contractGroupMemberships fields to the Data Contract Create transition and note that it now supports format versions 0 and 1. Document the public key contractBounds variants and their protocol 14 authentication semantics, and add the totalBudget and expiresAt key limit fields along with the remaining budget behavior. Note the protocol 14 requirement on the supported protocol versions for the identity transitions that can carry such keys. Describe the protocol 14 Core fee rules for withdrawals across the identity, address, and shielded pool references: the 6,765 duffs/byte cap, the fee taken from the withdrawn amount, and the resulting fee-inclusive minimums. Split the protocol constants withdrawal rows accordingly and add a maximum Core fee per byte row. Correct the two- and six-key identity creation examples, which omitted the asset lock cost. State the protocol 14 minimum of one epoch for epoch based token distribution intervals. Document the document create id collision rules including the contested tree check. Add the 22 new consensus error codes, extend the state range to 41099, and add a contract group state section. Rename max_contract_group_size to max_group_member_count and distinguish it from contract groups. Refresh the embedded meta-schema comment and update source line anchors that had shifted. --- docs/protocol-ref/address-system.md | 6 ++- docs/protocol-ref/data-contract-document.md | 4 +- docs/protocol-ref/data-contract-token.md | 2 +- docs/protocol-ref/data-contract.md | 50 ++++++++++++++++++--- docs/protocol-ref/document.md | 2 + docs/protocol-ref/errors.md | 32 ++++++++++++- docs/protocol-ref/identity.md | 43 ++++++++++++++---- docs/protocol-ref/protocol-constants.md | 35 ++++++++------- docs/protocol-ref/shielded-pool.md | 10 ++--- docs/protocol-ref/state-transition.md | 10 ++++- 10 files changed, 150 insertions(+), 44 deletions(-) diff --git a/docs/protocol-ref/address-system.md b/docs/protocol-ref/address-system.md index 1b4a3ea68..3ab10dd8f 100644 --- a/docs/protocol-ref/address-system.md +++ b/docs/protocol-ref/address-system.md @@ -214,16 +214,18 @@ Withdraw credits from Platform addresses back to the Core chain. | inputs | map | Varies | Map of source [Platform addresses](#platform-address) to (nonce, credits) pairs | | output | tuple | Varies | (Optional) Change output as (Platform address, credits) | | feeStrategy | array | Varies | [Fee deduction strategy](#fee-strategy) | -| coreFeePerByte | unsigned integer | 32 bits | Core transaction fee per byte (must be a [Fibonacci number](https://en.wikipedia.org/wiki/Fibonacci_sequence) ≥ 1) | +| coreFeePerByte | unsigned integer | 32 bits | Core transaction fee per byte (must be a [Fibonacci number](https://en.wikipedia.org/wiki/Fibonacci_sequence) ≥ 1; at most 6,765 from protocol version 14) | | pooling | unsigned integer | 8 bits | Pooling mode: `0` = Never (required), `1` = IfAvailable, `2` = Standard | | outputScript | array of bytes | Varies | Core chain destination script (P2PKH or P2SH only) | | userFeeIncrease | unsigned integer | 16 bits | Extra fee to prioritize processing if the mempool is full | | inputWitnesses | array | Varies | [Address witnesses](#address-witness) for each input | :::{note} -**Constraints:** Minimum inputs: 1. Maximum inputs: `max_address_inputs`. Minimum per input: 100,000 credits. Minimum output: 500,000 credits. Pooling must be `Never` (others not yet implemented). Output script must be P2PKH or P2SH. The withdrawn amount (input sum minus the change output) must be greater than zero and within the [min and max withdrawal amount](protocol-constants.md) limits. +**Constraints:** Minimum inputs: 1. Maximum inputs: `max_address_inputs`. Minimum per input: 100,000 credits. Minimum output: 500,000 credits. Pooling must be `Never` (others not yet implemented). Output script must be P2PKH or P2SH. The withdrawn amount (input sum minus the change output) must be greater than zero and within the [min and max withdrawal amount](protocol-constants.md) limits. From protocol version 14 the Core fee of the withdrawal transaction (190 bytes x `coreFeePerByte` duffs, or 190,000 x `coreFeePerByte` credits) is taken from the withdrawn amount, so the amount must be at least the minimum withdrawal amount plus that fee (1,190,000 credits at `coreFeePerByte` 1). `coreFeePerByte` above 6,765 is rejected. **Fee:** 400,000,000 credits + 500,000 per input + 6,000,000 for the change output (if present). Withdrawal fees are significantly higher due to the complexity and finality of moving funds back to the Core chain. + +At `coreFeePerByte` 6,765, the minimum withdrawn amount is 1,286,350,000 credits. The recipient receives the input sum minus the change output and Core fee. A fee rate above the cap is rejected with error `10522`, and an amount below the fee-inclusive minimum with `10818`. ::: See the [implementation in rs-dpp](https://github.com/dashpay/platform/blob/v4.2-dev/packages/rs-dpp/src/state_transition/state_transitions/address_funds/address_credit_withdrawal_transition/). diff --git a/docs/protocol-ref/data-contract-document.md b/docs/protocol-ref/data-contract-document.md index bb0d26481..ae995451c 100644 --- a/docs/protocol-ref/data-contract-document.md +++ b/docs/protocol-ref/data-contract-document.md @@ -331,8 +331,8 @@ For performance and security reasons, indices have the following constraints. Th | Maximum number of unique indices | [10](https://github.com/dashpay/platform/blob/v4.2-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/v4.2-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/v4.2-dev/packages/rs-dpp/schema/meta_schemas/document/v2/document-meta.json#L378) | -| Maximum `timeRange` overlap factor (`range / step`) (added in 4.2.0) | [24](https://github.com/dashpay/platform/blob/v4.2-dev/packages/rs-platform-version/src/version/system_limits/v4.rs#L65) | -| Maximum `timeRange` `ttl` (added in 4.2.0) | [604,800](https://github.com/dashpay/platform/blob/v4.2-dev/packages/rs-platform-version/src/version/system_limits/v4.rs#L66) seconds (1 week) | +| Maximum `timeRange` overlap factor (`range / step`) (added in 4.2.0) | [24](https://github.com/dashpay/platform/blob/v4.2-dev/packages/rs-platform-version/src/version/system_limits/v4.rs#L77) | +| Maximum `timeRange` `ttl` (added in 4.2.0) | [604,800](https://github.com/dashpay/platform/blob/v4.2-dev/packages/rs-platform-version/src/version/system_limits/v4.rs#L78) seconds (1 week) | | Maximum length of indexed string property | [63](https://github.com/dashpay/platform/blob/v4.2-dev/packages/rs-dpp/src/data_contract/document_type/class_methods/try_from_schema/mod.rs#L28) | | 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/v4.2-dev/packages/rs-dpp/src/data_contract/document_type/class_methods/try_from_schema/mod.rs#L29) | diff --git a/docs/protocol-ref/data-contract-token.md b/docs/protocol-ref/data-contract-token.md index b873650fb..53cc577f4 100644 --- a/docs/protocol-ref/data-contract-token.md +++ b/docs/protocol-ref/data-contract-token.md @@ -289,7 +289,7 @@ The `distributionType` field accepts one of three schedule types: 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). -The `interval` has a network specific minimum, checked when the contract is registered or updated. Block based intervals must be at least 100 blocks on mainnet (5 on testnet, 2 on devnet, 1 on regtest). Time based intervals must be at least 3,600,000 ms (1 hour) on mainnet (600,000 ms on testnet, 60,000 ms on devnet and regtest) and must be a multiple of 60,000 ms. Epoch based intervals have no minimum. +The `interval` has a network specific minimum, checked when the contract is registered or updated. Block based intervals must be at least 100 blocks on mainnet (5 on testnet, 2 on devnet, 1 on regtest). Time based intervals must be at least 3,600,000 ms (1 hour) on mainnet (600,000 ms on testnet, 60,000 ms on devnet and regtest) and must be a multiple of 60,000 ms. Epoch based intervals must be at least 1 epoch starting with protocol version 14; earlier protocol versions did not enforce a minimum. An interval of `0` is rejected with `InvalidTokenDistributionEpochIntervalTooShortError` (10828). Block- and time-based minimums are unchanged. #### Perpetual Distribution Options diff --git a/docs/protocol-ref/data-contract.md b/docs/protocol-ref/data-contract.md index 21c6823c0..3887a4dff 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/v4.2-dev/packages/rs-platform-version/src/version/system_limits/v4.rs#L39) | -| Maximum field value size | [5120 bytes (5 KB)](https://github.com/dashpay/platform/blob/v4.2-dev/packages/rs-platform-version/src/version/system_limits/v4.rs#L40) | -| Maximum state transition size | [20480 bytes (20 KB)](https://github.com/dashpay/platform/blob/v4.2-dev/packages/rs-platform-version/src/version/system_limits/v4.rs#L44) | +| Estimated maximum serialized data contract size | [16384 bytes (16 KB)](https://github.com/dashpay/platform/blob/v4.2-dev/packages/rs-platform-version/src/version/system_limits/v4.rs#L46) | +| Maximum field value size | [5120 bytes (5 KB)](https://github.com/dashpay/platform/blob/v4.2-dev/packages/rs-platform-version/src/version/system_limits/v4.rs#L47) | +| Maximum state transition size | [20480 bytes (20 KB)](https://github.com/dashpay/platform/blob/v4.2-dev/packages/rs-platform-version/src/version/system_limits/v4.rs#L51) | 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 @@ -109,7 +109,7 @@ This page reflects the v3 meta-schema, which adds the `refersTo` and `requiredSi { "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://github.com/dashpay/platform/blob/master/packages/rs-dpp/schema/meta_schemas/document/v1/document-meta.json", - "$comment": "EDITABLE UNTIL THE RELEASE CARRYING PROTOCOL V14 SHIPS — FROZEN AFTER. This v3 document meta-schema activates with protocol v14 (CONTRACT_VERSIONS_V6). It is v2 plus the ranked index keywords (rankedCountable, rankedSummable, rankedAverageable), the refersTo reference keyword on identifier properties, the requiredSince property keyword (the contract version a property is required from), and the timeRange index transform, and admits every v14+ contract written to disk. v2 stays in place for protocol v13, where those keys still fail an index entry's `additionalProperties: false`. Once the release carrying protocol v14 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 (v4+). The $id above deliberately still names the v1 path: v1, v2 and v3 all share that identity, and it is the exact string `enrich_with_base_schema` injects as every PV12+ document schema's `$schema`, so bumping it here would be a wire-visible change rather than a documentation fix.", + "$comment": "FROZEN: shipped with Platform 4.2 (protocol v14). This v3 document meta-schema activates with protocol v14 (CONTRACT_VERSIONS_V6). It is v2 plus the ranked index keywords (rankedCountable, rankedSummable, rankedAverageable), the refersTo reference keyword on identifier properties, the requiredSince property keyword (the contract version a property is required from), and the timeRange index transform, and admits every v14+ contract written to disk. v2 stays in place for protocol v13, where those keys still fail an index entry's `additionalProperties: false`. Mutating it would change historical validation results and break consensus replay. Any new top-level property or rule MUST go in a newer meta-schema version (v4+). The $id above deliberately still names the v1 path: v1, v2 and v3 all share that identity, and it is the exact string `enrich_with_base_schema` injects as every PV12+ document schema's `$schema`, so bumping it here would be a wire-visible change rather than a documentation fix.", "type": "object", "$defs": { "documentProperties": { @@ -1176,7 +1176,7 @@ Groups can be used to distribute contract configuration and update authorization | Constant | Value | Description | |----------|-------|-------------| | Minimum group size | [2](https://github.com/dashpay/platform/blob/v4.2-dev/packages/rs-dpp/src/data_contract/group/v0/mod.rs#L111-L114) | Minimum members per group | -| `max_contract_group_size` | [256](https://github.com/dashpay/platform/blob/v4.2-dev/packages/rs-platform-version/src/version/system_limits/v4.rs#L55) | Maximum members per group | +| `max_group_member_count` | [256](https://github.com/dashpay/platform/blob/v4.2-dev/packages/rs-platform-version/src/version/system_limits/v4.rs#L63) | Maximum members per change-control 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/v4.2-dev/packages/rs-dpp/src/data_contract/group/v0/mod.rs#L133-L138) value. | | Maximum required power | 65,535 (u32; cap enforced at u16::MAX) | Maximum threshold power | @@ -1257,6 +1257,40 @@ Its documents are written by the protocol while applying the corresponding docum See the [contract schema in rs-dpp](https://github.com/dashpay/platform/blob/v4.2-dev/packages/document-history-contract/schema/v1/document-history-contract-documents.json). +### Contract groups + +Contract groups require protocol version 14. + +A contract group is an identity-owned set of contracts, document types and tokens. It is not the same as the change-control [data contract groups](#data-contract-groups) above, which distribute update authorization inside a single contract. + +A group is registered by a [Data Contract Create](#data-contract-create) transition using format version `1`. The identity that signs the transition owns the group; the owner is not a wire field. The group ID is `hash_double("contract_group" || owner ID || identity nonce as big-endian bytes)`, so the client knows it before broadcasting. + +| Field | Type | Description | +|-------|------|-------------| +| `admins` | set of identity IDs | Identities that may add members alongside the owner. May be empty. At most 16, and the owner must not be listed. Each must be an existing identity that is not a masternode. | +| `name` | string (optional) | 1 to 64 Unicode characters when present | +| `description` | string (optional) | 1 to 256 Unicode characters when present | + +Admins act on their own; there is no threshold. Registering a group whose ID already exists is rejected (`41000`), and an admin that does not exist is rejected (`41003`). + +Invalid admin lists are rejected with `10364`; invalid name and description lengths are rejected with `10366` and `10367`. These lengths count characters, not UTF-8 bytes. The limits are listed in [Protocol Constants](protocol-constants.md#system-limits). + +#### Contract group memberships + +A create transition also declares which parts of the contract it creates join a contract group. Each membership names a `contractGroupId` and a `member`: + +| Member | Description | +|--------|-------------| +| Whole contract | Every document type and token the contract has or later gains | +| Document type | One document type of the contract, by name | +| Token | One token of the contract, by its position | + +A contract can only enroll its own parts, never another contract. At most 16 memberships per contract. The named document type or token must exist in the contract being created (`10363`), a membership must not repeat (`10361`), and a membership is redundant if the same group already has a whole-contract membership (`10362`). Exceeding the cap is rejected with `10360`. + +The group joined must already exist (`41001`), or be the group registered by the same transition, and the creating identity must be its owner or an admin (`41002`). Memberships are declared only when the contract is created. + +Once the signer is authenticated, a contract-group state validation failure is a paid failure that bumps the identity nonce. See the [contract group definitions](https://github.com/dashpay/platform/blob/v4.2-dev/packages/rs-dpp/src/contract_group/mod.rs#L28-L177), [basic validation](https://github.com/dashpay/platform/blob/v4.2-dev/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_create/basic_structure/v2/mod.rs#L125-L230), and [state validation](https://github.com/dashpay/platform/blob/v4.2-dev/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_create/state/v1/mod.rs#L110-L277) for the rules and [Errors](errors.md#contract-group-state) for the state error codes. + ## Data Contract State Transition Details There are two data contract-related state transitions: [data contract create](#data-contract-create) and [data contract update](#data-contract-update). Details are provided in this section. @@ -1267,15 +1301,17 @@ Data contracts are created on the platform by submitting the [data contract obje | Field | Type | Size | Description | | --------------- | -------------- | ---- | ----------- | -| $formatVersion | unsigned integer | 16 bits | The state transition format version (currently `0`) | +| $formatVersion | unsigned integer | 16 bits | Data Contract Create supports `0` and `1`. The DPP constructors default to `1` from protocol version 14; `1` supports the contract group fields below and requires protocol version 14. | | type | unsigned integer | 8 bits | State transition type (`0` for data contract create) | | dataContract | [data contract object](#data-contract-object) | Varies | Object containing the data contract details | | identityNonce | unsigned integer | 64 bits | Identity nonce for this transition to prevent replay attacks | +| contractGroup | object | Varies | (Optional; version `1` only) Registers a new [contract group](#contract-groups) owned by the signing identity. Contains `admins` (set of identity IDs, may be empty), `name` (optional string) and `description` (optional string). | +| contractGroupMemberships | array | Varies | (Version `1` only; defaults to empty) Contract groups the new contract joins. Each entry has `contractGroupId` and a `member` that is the whole contract, one document type (by name), or one token (by position). Empty for a plain contract creation. | | userFeeIncrease | unsigned integer | 16 bits | Extra fee to prioritize processing if the mempool is full. Typically set to zero. | | 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/v4.2-dev/packages/rs-dpp/src/state_transition/state_transitions/contract/data_contract_create_transition/v0/mod.rs#L36-L44) for more details. +See the [version 0](https://github.com/dashpay/platform/blob/v4.2-dev/packages/rs-dpp/src/state_transition/state_transitions/contract/data_contract_create_transition/v0/mod.rs#L36-L44) and [version 1](https://github.com/dashpay/platform/blob/v4.2-dev/packages/rs-dpp/src/state_transition/state_transitions/contract/data_contract_create_transition/v1/mod.rs#L40-L52) data contract create implementations in rs-dpp for more details. ### Data Contract Update diff --git a/docs/protocol-ref/document.md b/docs/protocol-ref/document.md index eab72147b..70fc4c4d7 100644 --- a/docs/protocol-ref/document.md +++ b/docs/protocol-ref/document.md @@ -110,6 +110,8 @@ Each document create transition must comply with the structure defined in [rs-dp ::: {note} The document create transition data field must include all [required document properties](./data-contract-document.md#required-properties) specified in the data contract. + +A create is rejected if a document with the same `$id` already exists ([`DocumentAlreadyPresentError`](errors.md), code 40100). From protocol version 14, a create without `$prefundedVotingBalance` on a document type with a contested index is also rejected if the `$id` is already in the contested document tree ([`DocumentContestDocumentWithSameIdAlreadyPresentError`](errors.md), code 40113). ::: The following example document create transition and subsequent table demonstrate how the document transition base, document create transition, and data contract document definitions are assembled into a complete transition for inclusion in a [state transition](#document-overview): diff --git a/docs/protocol-ref/errors.md b/docs/protocol-ref/errors.md index 14f9c8fea..30d3d400f 100644 --- a/docs/protocol-ref/errors.md +++ b/docs/protocol-ref/errors.md @@ -15,7 +15,7 @@ Platform error codes are organized into four categories. Each category may be fu | [Basic](#basic-errors) | 10000 - 10999 | Errors encountered while validating structure and data | | [Signature](#signature-errors) | 20000 - 20999 | Errors encountered while validating identity existence and state transition signature | | [Fee](#fee-errors) | 30000 - 30999 | Errors encountered while validating an identity's balance is sufficient to pay fees | -| [State](#state-errors) | 40000 - 40999 | Errors encounter while validating state transitions against the platform state | +| [State](#state-errors) | 40000 - 41099 | Errors encounter while validating state transitions against the platform state | ## Basic Errors @@ -146,6 +146,14 @@ Code range: 10350-10399 | 10357 |MainGroupIsNotDefinedError | | | 10358 |GroupRequiredPowerIsInvalidError | | | 10359 |GroupHasTooFewMembersError | | +| 10360 | ContractGroupMembershipsOverLimitError | | +| 10361 | DuplicateContractGroupMembershipError | | +| 10362 | RedundantContractGroupMembershipError | | +| 10363 | ContractGroupMemberNotInContractError | | +| 10364 | InvalidContractGroupAdminsError | | +| 10365 | *(unassigned)* | The registrant-not-owner rule became inexpressible when the owner was removed from the wire format before protocol version 14 shipped | +| 10366 | InvalidContractGroupNameLengthError | | +| 10367 | InvalidContractGroupDescriptionLengthError | | ### Document @@ -233,6 +241,10 @@ Code range: 10500-10599 | 10532 | WithdrawalOutputScriptNotAllowedWhenSigningWithOwnerKeyError | | | 10533 | InvalidKeyPurposeForContractBoundsError | | | 10534 | IdentityAssetLockTransactionTooManyInputsError | | +| 10535 | ContractGroupBoundKeyNotAllowedInShieldedIdentityCreationError | | +| 10536 | IdentityPublicKeyLimitsNotAllowedError | | +| 10537 | InvalidIdentityPublicKeyBudgetError | | +| 10538 | IdentityPublicKeyLimitsNotAllowedInShieldedIdentityCreationError | | ### State Transition @@ -287,6 +299,7 @@ Code range: 10800-10899 | 10825 | ShieldedTooManyActionsError | | | 10826 | ShieldedImplicitFeeCapExceededError | | | 10827 | ShieldedInvalidDenominationError | | +| 10828 | InvalidTokenDistributionEpochIntervalTooShortError | Token distribution error; minimum epoch interval is 1 | ## Signature Errors @@ -305,6 +318,10 @@ Code range: 10800-10899 | 20010 | BasicBLSError | | | 20011 | InvalidSignaturePublicKeyPurposeError | | | 20012 | UncompressedPublicKeyNotAllowedError | | +| 20013 | ContractBoundedKeyNonBatchError | | +| 20014 | ContractBoundedKeyOutOfBoundsError | Enforced during batch advanced-structure validation; an authenticated out-of-bounds member is a paid failure | +| 20015 | PublicKeyBudgetExhaustedError | | +| 20016 | PublicKeyExpiredError | Enforced during fee validation against the block time | ## Fee Errors @@ -418,6 +435,8 @@ Code range: 40200-40299 | 40215 | NoTransferKeyForCoreWithdrawalAvailableError | | | 40216 | RecipientIdentityDoesNotExistError | | | 40217 | IdentityToFreezeDoesNotExistError | | +| 40218 | IdentityPublicKeyBudgetExceededError | | +| 40219 | IdentityPublicKeyAlreadyExpiredError | | ### Voting State @@ -486,3 +505,14 @@ Code range: 40900-40999 | 40902 | InvalidShieldedProofError | | | 40903 | InsufficientPoolNotesError | | | 40904 | InsufficientShieldedFeeError | | + +### Contract Group State + +Code range: 41000-41099 + +| Code | Error Description | Comment | +| :---: | ----------------------------------------- | ------- | +| 41000 | ContractGroupAlreadyExistsError | | +| 41001 | ContractGroupNotFoundError | | +| 41002 | IdentityNotContractGroupOwnerOrAdminError | | +| 41003 | ContractGroupAdminNotFoundError | | diff --git a/docs/protocol-ref/identity.md b/docs/protocol-ref/identity.md index 0d4840535..e2d23dec7 100644 --- a/docs/protocol-ref/identity.md +++ b/docs/protocol-ref/identity.md @@ -63,17 +63,24 @@ Each item in the `publicKeys` array consists of an object containing: | Field | Type | Description | | ------------- | -------------- | ----------- | +| $formatVersion | string (JSON) | Key format version: `"0"`, or `"1"` from protocol version 14. Version `1` supports the optional usage limits below. | | [id](#public-key-id) | integer | The key id (all public keys must be unique) | | [purpose](#public-key-purpose) | integer | Public key purpose (`0` - Authentication, `1` - Encryption, `2` - Decryption, `3` - Transfer) | | [securityLevel](#public-key-securitylevel) | integer | Public key security level (`0` - Master, `1` - Critical, `2` - High, `3` - Medium) | -| contractBounds | object (optional) | Restricts this key to a specific data contract or document type context | +| [contractBounds](#public-key-contractbounds) | object (optional) | Restricts this key to a data contract (`$type` `singleContract`), a document type (`documentType`), or a contract group (`contractGroup`, protocol version 14) | | [type](#public-key-type) | integer | Type of key (default: `0` - ECDSA) | | [readOnly](#public-key-readonly) | boolean | Identity public key can’t be modified with `readOnly` set to `true`. This can’t be changed after adding a key. | | [data](#public-key-data) | array of bytes | Public key (`0` - ECDSA: 33 bytes, `1` - BLS: 48 bytes, `2` - ECDSA Hash160: 20 bytes, `3` - [BIP13](https://github.com/bitcoin/bips/blob/master/bip-0013.mediawiki) Hash160: 20 bytes, `4` - EDDSA_25519_HASH160: 20 bytes) | | [disabledAt](#public-key-disabledat) | integer | Timestamp indicating that the key was disabled at a specified time | +| totalBudget | unsigned integer (64 bits, optional) | Budget in credits for transitions signed with this key; metered processing fees can exceed it as described below. Must be greater than `0`. Only allowed on authentication keys with security level `1`, `2`, or `3`. Requires key format version `1` (protocol version 14). | +| expiresAt | unsigned integer (64 bits, optional) | Block time (milliseconds) from which the key can no longer sign. Must be later than the block time when the key is added. Only allowed on authentication keys with security level `1`, `2`, or `3`. Requires key format version `1` (protocol version 14). | | signature | array of bytes | Signature of the signable state transition adding the key (identity create, identity update, or identity create from addresses) by the private key for this public key. Must be empty for key types `2`, `3`, and `4`. | -See the [public key implementation in rs-dpp](https://github.com/dashpay/platform/blob/v4.2-dev/packages/rs-dpp/src/identity/identity_public_key/v0/mod.rs#L43-L61) for more details. +Each key has a `$formatVersion`. Version `0` keys have the fields above except `totalBudget` and `expiresAt`. Version `1` keys (protocol version 14 and later) add those two optional fields; keys without limits ordinarily use version `0`; the V1 format can also carry no limits. See the [version 0](https://github.com/dashpay/platform/blob/v4.2-dev/packages/rs-dpp/src/identity/identity_public_key/v0/mod.rs#L43-L61) and [version 1](https://github.com/dashpay/platform/blob/v4.2-dev/packages/rs-dpp/src/identity/identity_public_key/v1/mod.rs#L39-L58) public key implementations in rs-dpp for more details. + +The original `totalBudget` stays on the key; the remaining budget is tracked separately in Drive and stops at zero. Removed credits, storage fees, fixed fees and the user fee increase must fit within the remaining budget, but metered processing fees can exceed it. A key with no remaining budget cannot sign. Limits on a MASTER or non-authentication key are rejected with error `10536`, a zero budget with `10537`, and an expiry at or before the block adding the key with `40219`. + +The limits are included in the signable bytes when adding a key. Changing the proposed limits before submission requires signing again; this does not make an already registered key's limits editable. #### Public Key `id` @@ -135,6 +142,24 @@ value of this field cannot be changed after adding the key. The `disabledAt` field indicates that the key has been disabled. Its value equals the timestamp when the key was disabled. +#### Public Key `contractBounds` + +The optional `contractBounds` object limits where a key may be used. Its `$type` selects the bound: + +| `$type` | Fields | Description | +| --- | --- | --- | +| `singleContract` | `id` | The key is limited to one data contract | +| `documentType` | `id`, `documentTypeName` | The key is limited to one document type of a data contract | +| `contractGroup` | `id` | The key is limited to the contracts, document types, and tokens that belong to a contract group when the key signs | + +The JSON `$type` values above are names; their binary discriminants are `0`, `1`, and `2`, respectively. + +From protocol version 14, authentication keys may carry contract bounds. No contract opt-in or uniqueness rule is required for authentication bounds. A bound authentication key cannot be a master key, and the contract, document type, or contract group it names must exist. It can only sign [batch](state-transition.md#batch) state transitions, and every transition in the batch must be within the bounds. The `contractGroup` bound is only allowed on authentication keys. + +Encryption and decryption keys retain their separate rules: the bound contract or document type must opt in to bounded keys for that purpose, and its configured uniqueness requirements apply. These keys cannot use a `contractGroup` bound. + +See the [ContractBounds implementation in rs-dpp](https://github.com/dashpay/platform/blob/v4.2-dev/packages/rs-dpp/src/identity/identity_public_key/contract_bounds/mod.rs#L51-L65) for more details. + ### Identity balance Each identity has a balance of credits established by an [asset lock transaction](inv:user:std#ref-txs-assetlocktx) on the Core chain. This credit balance is used to pay the fees associated with state transitions. @@ -164,8 +189,8 @@ Total = identity_create_base_cost + asset_lock_base_cost + (number_of_keys × id **Examples:** - 1 key: 2,000,000 + 200,000,000 + 6,500,000 = **208,500,000 credits** (0.002085 Dash) -- 2 keys: 2,000,000 + 13,000,000 = **15,000,000 credits** (0.00015 Dash) -- 6 keys: 2,000,000 + 39,000,000 = **41,000,000 credits** (0.00041 Dash) +- 2 keys: 2,000,000 + 200,000,000 + 13,000,000 = **215,000,000 credits** (0.00215 Dash) +- 6 keys: 2,000,000 + 200,000,000 + 39,000,000 = **241,000,000 credits** (0.00241 Dash) ### Minimum Funding Requirements @@ -185,15 +210,15 @@ The following state transitions create, fund, update, or transfer credits to or | Type | Name | Supported protocol versions | | --- | --- | --- | -| 2 | [Identity Create](#identity-create) | ≥ 1 | +| 2 | [Identity Create](#identity-create) | ≥ 1 (≥ 14 if any key is format version `1` or has a `contractGroup` bound) | | 3 | [Identity Top-Up](#identity-topup) | ≥ 1 | -| 5 | [Identity Update](#identity-update) | ≥ 1 | +| 5 | [Identity Update](#identity-update) | ≥ 1 (≥ 14 if any added key is format version `1` or has a `contractGroup` bound) | | 6 | [Identity Credit Withdrawal](#identity-credit-withdrawal) | ≥ 1 | | 7 | [Identity Credit Transfer](#identity-credit-transfer) | ≥ 1 | | 9 | [Identity Credit Transfer to Addresses](address-system.md#identity-credit-transfer-to-addresses) | ≥ 11 | -| 10 | [Identity Create from Addresses](address-system.md#identity-create-from-addresses) | ≥ 11 | +| 10 | [Identity Create from Addresses](address-system.md#identity-create-from-addresses) | ≥ 11 (≥ 14 if any key is format version `1` or has a `contractGroup` bound) | | 11 | [Identity Top-Up from Addresses](address-system.md#identity-top-up-from-addresses) | ≥ 11 | -| 20 | [Identity Create from Shielded Pool](shielded-pool.md#identity-create-from-shielded-pool) | ≥ 12 | +| 20 | [Identity Create from Shielded Pool](shielded-pool.md#identity-create-from-shielded-pool) | ≥ 12 (≥ 14 if any key is format version `1` or has a `contractGroup` bound) | | 21 | [Shield from Identity](shielded-pool.md#shield-from-identity) | ≥ 14 | | 22 | [Identity Top-Up from Shielded Pool](shielded-pool.md#identity-top-up-from-shielded-pool) | ≥ 14 | @@ -288,7 +313,7 @@ Credits can be withdrawn from an identity to an external Core wallet using an id | signature | array of bytes | Signature of state transition data (65 bytes) | :::{note} -**Constraints:** `pooling` must be `0` (Never); `1` (IfAvailable) and `2` (Standard) are not yet implemented. `coreFeePerByte` must be a non-zero [Fibonacci number](https://en.wikipedia.org/wiki/Fibonacci_sequence). `outputScript`, when set, must be P2PKH or P2SH. `amount` must be within the [min and max withdrawal amount](protocol-constants.md) limits. +**Constraints:** `pooling` must be `0` (Never); `1` (IfAvailable) and `2` (Standard) are not yet implemented. `coreFeePerByte` must be a non-zero [Fibonacci number](https://en.wikipedia.org/wiki/Fibonacci_sequence); from protocol version 14 it is also capped at 6,765, and a higher rate is rejected with error `10522`. `outputScript`, when set, must be P2PKH or P2SH. `amount` must be within the [min and max withdrawal amount](protocol-constants.md) limits. From protocol version 14 the Core fee of the withdrawal transaction (190 bytes x `coreFeePerByte` duffs, or 190,000 x `coreFeePerByte` credits) is taken from `amount`, so `amount` must be at least the minimum withdrawal amount plus that fee: 1,190,000 credits at `coreFeePerByte` 1 and 1,286,350,000 credits at 6,765. An `amount` below that floor is rejected with error `10525`. The recipient receives `amount` less the Core fee. ::: See the [identity credit withdrawal implementation in rs-dpp](https://github.com/dashpay/platform/blob/v4.2-dev/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_withdrawal_transition/v1/mod.rs#L31-L48) for more details. diff --git a/docs/protocol-ref/protocol-constants.md b/docs/protocol-ref/protocol-constants.md index 408e8b5cb..e9c26d4ac 100644 --- a/docs/protocol-ref/protocol-constants.md +++ b/docs/protocol-ref/protocol-constants.md @@ -21,14 +21,18 @@ Maximum sizes and limits for various platform components. | Retry signing expired withdrawals per block | 1 | Max expired withdrawal retries per block | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.2-dev/packages/rs-platform-version/src/version/system_limits/v3.rs#L20) | | Max withdrawal amount | 50,000,000,000,000 credits | 500 Dash maximum per withdrawal | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.2-dev/packages/rs-platform-version/src/version/system_limits/v3.rs#L21) | | Daily withdrawal limit | Protocol versions 8-13: 200,000,000,000,000 credits (2000 Dash)
Protocol version 14+: 15% of the credits Platform held one day earlier, with a 500-Dash floor and 4000-Dash cap | The relative limit added in 4.2.0 is `min(max(day-old total × 15%, max withdrawal amount), 4000 Dash)`. Until a full day of credit history is available after activation, the previous 2000-Dash limit remains in effect. | [v8-v13](https://github.com/dashpay/platform/blob/v4.2-dev/packages/rs-dpp/src/withdrawal/daily_withdrawal_limit/v1/mod.rs), [v14+](https://github.com/dashpay/platform/blob/v4.2-dev/packages/rs-dpp/src/withdrawal/daily_withdrawal_limit/v2/mod.rs) | -| Max contract group size | 256 | Maximum members per group | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.2-dev/packages/rs-platform-version/src/version/system_limits/v3.rs#L26) | -| Max token redemption cycles | 128 | Maximum redemption cycles | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.2-dev/packages/rs-platform-version/src/version/system_limits/v3.rs#L27) | -| Max shielded transition actions | 16 | Consensus cap on [actions](shielded-pool.md#actions) per shielded transition. The effective limit is 6 - the Halo 2 proof grows ~2,681 bytes per action, so larger transitions exceed the max state transition size | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.2-dev/packages/rs-platform-version/src/version/system_limits/v3.rs#L35) | -| Max time-range overlap factor | 24 | **Added in 4.2.0.** Maximum `range / step` for a [timeRange](data-contract-document.md#document-indices) index, so at most 24 windows overlap at any timestamp | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.2-dev/packages/rs-platform-version/src/version/system_limits/v4.rs#L65) | -| Max time-range TTL | 604,800 seconds (1 week) | **Added in 4.2.0.** Maximum `ttl` a [timeRange](data-contract-document.md#document-indices) index may declare | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.2-dev/packages/rs-platform-version/src/version/system_limits/v4.rs#L66) | -| Min time-range TTL drop operations per write | 32 | **Added in 4.2.0.** Minimum expired-entry cleanup operations Drive performs on each write into a `ttl` index | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.2-dev/packages/rs-platform-version/src/version/system_limits/v4.rs#L67) | -| Core dust relay fee | 3,000 duffs/kB | **Added in 4.2.0.** Used to compute the Core dust threshold of a withdrawal's output script (546 duffs for P2PKH). An expired withdrawal whose whole amount is below it is marked `FAILED` instead of being re-signed | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.2-dev/packages/rs-platform-version/src/version/system_limits/v4.rs#L54) | -| Min GroveDB proof envelope version | 1 | **Added in 4.2.0.** Clients verifying with protocol version 14 tables reject the legacy V0 proof envelope | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.2-dev/packages/rs-platform-version/src/version/system_limits/v4.rs#L68) | +| Max group member count | 256 | Maximum members of a group defined inside a data contract (token change-control groups). Not related to contract groups | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.2-dev/packages/rs-platform-version/src/version/system_limits/v3.rs#L27) | +| Max contract group memberships per contract | 16 | Maximum contract group memberships one data contract create transition may declare | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.2-dev/packages/rs-platform-version/src/version/system_limits/v4.rs#L64) | +| Max contract group admins | 16 | Maximum admins a contract group may name besides its owner | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.2-dev/packages/rs-platform-version/src/version/system_limits/v4.rs#L65) | +| Max contract group name length | 64 characters | Name must contain 1–64 characters when present | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.2-dev/packages/rs-platform-version/src/version/system_limits/v4.rs#L66) | +| Max contract group description length | 256 characters | Description must contain 1–256 characters when present | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.2-dev/packages/rs-platform-version/src/version/system_limits/v4.rs#L67) | +| Max token redemption cycles | 128 | Maximum redemption cycles | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.2-dev/packages/rs-platform-version/src/version/system_limits/v3.rs#L32) | +| Max shielded transition actions | 16 | Consensus cap on [actions](shielded-pool.md#actions) per shielded transition. The effective limit is 6 - the Halo 2 proof grows ~2,681 bytes per action, so larger transitions exceed the max state transition size | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.2-dev/packages/rs-platform-version/src/version/system_limits/v3.rs#L40) | +| Max time-range overlap factor | 24 | **Added in 4.2.0.** Maximum `range / step` for a [timeRange](data-contract-document.md#document-indices) index, so at most 24 windows overlap at any timestamp | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.2-dev/packages/rs-platform-version/src/version/system_limits/v4.rs#L77) | +| Max time-range TTL | 604,800 seconds (1 week) | **Added in 4.2.0.** Maximum `ttl` a [timeRange](data-contract-document.md#document-indices) index may declare | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.2-dev/packages/rs-platform-version/src/version/system_limits/v4.rs#L78) | +| Min time-range TTL drop operations per write | 32 | **Added in 4.2.0.** Minimum expired-entry cleanup operations Drive performs on each write into a `ttl` index | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.2-dev/packages/rs-platform-version/src/version/system_limits/v4.rs#L79) | +| Core dust relay fee | 3,000 duffs/kB | **Added in 4.2.0.** Used to compute the Core dust threshold of a withdrawal's output script (546 duffs for P2PKH). An expired withdrawal whose whole amount is below it is marked `FAILED` instead of being re-signed | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.2-dev/packages/rs-platform-version/src/version/system_limits/v4.rs#L61) | +| Min GroveDB proof envelope version | 1 | **Added in 4.2.0.** Clients verifying with protocol version 14 tables reject the legacy V0 proof envelope | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.2-dev/packages/rs-platform-version/src/version/system_limits/v4.rs#L80) | | Max CBOR encoded length | 16,384 bytes (16 KiB) | Maximum CBOR encoding size (defined as `MAX_ENCODED_KBYTE_LENGTH = 16` kibibytes) | [rs-dpp](https://github.com/dashpay/platform/blob/v4.2-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/v4.2-dev/packages/rs-dpp/src/data_contract/serialized_version/mod.rs#L40) | @@ -184,7 +188,7 @@ Fees related to contested document voting. | Min asset lock balance | 200,000 duffs | 0.002 Dash minimum | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.2-dev/packages/rs-platform-version/src/version/dpp_versions/dpp_state_transition_versions/v3.rs#L20) | | Min top-up balance | 50,000 duffs | 0.0005 Dash minimum | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.2-dev/packages/rs-platform-version/src/version/dpp_versions/dpp_state_transition_versions/v3.rs#L21) | | Min address funding balance | 50,000 duffs | 0.0005 Dash minimum | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.2-dev/packages/rs-platform-version/src/version/dpp_versions/dpp_state_transition_versions/v3.rs#L22) | -| Min identity funding amount | 200,000 credits | Minimum for address-based creation | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.2-dev/packages/rs-platform-version/src/version/dpp_versions/dpp_state_transition_versions/v3.rs#L42) | +| Min identity funding amount | 200,000 credits | Minimum for address-based creation | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.2-dev/packages/rs-platform-version/src/version/dpp_versions/dpp_state_transition_versions/v3.rs#L43) | | 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.2-dev/packages/rs-platform-version/src/version/dpp_versions/dpp_state_transition_versions/v3.rs#L25) | ## Document & Data Contract Model @@ -272,11 +276,11 @@ These limits apply to token perpetual distribution function parameters. | Limit | Value | Description | Source | |-------|-------|-------------|--------| -| Min output amount | 500,000 credits | Minimum output per address | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.2-dev/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.2-dev/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.2-dev/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.2-dev/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.2-dev/packages/rs-platform-version/src/version/dpp_versions/dpp_state_transition_versions/v3.rs#L45) | +| Min output amount | 500,000 credits | Minimum output per address | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.2-dev/packages/rs-platform-version/src/version/dpp_versions/dpp_state_transition_versions/v3.rs#L41) | +| Min input amount | 100,000 credits | Minimum input per address | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.2-dev/packages/rs-platform-version/src/version/dpp_versions/dpp_state_transition_versions/v3.rs#L42) | +| Max fee strategies | 4 | Maximum fee strategy steps | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.2-dev/packages/rs-platform-version/src/version/dpp_versions/dpp_state_transition_versions/v3.rs#L50) | +| Max address inputs | 16 | Maximum input addresses per address-based transition | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.2-dev/packages/rs-platform-version/src/version/dpp_versions/dpp_state_transition_versions/v3.rs#L48) | +| Max address outputs | 128 | Maximum output addresses per address-based transition | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.2-dev/packages/rs-platform-version/src/version/dpp_versions/dpp_state_transition_versions/v3.rs#L49) | | 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.2-dev/packages/rs-platform-version/src/version/dpp_versions/dpp_state_transition_versions/v3.rs#L25) | ## Epoch and Time Constants @@ -299,5 +303,6 @@ These limits apply to token perpetual distribution function parameters. | Constant | Value | Description | Source | |----------|-------|-------------|--------| -| Min withdrawal amount | 1,000,000 credits | 1,000 duffs minimum per withdrawal (protocol version 12 and later; raised from 190,000 credits in earlier versions) | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.2-dev/packages/rs-platform-version/src/version/system_limits/v3.rs#L24) | +| Min withdrawal amount | 1,000,000 credits | Minimum reserved withdrawal amount from protocol version 12 (raised from 190,000 credits). From protocol version 14, this is the recipient's output floor: the amount reserved for Core must also cover the Core fee. The fee-inclusive minimum is 1,190,000 credits at `coreFeePerByte` 1 and 1,286,350,000 credits at 6,765 | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.2-dev/packages/rs-platform-version/src/version/system_limits/v4.rs#L60), [rs-dpp](https://github.com/dashpay/platform/blob/v4.2-dev/packages/rs-dpp/src/withdrawal/mod.rs#L92-L110) | +| Max core fee per byte | 6,765 duffs/byte | Maximum `coreFeePerByte` a withdrawal may request from protocol version 14. The Core fee is `190 × coreFeePerByte × 1,000` credits; at the cap it is 1,285,350,000 credits. Earlier protocol versions have no cap | [rs-platform-version](https://github.com/dashpay/platform/blob/v4.2-dev/packages/rs-platform-version/src/version/system_limits/v4.rs#L62), [rs-dpp](https://github.com/dashpay/platform/blob/v4.2-dev/packages/rs-dpp/src/withdrawal/mod.rs#L60-L89) | | Min core fee per byte | 1 | Must be Fibonacci number | [rs-dpp](https://github.com/dashpay/platform/blob/v4.2-dev/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_withdrawal_transition/mod.rs#L39) | diff --git a/docs/protocol-ref/shielded-pool.md b/docs/protocol-ref/shielded-pool.md index 31bd03f81..28bba9fda 100644 --- a/docs/protocol-ref/shielded-pool.md +++ b/docs/protocol-ref/shielded-pool.md @@ -57,7 +57,7 @@ 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) | -Each action permanently stores [344 bytes](https://github.com/dashpay/platform/blob/v4.2-dev/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v9.rs#L357) (312 bytes in the note commitment tree + 32 bytes in the nullifier tree). The minimum shielded fee charges a per-action storage allowance of `shielded_storage_bytes_per_action` bytes at the storage rate: 344 bytes through protocol version 13, and 550 bytes from protocol version 14 to cover tree framing overhead. +Each action permanently stores [344 bytes](https://github.com/dashpay/platform/blob/v4.2-dev/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v9.rs#L358) (312 bytes in the note commitment tree + 32 bytes in the nullifier tree). The minimum shielded fee charges a per-action storage allowance of `shielded_storage_bytes_per_action` bytes at the storage rate: 344 bytes through protocol version 13, and 550 bytes from protocol version 14 to cover tree framing overhead. See the [serialized action implementation in rs-dpp](https://github.com/dashpay/platform/blob/v4.2-dev/packages/rs-dpp/src/shielded/mod.rs). @@ -65,7 +65,7 @@ See the [serialized action implementation in rs-dpp](https://github.com/dashpay/ 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). -Anchors are not retained indefinitely. Nodes keep a rolling window governed by [`shielded_anchor_retention_blocks` and `shielded_anchor_pruning_interval`](https://github.com/dashpay/platform/blob/v4.2-dev/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v1.rs#L297-L298), pruning anchors older than the retention window at each pruning boundary. A prover selecting an anchor must therefore choose one from the current window, not from arbitrary history. +Anchors are not retained indefinitely. Nodes keep a rolling window governed by [`shielded_anchor_retention_blocks` and `shielded_anchor_pruning_interval`](https://github.com/dashpay/platform/blob/v4.2-dev/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v1.rs#L298-L299), pruning anchors older than the retention window at each pruning boundary. A prover selecting an anchor must therefore choose one from the current window, not from arbitrary history. ### Platform Sighash @@ -179,14 +179,14 @@ Move credits from the pool back to Dash Core (L1). The funds leave Platform enti :::{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). -**Constraints:** Pooling must be `Never` (others not yet implemented). `coreFeePerByte` must be a non-zero Fibonacci number. Output script must be P2PKH or P2SH. +**Constraints:** Pooling must be `Never` (others not yet implemented). `coreFeePerByte` must be a non-zero Fibonacci number; from protocol version 14 it is also capped at 6,765, and a higher rate is rejected with error `10522`. Output script must be P2PKH or P2SH. From protocol version 14 the Core fee of the withdrawal transaction (190 bytes x `coreFeePerByte` duffs, or 190,000 x `coreFeePerByte` credits) is taken from the amount reserved for Core, which is `unshieldingAmount` less the Platform fee for the transition's actions. That reserved amount must be at least the minimum withdrawal amount plus the Core fee: 1,190,000 credits at `coreFeePerByte` 1 and 1,286,350,000 credits at 6,765. A reserved amount below that floor is rejected with error `10818`, and one above the maximum withdrawal amount with error `10525`. If `unshieldingAmount` cannot cover the Platform fee, structure validation leaves the rejection to fee validation. The recipient receives the reserved amount less the Core fee. ::: See the [implementation in rs-dpp](https://github.com/dashpay/platform/blob/v4.2-dev/packages/rs-dpp/src/state_transition/state_transitions/shielded/shielded_withdrawal_transition/v0/mod.rs#L33-L54). ### 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). +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 uses the public key structure of an ordinary [Identity Create](identity.md#identity-create), but starting with protocol version 14 its keys cannot be bound to a contract group or carry a budget or expiry. Those keys can be added later using an [Identity Update](identity.md#identity-update). A version `1` key without these restrictions is allowed. The restriction protects fields absent from the Orchard sighash layout: group-bound keys produce error 10535, and keys with limits produce error 10538. Group-bound key errors take precedence. | Field | Type | Size | Description | | --- | --- | --- | --- | @@ -216,7 +216,7 @@ The `denomination` field must exactly match one of the values accepted by the ac | 14 | 0.03 DASH (3,000,000,000 credits), 0.1 DASH (10,000,000,000), 0.25 DASH (25,000,000,000), 0.5 DASH (50,000,000,000), 1 DASH (100,000,000,000) | | 12 | 0.1 DASH (10,000,000,000 credits), 0.3 DASH (30,000,000,000), 0.5 DASH (50,000,000,000), 1 DASH (100,000,000,000) | -Protocol version 13 added 0.03 and 0.25 DASH and retired 0.3 DASH. Protocol version 14 keeps the version 13 set unchanged. The protocol version 12 set is retained for chain replay. See the [denomination set in rs-platform-version](https://github.com/dashpay/platform/blob/v4.2-dev/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v10.rs#L386-L394). +Protocol version 13 added 0.03 and 0.25 DASH and retired 0.3 DASH. Protocol version 14 keeps the version 13 set unchanged. The protocol version 12 set is retained for chain replay. See the [denomination set in rs-platform-version](https://github.com/dashpay/platform/blob/v4.2-dev/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v10.rs#L392-L398). See the [implementation in rs-dpp](https://github.com/dashpay/platform/blob/v4.2-dev/packages/rs-dpp/src/state_transition/state_transitions/shielded/identity_create_from_shielded_pool_transition/v0/mod.rs#L31-L64). diff --git a/docs/protocol-ref/state-transition.md b/docs/protocol-ref/state-transition.md index 2da9d36da..22f7ed35d 100644 --- a/docs/protocol-ref/state-transition.md +++ b/docs/protocol-ref/state-transition.md @@ -25,7 +25,7 @@ The list of common fields used by multiple state transitions is defined in [rs-d | Field | Type | Size | Description | | --------------- | -------------- | ---- | ----------- | -| $formatVersion | 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. | +| $formatVersion | unsigned integer | 16 bits | The state transition format version (FeatureVersion). Currently `0` for most transitions; `1` for Batch; `0` or `1` for Data Contract Create (`1` carries contract groups and requires protocol version 14). 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/v4.2-dev/packages/rs-dpp/src/state_transition/state_transition_types.rs#L22)). 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 or 96 bytes | Signature of state transition data. Present on identity-signed and asset-lock-signed transitions (types 0-9, 13, 18, and 21): 65 bytes for ECDSA signatures or 96 bytes for BLS signatures. | @@ -72,6 +72,10 @@ Dash Platform Protocol defines the following [state transition types](https://gi | 21 | Shield from Identity | [Shield from Identity](shielded-pool.md#shield-from-identity) (added in 4.2.0) | | 22 | Identity Top Up From Shielded Pool | [Identity Top Up From Shielded Pool](shielded-pool.md#identity-top-up-from-shielded-pool) (added in 4.2.0) | +:::{note} +Each state transition is active from a given protocol version. For some, the version depends on content: a Data Contract Create with format version `1`, or an identity transition adding a key with format version `1` or a `contractGroup` bound, is active from protocol version 14. A transition that is not active at the current protocol version is [rejected](https://github.com/dashpay/platform/blob/v4.2-dev/packages/rs-dpp/src/state_transition/mod.rs#L885-L903) before any fee is charged. +::: + ### Batch | Field | Type | Size | Description | @@ -147,6 +151,8 @@ Within a batch, token transfers are restricted to a CRITICAL (`1`) key. An ident hold a MASTER key for identity updates and, for the other transitions it will sign, a key meeting that transition's minimum level. +From protocol version 14, an authentication key with [contract bounds](identity.md#public-key-contractbounds) can only sign a batch, and every member must fall within those bounds. A key with `totalBudget` cannot sign when its remaining budget is zero. The credits removed, storage fee, fixed fees and user fee increase must fit within the remaining budget; metered processing fees can exceed it. A key with `expiresAt` cannot sign once the block time reaches that value. An out-of-bounds batch member produces a paid failure and bumps the identity's data contract nonce. + The process to sign state transitions using an identity consists of the following steps: 1. **Create a canonical, signable state transition** encoded using [Bincode](https://github.com/bincode-org/bincode). @@ -200,7 +206,7 @@ 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/v4.2-dev/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v1/mod.rs#L34-L37) | Exclude | Exclude | N/A | N/A | -| [Contract create](https://github.com/dashpay/platform/blob/v4.2-dev/packages/rs-dpp/src/state_transition/state_transitions/contract/data_contract_create_transition/v0/mod.rs#L40-L43) | Exclude | Exclude | N/A | N/A | +| Contract create ([v0](https://github.com/dashpay/platform/blob/v4.2-dev/packages/rs-dpp/src/state_transition/state_transitions/contract/data_contract_create_transition/v0/mod.rs#L40-L43), [v1](https://github.com/dashpay/platform/blob/v4.2-dev/packages/rs-dpp/src/state_transition/state_transitions/contract/data_contract_create_transition/v1/mod.rs#L48-L51)) | Exclude | Exclude | N/A | N/A | | [Contract update](https://github.com/dashpay/platform/blob/v4.2-dev/packages/rs-dpp/src/state_transition/state_transitions/contract/data_contract_update_transition/v0/mod.rs#L39-L42) | Exclude | Exclude | N/A | N/A | | [Identity create](https://github.com/dashpay/platform/blob/v4.2-dev/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_create_transition/v0/mod.rs#L49-L53) | Exclude | N/A | Exclude | [Exclude](https://github.com/dashpay/platform/blob/v4.2-dev/packages/rs-dpp/src/state_transition/state_transitions/identity/public_key_in_creation/v0/mod.rs#L56-L57) | | [Identity topup](https://github.com/dashpay/platform/blob/v4.2-dev/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_topup_transition/v0/mod.rs#L44-L45) | Exclude | N/A | N/A | N/A |