```{eval-rst} .. _reference-platform-proofs: ``` # Platform Proofs Platform proofs are an important part of Dash Platform's trust model. When a response is requested with `prove: true`, Platform can return proof data that allows clients to verify that the response matches consensus state. Since data verification is a critical aspect of Dash Platform, all [Platform endpoints](../reference/dapi-endpoints-platform-endpoints.md) can provide an optional proof that the response is correct. Set the optional `prove` parameter (`"prove": true`) in the request to receive a proof that contains the requested data. ## Proof Structure Each proof consists of four parts: | Field | Type | Description | |-|-|-| | rootTreeProof | Bytes (base64) | Merkle path to the `storeTreeProof` | | [storeTreeProof](#store-tree-proof) | Object | Object containing data and proofs from one or more store trees. Currently there are 5 types of trees: identities, public key hash to identity IDs, data contracts, documents, and state transitions. The merk tree proofs contain the store root hash, the merkle path, and the requested data | | signatureLlmqHash | Bytes (base64) | Hash of the LLMQ that created the `signature` | | signature | Bytes (base64) | Signature of the merkle root of the `rootTreeProof` | ```json { "proof": { "rootTreeProof": "v+99FytmaUPDP65HthQllBL1JDXt2Zu/kzFEQRw66rT6QF8LYwKmAP6fEaXLaSVPe/OHfTDEG2+KoLxjyirQIDmDy4lNl4yhJE5stQZGO2G/74H4MxN/a/luSWkqE1vF", "storeTreeProofs": { "identitiesProof": "AeFWk/kp1HXlJMzA4Wwov+NifjrocHebDU8863BDtp4aAlHeCG7lcVi52OSo+U5LlykSjARXJ5Rv6hE+mui+RnUFEAGJ24nuRAkAZMjcRp1sbzLPwYxxagTD12YTLksNN+y1cAKxpoxQdHpC/RQN7cq7fE/z6+0ccpoVQbobRPGtfCSj4hABjDZM5byc2NbfTNb7NGWDKm0bAoZjaAHx+C7Gn2cKmfsCIyWhRVW4QDdnoxTDvJuHCKJeK8dWzsrfVuUYTejcw6MQAX4HE7Y1WuXPPAG6uU9vewbilQnhjLzSTYNVLsdkxmLfAmwhTWaLg5A+tuxnzvdPhNU+bmbyMHr4PIL8Z+ScbyikEAFtCRA34Yl9tuEzqAF1EdiY0U9/jNoyEpU2vkPLO7xUYAJEmc3z/snpNWPXQdMrrAAHqWNhwddPRSMrF0epC75qThADIHwTzudaE/98V8XvldeYDIpe0yZOW3s6iK0jdqsoOJz3AIABAAAApGJpZFggfBPO51oT/3xXxe+V15gMil7TJk5bezqIrSN2qyg4nPdnYmFsYW5jZRoAp8O4aHJldmlzaW9uAGpwdWJsaWNLZXlzgaNiaWQAZGRhdGFYIQOF51gOnYk5T+0EdR4DSKUkDo5TmEDMoMxdxOy7FnqKjmR0eXBlABEREQL0H2yuZyiMzKzHmrXCwp/W7DuDkZYlEx7JE5xlYGhJxhABJt9KcGPXHnE7hzz3aQ9PpYDhvILZCDUOu5BBwV66RPYRERECyX/3Cih/TZdB9cVOX8Xmo2UEPNvt9iOufQ4oCmoytwsQAU14wPdQ7t7FfsfXx9fGnwbZk8h1uxoWd0MroZRO0YVXEQ==", "publicKeyHashesToIdentityIdsProof": "Afe33zbtlgXiPzJ1+zSjjVttIBmiKHy1iEc7uOKqxVUGAjs/C8gAlTwbVhnRBqbhGFkz0Kg/0Cr8mAV41WXxocBpEAGVsw8werVp7Cka+OSMj3GgkX2Da0FMMGGIJx4aZxPwPhE=" }, "signatureLlmqHash": "AAACBMSv9TakRGNdP+yvxw/+VCgIbALhn314jLOpgcY=", "signature": "Fhl8Md9MDlB0Tlekgjoj+Qe5PdKeUDyL6svVmcP9ttRu1UB7oeAGaSMAyqJI+k/HA/jAfPFb9+q9gepdZDhj8zHrl5BRSaAiBPEtM6CTQ+eCWUvqOlDENVQfubrXLLdk" }, "metadata": { "height": "7986", "coreChainLockedHeight": 57585 } } ``` ### Root tree proof > 📘 > > Details regarding the root tree proofs and their verification will be provided in a future update to this page. ### Store tree proof Store tree proofs are based on a modified version of [Merk](https://github.com/nomic-io/merk/). Some details from the Merk documentation are included below. Additional details are available in the [Algorithms document](https://github.com/nomic-io/merk/blob/develop/docs/algorithms.md) on the Merk repository. Dash Platform 0.21.0 introduced updates to support returning multiple store tree proofs. Each response that requests proofs will receive one or more of the following: - `identitiesProof` - `publicKeyHashesToIdentityIdsProof` - `dataContractsProof` - `documentsProof` - `stateTransitionProof` :::{note} Some proof payloads include a 4-byte protocol version prefix that is not part of the CBOR-encoded value. When decoding those values, strip the version prefix before CBOR decoding. ::: #### Structure Merk proofs are a list of stack-based operators and node data, with 3 possible operators: `Push(node)`, `Parent`, and `Child`. A stream of these operators can be processed by a verifier in order to reconstruct a sparse representation of part of the tree, in a way where the data can be verified against a known root hash. The value of `node` in a `Push` operation can be one of three types: - `Hash(hash)` - The hash of a node - `KVHash(hash)` - The key/value hash of a node - `KV(key, value)` - The key and value of a node #### Binary Format We can efficiently encode these proofs by encoding each operator as follows: | Operator | Op. Value | Size | Description | |-|:-:|-|-| | Push(Hash(hash)) | `0x01` | 32 bytes | Node hash | | Push(KVHash(hash)) | `0x02` | 32 bytes | Node key/value hash | | Push(KV(key, value)) | `0x03` | < 1-byte key length >
< n-byte key >
< 2-byte value length >
< n-byte value > | Node key/value | This results in a compact binary representation, with a very small space overhead (roughly 2 bytes per node in the proof (1 byte for the Push operator type flag, and 1 byte for a Parent or Child operator), plus 3 bytes per key/value pair (1 byte for the key length, and 2 bytes for the value length)). ## Retrieving response data from proofs The function below shows a simple example of parsing a response's `storeTreeProof` to retrieve the data asked for by the request: ```javascript // Get data from base64 encoded store tree proof function getStoreProofData(storeProof) { const values = []; const buf = Buffer.from(storeProof, 'base64'); let x = 0; let valueFound = false; while (x < buf.length) { const type = buf.readUInt8(x); x += 1; switch (type) { case 0x01: { // Hash x += hashLength; break; } case 0x02: { // Key/value hash x += hashLength; break; } case 0x03: { // Key / Value const keySize = buf.readUInt8(x); x += (1 + keySize); const valueSize = buf.readUInt16BE(x); x += 2; // Value // Start at x+4 because the first 4 bytes are the protocol version // and are not part of the CBOR value const value = buf.toString('hex', x + 4, x + valueSize); x += valueSize; const map = cbor.decode(value); valueFound = true; values.push(map); break; } case 0x10: // Parent break; case 0x11: // Child break; default: console.log(`Unknown type: ${type.toString(16)}`); break; } } console.log(`Value found: ${valueFound}`); return values; } ```