```{eval-rst} .. _protocol-ref-identity: ``` # Identity ## Identity Overview Identities are a low-level construct that provide the foundation for user-facing functionality on the platform. An identity is a public key (or set of public keys) recorded on the platform chain that can be used to prove ownership of data. Please see the [Identity DIP](https://github.com/dashpay/dips/blob/master/dip-0011.md) for additional information. Identities consist of multiple objects that are described in the following sections and listed in this summary table: | Field | Type | Description | | --------------- | -------------- | ------------------------------------------- | | [id](#identity-id) | array of bytes | The identity id (32 bytes) | | [publicKeys](#identity-publickeys) | array of keys | Public key(s) associated with the identity | | [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/v5.0.1/packages/rs-dpp/src/identity/v0/mod.rs#L41-L47) for more details. **Example Identity** ```json { "id":"6YfP6tT9AK8HPVXMK7CQrhpc8VMg7frjEnXinSPvUmZC", "publicKeys":[ { "id":0, "type":0, "purpose":0, "securityLevel":0, "data":"AkWRfl3DJiyyy6YPUDQnNx5KERRnR8CoTiFUvfdaYSDS", "readOnly":false } ], "balance":0, "revision":0 } ``` ### Identity id The identity `id` is a unique identifier created from the double sha256 hash of the [outpoint](https://docs.dash.org/en/stable/docs/core/resources/glossary.html#outpoint) funding the identity creation. Typically it is displayed using Base58 encoding. `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/v5.0.1/packages/rs-platform-value/src/types/identifier.rs). ::: See rs-dpp for examples of using [InstantSend](https://github.com/dashpay/platform/blob/v5.0.1/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/instant/instant_asset_lock_proof.rs#L142) or [ChainLocks](https://github.com/dashpay/platform/blob/v5.0.1/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/chain/chain_asset_lock_proof.rs#L47) 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/v5.0.1/packages/rs-dpp/src/identity/fields.rs#L7). ::: Each item in the `publicKeys` array consists of an object containing: | Field | Type | Description | | ------------- | -------------- | ----------- | | [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 single data contract (`$type`: `singleContract`), a document type of a data contract (`documentType`), or, **added in 5.0.0**, the members of a contract group (`contractGroup`). From protocol version 14, a contract-bound authentication key can sign only [batch](./state-transition.md#batch) transitions ([rs-drive-abci](https://github.com/dashpay/platform/blob/v5.0.1/packages/rs-drive-abci/src/execution/validation/state_transition/common/validate_state_transition_identity_signed/v1/mod.rs#L66-L75)), a batch member outside the key's bounds is rejected, and binding a key to a contract group that does not exist is rejected. See the [contract bounds implementation in rs-dpp](https://github.com/dashpay/platform/blob/v5.0.1/packages/rs-dpp/src/identity/identity_public_key/contract_bounds/mod.rs#L51-L65). | | [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](#public-key-limits) | unsigned integer (64 bits) | (Optional) **Added in 5.0.0.** Total credits that state transitions signed with this key may take from the identity | | [expiresAt](#public-key-limits) | unsigned integer (64 bits) | (Optional) **Added in 5.0.0.** Block time (in milliseconds) from which the key can no longer sign | | 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 implementations in rs-dpp ([v0](https://github.com/dashpay/platform/blob/v5.0.1/packages/rs-dpp/src/identity/identity_public_key/v0/mod.rs#L43-L61), [v1](https://github.com/dashpay/platform/blob/v5.0.1/packages/rs-dpp/src/identity/identity_public_key/v1/mod.rs#L39-L58)) for more details. #### Public Key `id` Each public key in an identity's `publicKeys` array must be assigned a unique index number (`id`). #### 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/v5.0.1/packages/rs-dpp/src/identity/identity_public_key/key_type.rs#L47-L54) include: | Type | Size (bytes) | Description | | :--: | :----------: | ----------- | | `0` | 33 | ECDSA Secp256k1 (default) | | `1` | 48 | BLS 12-381 | | `2` | 20 | ECDSA Secp256k1 Hash160 | | `3` | 20 | [BIP13](https://github.com/bitcoin/bips/blob/master/bip-0013.mediawiki) pay-to-script-hash public key | | `4` | 20 | EDDSA 25519 Hash160 | #### Public Key `data` 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/v5.0.1/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) | | :--: | -------------- | ------------------------- | | `0` | Authentication | Any security level | | `1` | Encryption | Medium | | `2` | Decryption | Medium | | `3` | Transfer | Critical | The system automatically creates the following key types for masternodes and evonodes. They cannot be created or updated manually: | Type | Description | Allowed Security Level | | :--: | -------------- | ---------------------- | | `4` | System | Critical | | `5` | Voting | High | | `6` | Owner | Critical | #### Public Key `securityLevel` The `securityLevel` field indicates how securely the key should be stored by clients. Please refer to [DIP11 - Identities](https://github.com/dashpay/dips/blob/master/dip-0011.md#keys) for additional information regarding this. | Level | Description | Security Practice | | :---: | ----------- | ----------------- | | 0 | Master | Should always require a user to authenticate when signing a transition. Can only be used to update an identity or, from protocol version 14, to sign an [identity key limits update](#identity-key-limits-update). | | 1 | Critical | Should always require a user to authenticate when signing a transition | | 2 | High | Should be available as long as the user has authenticated at least once during a session. Typically used to sign state transitions, but cannot be used for identity update transitions. | | 3 | Medium | Should not require user authentication but must require access to the client device | #### Public Key `readOnly` The `readOnly` field indicates that the public key can't be modified if it is set to `true`. The value of this field cannot be changed after adding the key. #### Public Key `disabledAt` The `disabledAt` field indicates that the key has been disabled. Its value equals the timestamp when the key was disabled. #### Public Key Limits :::{versionadded} 5.0.0 ::: A key can carry a credit budget (`totalBudget`), an expiry time (`expiresAt`), or both. A key with either limit is serialized as an [`IdentityPublicKeyV1`](https://github.com/dashpay/platform/blob/v5.0.1/packages/rs-dpp/src/identity/identity_public_key/v1/mod.rs#L17-L58) (`$formatVersion` `1`). A key without limits is still serialized as `IdentityPublicKeyV0`. Limits are allowed only on authentication keys ([purpose](#public-key-purpose) `0`) below the master [security level](#public-key-securitylevel). A limit on any other key is rejected, and so is a `totalBudget` of `0`. See the [key structure validation in rs-dpp](https://github.com/dashpay/platform/blob/v5.0.1/packages/rs-dpp/src/state_transition/state_transitions/identity/public_key_in_creation/methods/validate_identity_public_keys_structure/v1/mod.rs#L47-L68). A transition signed with a limited key is rejected once the block time reaches `expiresAt`, once the key's budget is spent, or when its spend does not fit in the key's remaining budget (metered processing fees may exceed it). Adding a key whose `expiresAt` the block time has already reached is rejected. Keys with limits, and keys bound to a contract group, are also rejected in [identity create from shielded pool](shielded-pool.md#identity-create-from-shielded-pool). A key's limits can only be loosened, using the [identity key limits update](#identity-key-limits-update) transition. ### 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. ## Identity Constants and Limits The following constants and limits apply to identities: | Constant | Value | Description | |----------|-------|-------------| | `IDENTITY_MAX_KEYS` | 15,000 | Maximum number of public keys per identity | | `MAX_CREDITS` | 9,223,372,036,854,775,807 | Maximum credit balance (i64::MAX) | | `max_public_keys_in_creation` | 6 | Maximum keys when creating an identity | | `min_identity_funding_amount` | 200,000 credits | Minimum funding for address-based identity create and top-up transitions | | `identity_create_base_cost` | 2,000,000 credits | Base fee for identity creation | | `identity_key_in_creation_cost` | 6,500,000 credits | Fee per key during creation | | `identity_topup_base_cost` | 500,000 credits | Base fee for identity top-up. The minimum top-up fee is this plus the asset lock requirement (50,000,000 credits), so 50,500,000 credits. | ### Identity Creation Cost Calculation The total cost to create an identity is: ```text Total = identity_create_base_cost + asset_lock_base_cost + (number_of_keys × identity_key_in_creation_cost) ``` **Examples:** - 1 key: 2,000,000 + 200,000,000 + 6,500,000 = **208,500,000 credits** (0.002085 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 | Operation | Required Balance (credits) | Required Balance (Dash) | |-----------|---------------------------|------------------------| | Identity create (asset lock) | 200,000,000 | 0.002 | | Identity top-up (asset lock) | 50,000,000 | 0.0005 | | Address funding | 50,000,000 | 0.0005 | :::{seealso} For all protocol constants, see [Protocol Constants](protocol-constants.md). ::: ## Identity State Transition Details The following state transitions create, fund, update, or transfer credits to or from identities. Some are documented on this page, along with the relevant [asset-lock](#asset-lock) and [signing](#identity-state-transition-signing) mechanisms; the others are documented with the feature they belong to. | Type | Name | Supported protocol versions | | --- | --- | --- | | 2 | [Identity Create](#identity-create) | ≥ 1 | | 3 | [Identity Top-Up](#identity-topup) | ≥ 1 | | 5 | [Identity Update](#identity-update) | ≥ 1 | | 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 | | 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 | | 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 | | 23 | [Identity Key Limits Update](#identity-key-limits-update) | ≥ 14 | ### Identity Create Identities are created on the platform by submitting the identity information in an identity create state transition. | Field | Type | Description | | --------------- | -------------- | ----------- | | $formatVersion | integer | The state transition format version (currently `0`) | | type | integer | State transition type (`2` for identity create) | | publicKeys | array of [keys](#identity-publickeys) | Public key(s) associated with the identity | | assetLockProof | [proof object](#asset-lock) | Asset lock proof object proving the [asset lock transaction](inv:user:std#ref-txs-assetlocktx) exists on the Core chain and is locked | | 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) | | 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/v5.0.1/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_create_transition/v0/mod.rs#L43-L54) for more details. ### Identity TopUp Identity credit balances are increased by submitting the topup information in an identity topup state transition. | Field | Type | Description | | --------------- | -------------- | ----------- | | $formatVersion | integer | The state transition format version (currently `0`) | | type | integer | State transition type (`3` for identity topup) | | assetLockProof | [proof object](#asset-lock) | Asset lock proof object proving the layer 1 locking transaction exists and is locked | | identityId | array of bytes | An [identity id](#identity-id) for the identity receiving the topup (can be any identity) (32 bytes) | | 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/v5.0.1/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_topup_transition/v0/mod.rs#L39-L46) for more details. ### Identity Update Identities are updated on the platform by submitting the identity information in an identity update state transition. This state transition requires either a set of one or more new public keys to add to the identity or a list of existing keys to disable. | Field | Type | Description | | -------------------- | -------------------- | ----------- | | $formatVersion | integer | The state transition format version (currently `0`) | | type | integer | State transition type (`5` for identity update) | | identityId | array of bytes | The [identity id](#identity-id) (32 bytes) | | revision | integer | Identity update revision | | nonce | unsigned integer (64 bits) | Identity nonce for this transition to prevent replay attacks | | addPublicKeys | array of public [keys](#identity-publickeys) | (Optional) Array of up to 6 new public keys to add to the identity. Required if adding keys. | | disablePublicKeys | array of integers | (Optional) Array of up to 10 existing identity public key ID(s) to disable for the identity. Required if disabling keys. | | userFeeIncrease | integer | Extra fee to prioritize processing if the mempool is full. Typically set to zero. | | 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/v5.0.1/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_update_transition/v0/mod.rs#L39-L68) for more details. ### Identity Key Limits Update :::{versionadded} 5.0.0 ::: An identity raises the [limits](#public-key-limits) of one of its keys by submitting an identity key limits update state transition. Each limit field carries the new absolute value. The identity revision is not changed. | Field | Type | Description | | -------------------- | -------------------- | ----------- | | $formatVersion | integer | The state transition format version (currently `0`) | | type | integer | State transition type (`23` for identity key limits update) | | identityId | array of bytes | The [identity id](#identity-id) (32 bytes) | | nonce | unsigned integer (64 bits) | Identity nonce for this transition to prevent replay attacks | | keyId | unsigned integer (32 bits) | The [id](#public-key-id) of the key whose limits are raised | | totalBudget | unsigned integer (64 bits) | (Optional) New total budget in credits. Must be greater than the key's current budget. The remaining budget grows by the same amount. Omit to leave the budget unchanged. | | expiresAt | unsigned integer (64 bits) | (Optional) New expiry in block time milliseconds. Must be later than the key's current expiry. Omit to leave the expiry unchanged. | | userFeeIncrease | integer | Extra fee to prioritize processing if the mempool is full. Typically set to zero. | | signaturePublicKeyId | integer | The ID of public key used to sign the state transition | | signature | array of bytes | Signature of state transition data (65 bytes) | The transition must be signed by a master key or by a critical key that carries no limits of its own. Signing with a limited key is rejected. The transition is also rejected if: - `keyId` is not a key of the identity - Neither `totalBudget` nor `expiresAt` is set, or `totalBudget` is `0` - The key is disabled - It sets a limit the key does not already have. A limit cannot be added to a key or removed from it. - A new value does not raise the current one - The key would still be expired after the update To give an application less, disable its key with an [identity update](#identity-update) and add a new one. See the [identity key limits update implementation in rs-dpp](https://github.com/dashpay/platform/blob/v5.0.1/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_key_limits_update_transition/v0/mod.rs#L32-L67) and the [state validation in rs-drive-abci](https://github.com/dashpay/platform/blob/v5.0.1/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_key_limits_update/state/v0/mod.rs#L113-L175) for more details. ### Identity Credit Transfer Identities can transfer credits on the platform by submitting an identity credit transfer state transition. This state transition requires specifying the sender identity, recipient identity, transfer amount, and a signature for verification. | Field | Type | Description | | -------------------- | -------------- | ----------- | | $formatVersion | integer | The state transition format version (currently `0`) | | type | integer | State transition type (`7` for identity credit transfer) | | identityId | array of bytes | The [identity id](#identity-id) of the sender (32 bytes) | | recipientId | array of bytes | The [identity id](#identity-id) of the recipient (32 bytes) | | amount | integer | The credit amount to transfer (minimum 100,000 credits) | | nonce | unsigned integer (64 bits) | Identity nonce for this transition to prevent replay attacks | | userFeeIncrease | integer | Extra fee to prioritize processing if the mempool is full. Typically set to zero. | | signaturePublicKeyId | integer | The ID of public key used to sign the state transition | | signature | array of bytes | Signature of state transition data (65 bytes) | :::{note} The `recipientId` must differ from `identityId`; transfers to the sending identity are rejected. ::: See the [identity credit transfer implementation in rs-dpp](https://github.com/dashpay/platform/blob/v5.0.1/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_transfer_transition/v0/mod.rs#L42-L53) for more details. ### Identity Credit Withdrawal Credits can be withdrawn from an identity to an external Core wallet using an identity credit withdrawal state transition. This transition allows specifying the withdrawal amount, output script, and signing details. | Field | Type | Description | | -------------------- | -------------- | ----------- | | $formatVersion | 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) | | coreFeePerByte | integer | Fee per byte for the transaction on Core (32 bits) | | pooling | integer | Pooling mode for transaction batching | | outputScript | array of bytes | (Optional) The output script for receiving the withdrawal (if not set, defaults to Core address) | | nonce | unsigned integer (64 bits) | Identity nonce for this transition to prevent replay attacks | | userFeeIncrease | integer | Extra fee to prioritize processing if the mempool is full. Typically set to zero. | | signaturePublicKeyId | integer | The ID of public key used to sign the state transition | | 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), and at most [6,765](https://github.com/dashpay/platform/blob/v5.0.1/packages/rs-platform-version/src/version/system_limits/v4.rs#L159) from protocol version 14. `outputScript`, when set, must be P2PKH or P2SH. `amount` must be within the [min and max withdrawal amount](protocol-constants.md) limits. Starting in protocol version 14, the Core transaction fee is deducted from `amount`, so `amount` must be at least the min withdrawal amount plus the Core fee (190-byte asset unlock transaction × `coreFeePerByte` × 1,000 credits; [rs-dpp](https://github.com/dashpay/platform/blob/v5.0.1/packages/rs-dpp/src/withdrawal/mod.rs#L61-L111)). ::: See the [identity credit withdrawal implementation in rs-dpp](https://github.com/dashpay/platform/blob/v5.0.1/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_withdrawal_transition/v1/mod.rs#L31-L48) 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/v5.0.1/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/mod.rs#L44-L47): 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/v5.0.1/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/instant/instant_asset_lock_proof.rs) or [ChainLocks](https://github.com/dashpay/platform/blob/v5.0.1/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/v5.0.1/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/instant/instant_asset_lock_proof.rs#L38-L45). | Field | Type | Description | | ----------- | -------------- | ----------- | | $type | string | The asset lock proof type (`"instant"` for InstantSend locks) | | instantLock | array of bytes | The InstantSend lock ([`islock`](https://docs.dash.org/en/stable/docs/core/reference/p2p-network-instantsend-messages.html#islock)) | | transaction | array of bytes | The asset lock transaction | | outputIndex | integer | Index of the transaction output to be used | #### 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/v5.0.1/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/chain/chain_asset_lock_proof.rs#L24-L29). | Field | Type | Description | | --------------------- | -------------- | ----------- | | $type | string | The asset lock proof type (`"chain"` for ChainLocks) | | coreChainLockedHeight | integer | Height of the ChainLocked Core block containing the transaction | | outPoint | string | The [outpoint](https://docs.dash.org/en/stable/docs/core/resources/glossary.html#outpoint) being used as the asset lock. JSON encodes it as `":"`. The `platform_value` representation is an object containing `txid` as 32 bytes and `vout` as an unsigned 32-bit integer. | ### Identity State Transition Signing :::{note} The identity create and topup state transition signatures are unique in that they must be signed by the private key used in the layer 1 locking transaction. All other state transitions will be signed by a private key of the identity submitting them. ::: The process to sign an identity create state transition consists of the following steps: 1. Create a canonical, signable version of the state transition encoded with [Bincode](https://github.com/bincode-org/bincode). The signable state transition excludes the following fields: - `identityId` - `signature` for all [public keys](#identity-publickeys) - `signature` for the overall state transition 2. Calculate the double SHA-256 hash of the encoded signable state transition 3. Sign the hash from the previous step using the private key associated with the asset lock transaction, then add the result to the state transition's `signature` field 4. For each public key of type `0` or `1` being added to the identity, sign the hash from step 2 using the respective private key and add the result to the public key's `signature` field. Keys of type `2`, `3`, or `4` must have an empty `signature`. 5. Use Bincode to re-encode the state transition with all signatures and the identity id included