Document#
Document Overview#
Once a data contract has been created, data can be stored by submitting documents that comply with the document structure specified in the contract. Each document consists of one or more fields and the indices necessary to support querying. Documents are created, replaced, deleted, transferred, purchased, or have their price updated by submitting them to the platform in a batch state transition.
Document State Transition Details#
All document transitions include the document base transition fields. Some document transitions (e.g., document create) require additional fields to provide their functionality.
Document Base Transition#
The following fields are included in all document transitions. Note that $action is present in the JSON wire format as a type discriminator (see Document Transition Action) but is not a stored field in the base transition structure — it is derived from the transition variant type.
Field |
Type |
Size |
Description |
|---|---|---|---|
array |
32 bytes |
The document ID |
|
$identityContractNonce |
unsigned integer |
64 bits |
Identity contract nonce |
$type |
string |
1-64 characters |
Name of a document type found in the data contract associated with the |
$dataContractId |
array |
32 bytes |
Data contract ID generated from the data contract’s |
object |
Varies |
(Optional, V1+) Token-based fee payment information for this transition |
Each document transition must comply with the document base transition defined in rs-dpp.
Document id#
The document $id is created by double sha256 hashing the document’s dataContractId, ownerId, type, and entropy as shown in rs-dpp.
// From the Rust reference implementation (rs-dpp)
// generate_document_id.rs
pub fn generate_document_id_v0(
contract_id: &Identifier,
owner_id: &Identifier,
document_type_name: &str,
entropy: &[u8],
) -> Identifier {
let mut buf: Vec<u8> = vec![];
buf.extend_from_slice(&contract_id.to_buffer());
buf.extend_from_slice(&owner_id.to_buffer());
buf.extend_from_slice(document_type_name.as_bytes());
buf.extend_from_slice(entropy);
Identifier::from_bytes(&hash_double_to_vec(&buf)).unwrap()
}
Token Payment Info#
When a document type requires token payment (configured via tokenCost in the data contract), the $tokenPaymentInfo object specifies which token to use and the cost limits the client is willing to accept. The object is defined in rs-dpp.
Field |
Type |
Size |
Description |
|---|---|---|---|
paymentTokenContractId |
array |
32 bytes |
(Optional) Identifier of the contract containing the payment token. Defaults to the current contract if omitted. |
tokenContractPosition |
unsigned integer |
16 bits |
Position of the token within the contract to use for payment |
minimumTokenCost |
unsigned integer |
64 bits |
(Optional) Minimum acceptable token cost. Not typically set by clients. |
maximumTokenCost |
unsigned integer |
64 bits |
(Optional) Maximum token cost the client is willing to pay. Recommended when the contract allows prices to be changed, to protect against unexpected cost increases. |
gasFeesPaidBy |
integer |
8 bits |
Who pays the gas fees for the operation: |
Note
The gasFeesPaidBy value must match what the data contract’s tokenCost configuration allows for the operation type.
Entropy Generation#
Dash Platform uses the following entropy generator found in rs-dpp:
// From the Rust reference implementation (rs-dpp)
// entropy_generator.rs
fn generate(&self) -> anyhow::Result<[u8; 32]> {
let mut buffer = [0u8; 32];
getrandom::getrandom(&mut buffer)
.map_err(|e| anyhow::anyhow!(format!("generating entropy failed: {}", e)))?;
Ok(buffer)
}
Document Transition Action#
Document transition actions indicate what operation platform should perform with the provided transition data. Documents provide CRUD functionality, ownership transfer, and NFT features as defined in rs-dpp.
Action |
Name |
Description |
|---|---|---|
0 |
Create a new document with the provided data |
|
1 |
Replace an existing document with the provided data |
|
2 |
Delete the referenced document |
|
3 |
Transfer the referenced document to a new owner |
|
4 |
Purchase the referenced document |
|
5 |
Update the price for the document |
|
6 |
IgnoreWhileBumpingRevision |
Internal action type used to bypass revision bump |
Document Create Transition#
The document create transition extends the base transition to include the following additional fields:
Field |
Type |
Size |
Description |
|---|---|---|---|
$entropy |
array |
32 bytes |
Entropy used in creating the document ID. Generated as shown here. |
data |
Varies |
Document data being submitted. |
|
$prefundedVotingBalance |
Varies |
(Optional) Prefunded amount of credits reserved for unique index conflict resolution voting (e.g., premium DPNS name). |
Each document create transition must comply with the structure defined in rs-dpp (in addition to the document base transition that is required for all document transitions).
Note
The document create transition data field must include all required document properties specified in the data contract.
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:
{
"$action": 0,
"$dataContractId": "5wpZAEWndYcTeuwZpkmSa8s49cHXU5q2DhdibesxFSu8",
"$id": "6oCKUeLVgjr7VZCyn1LdGbrepqKLmoabaff5WQqyTKYP",
"$type": "note",
"$identityContractNonce": 1,
"$entropy": "yfo6LnZfJ5koT2YUwtd8PdJa8SXzfQMVDz",
"message": "Tutorial Test @ Mon, 27 Apr 2020 20:23:35 GMT"
}
Field |
Required By |
|---|---|
$dataContractId |
Document base transition |
$id |
Document base transition |
$type |
Document base transition |
$identityContractNonce |
Document base transition |
$entropy |
Document create transition |
message |
Data Contract (the |
Document Replace Transition#
The document replace transition extends the base transition to include the following additional fields:
Field |
Type |
Size |
Description |
|---|---|---|---|
$revision |
unsigned integer |
64 bits |
Document revision (=> 1) |
data |
Varies |
Document data being updated |
Each document replace transition must comply with the structure defined in rs-dpp (in addition to the document base transition that is required for all document transitions).
Note
The document replace transition data field must include all required document properties specified in the data contract.
The following example document replace transition and subsequent table demonstrate how the document transition base, document replace transition, and data contract document definitions are assembled into a complete transition for inclusion in a state transition:
{
"$action": 1,
"$dataContractId": "5wpZAEWndYcTeuwZpkmSa8s49cHXU5q2DhdibesxFSu8",
"$id": "6oCKUeLVgjr7VZCyn1LdGbrepqKLmoabaff5WQqyTKYP",
"$type": "note",
"$identityContractNonce": 1,
"$revision": 1,
"message": "Tutorial Test @ Mon, 27 Apr 2020 20:23:35 GMT"
}
Field |
Required By |
|---|---|
$dataContractId |
Document base transition |
$id |
Document base transition |
$type |
Document base transition |
$identityContractNonce |
Document base transition |
$revision |
Document revision |
message |
Data Contract (the |
Document Delete Transition#
The document delete transition only requires the fields found in the base document transition. See the implementation in rs-dpp for details.
Document Transfer Transition#
The document transfer transition allows a document owner to transfer document ownership directly to another identity without making it available for purchase. This transition extends the base transition to include the following additional fields:
Field |
Type |
Size |
Description |
|---|---|---|---|
$revision |
unsigned integer |
64 bits |
Document revision (=> 1) |
recipientOwnerId |
array of bytes |
32 bytes |
Identifier of the recipient (new owner). See the NFT page for more details. |
Each document transfer transition must comply with the structure defined in rs-dpp (in addition to the document base transition that is required for all document transitions).
Document Purchase Transition#
The document purchase transition allows an identity to purchase a document previously made available for sale by the current document owner. This transition extends the document base transition to include the following additional fields:
Field |
Type |
Size |
Description |
|---|---|---|---|
$revision |
unsigned integer |
64 bits |
Document revision (=> 1) |
price |
unsigned integer |
64 bits |
Number of credits being offered for the purchase. See the NFT page for more details. |
Each document purchase transition must comply with the structure defined in rs-dpp (in addition to the document base transition that is required for all document transitions).
Document Update Price Transition#
The document update price transition allows a document owner to set or update the minimum price they will accept in exchange for transferring document ownership to another party. This transition extends the document base transition to include the following additional fields:
Field |
Type |
Size |
Description |
|---|---|---|---|
$revision |
unsigned integer |
64 bits |
Document revision (=> 1) |
$price |
unsigned integer |
64 bits |
Updated price for the document. Can only be set by the current document owner. See the NFT page for more details. |
Each document update price transition must comply with the structure defined in rs-dpp (in addition to the document base transition that is required for all document transitions).
Document Object#
The document object represents the data provided by the platform in response to a query. Responses consist of an array of these objects containing the following fields as defined in the Rust reference client (rs-dpp):
Property |
Type |
Required |
Description |
|---|---|---|---|
$id |
array |
Yes |
The document ID (32 bytes) |
$type |
string |
Yes |
Document type defined in the referenced contract (1-64 characters) |
$revision |
unsigned integer (64 bits) |
No |
Document revision (=>1) if the document is mutable |
$dataContractId |
array |
Yes |
Data contract ID generated from the data contract’s |
$ownerId |
array |
Yes |
Identity of the user submitting the document (32 bytes) |
$createdAt |
unsigned integer (64 bits) |
No |
Time (in milliseconds) at document creation, if required by the document type schema |
$updatedAt |
unsigned integer (64 bits) |
No |
Last document update time in milliseconds, if required by the document type schema |
$transferredAt |
unsigned integer (64 bits) |
No |
Last transferred time in milliseconds, if required by the document type schema |
$createdAt |
unsigned integer (64 bits) |
No |
Block height at document creation, if required by the schema |
$updatedAt |
unsigned integer (64 bits) |
No |
Block height at the document’s last update, if required by the schema |
$transferredAt |
unsigned integer (64 bits) |
No |
Block height when document was last transferred, if required by the schema |
$createdAt |
unsigned integer (32 bits) |
No |
Core block height at document creation, if required by the schema |
$updatedAt |
unsigned integer (32 bits) |
No |
Core block height at the document’s last update, if required by the schema |
$transferredAt |
unsigned integer (32 bits) |
No |
Core block height when document was last transferred, if required by the schema |
$creatorId |
array |
No |
Identity of the document creator (32 bytes), if required by the document type schema |
Example Document Object#
{
"$id": "4mWnFcDDzCpeLExJqE8v7pfN4EERC8NE2xn4hw3VKriU",
"$type": "note",
"$dataContractId": "63au7XVDt8aHtPrsYKoHx2bnRTSenwH62pDN1BQ5n5m9",
"$ownerId": "7TkaE5uhG3T9AhyEkAvYCqZvRH4pyBibhjuSYPReNfME",
"$revision": 1,
"message": "Tutorial Test @ Mon, 26 Oct 2020 15:54:35 GMT",
"$createdAt": 1603727675072,
"$updatedAt": 1603727675072
}