From ec3d87e8c8dca912945366521ae445928b34e460 Mon Sep 17 00:00:00 2001 From: pshenmic Date: Sun, 20 Oct 2024 08:02:17 +0700 Subject: [PATCH] Hardcode DPNS data contract in the code --- src/commands/register_dpns_name.rs | 8 +- src/constants.rs | 181 +++++++++++++++++++++++++++++ src/main.rs | 1 + 3 files changed, 185 insertions(+), 5 deletions(-) create mode 100644 src/constants.rs diff --git a/src/commands/register_dpns_name.rs b/src/commands/register_dpns_name.rs index bf5e1f8..69d419f 100644 --- a/src/commands/register_dpns_name.rs +++ b/src/commands/register_dpns_name.rs @@ -7,7 +7,7 @@ use dpp::dashcore::hashes::Hash; use dpp::dashcore::{Network}; use dpp::dashcore::secp256k1::Secp256k1; use dpp::data_contract::accessors::v0::DataContractV0Getters; -use dpp::data_contract::{DataContract, JsonValue}; +use dpp::data_contract::{DataContract}; use dpp::data_contract::conversion::value::v0::DataContractValueConversionMethodsV0; use dpp::identifier::Identifier; use dpp::identity::accessors::IdentityGettersV0; @@ -35,6 +35,7 @@ use crate::factories::Factories; use crate::grpc::PlatformGRPCClient; use crate::utils::{MyDefaultEntropyGenerator, Utils}; use regex::Regex; +use crate::constants::Constants; use crate::MockBLS; /// Register an Identity Name in the Dash Platform DPNS system. @@ -91,10 +92,7 @@ impl RegisterDPNSNameCommand { let public_key = private_key.public_key(&secp); let identifier = Identifier::from_string(&self.identity, Base58).unwrap(); - let dpns_data_contract_data = fs::read_to_string("dpns_contract.json").expect("Unable to read file"); - let json_value = JsonValue::from_str(&dpns_data_contract_data).expect("Could not decode DPNS data contract json"); - let raw_data_contract: Value = Value::from(json_value); - let dpns_contract = DataContract::from_value(raw_data_contract, true, PlatformVersion::latest()).unwrap(); + let dpns_contract = DataContract::from_value(Constants::dpns_data_contract_value(), true, PlatformVersion::latest()).unwrap(); let platform_grpc_client = PlatformGRPCClient::new(&self.dapi_url); diff --git a/src/constants.rs b/src/constants.rs new file mode 100644 index 0000000..d9d3deb --- /dev/null +++ b/src/constants.rs @@ -0,0 +1,181 @@ +use dpp::platform_value::{platform_value, Value}; + +pub struct Constants; + +impl Constants { + pub fn dpns_data_contract_value() -> Value { + platform_value!({ + "$format_version": "0", + "id": "GWRSAVFMjXx8HpQFaNJMqBV7MBgMK4br5UESsB4S31Ec", + "ownerId": "11111111111111111111111111111111", + "version": 1, + "documentSchemas": { + "domain": { + "documentsMutable": false, + "canBeDeleted": true, + "transferable": 1, + "tradeMode": 1, + "type": "object", + "indices": [ + { + "name": "parentNameAndLabel", + "properties": [ + { + "normalizedParentDomainName": "asc" + }, + { + "normalizedLabel": "asc" + } + ], + "unique": true, + "contested": { + "fieldMatches": [ + { + "field": "normalizedLabel", + "regexPattern": "^[a-zA-Z01-]{3,19}$" + } + ], + "resolution": 0, + "description": "If the normalized label part of this index is less than 20 characters (all alphabet a-z, A-Z, 0, 1, and -) then a masternode vote contest takes place to give out the name" + } + }, + { + "name": "identityId", + "nullSearchable": false, + "properties": [ + { + "records.identity": "asc" + } + ] + } + ], + "properties": { + "label": { + "type": "string", + "pattern": "^[a-zA-Z0-9][a-zA-Z0-9-]{0,61}[a-zA-Z0-9]$", + "minLength": 3, + "maxLength": 63, + "position": 0, + "description": "Domain label. e.g. 'Bob'." + }, + "normalizedLabel": { + "type": "string", + "pattern": "^[a-hj-km-np-z0-9][a-hj-km-np-z0-9-]{0,61}[a-hj-km-np-z0-9]$", + "maxLength": 63, + "position": 1, + "description": "Domain label converted to lowercase for case-insensitive uniqueness validation. \"o\", \"i\" and \"l\" replaced with \"0\" and \"1\" to mitigate homograph attack. e.g. 'b0b'", + "$comment": "Must be equal to the label in lowercase. \"o\", \"i\" and \"l\" must be replaced with \"0\" and \"1\"." + }, + "parentDomainName": { + "type": "string", + "pattern": "^$|^[a-zA-Z0-9][a-zA-Z0-9-]{0,61}[a-zA-Z0-9]$", + "minLength": 0, + "maxLength": 63, + "position": 2, + "description": "A full parent domain name. e.g. 'dash'." + }, + "normalizedParentDomainName": { + "type": "string", + "pattern": "^$|^[a-hj-km-np-z0-9][a-hj-km-np-z0-9-\\.]{0,61}[a-hj-km-np-z0-9]$", + "minLength": 0, + "maxLength": 63, + "position": 3, + "description": "A parent domain name in lowercase for case-insensitive uniqueness validation. \"o\", \"i\" and \"l\" replaced with \"0\" and \"1\" to mitigate homograph attack. e.g. 'dash'", + "$comment": "Must either be equal to an existing domain or empty to create a top level domain. \"o\", \"i\" and \"l\" must be replaced with \"0\" and \"1\". Only the data contract owner can create top level domains." + }, + "preorderSalt": { + "type": "array", + "byteArray": true, + "minItems": 32, + "maxItems": 32, + "position": 4, + "description": "Salt used in the preorder document" + }, + "records": { + "type": "object", + "properties": { + "identity": { + "type": "array", + "byteArray": true, + "minItems": 32, + "maxItems": 32, + "position": 1, + "contentMediaType": "application/x.dash.dpp.identifier", + "description": "Identifier name record that refers to an Identity" + } + }, + "minProperties": 1, + "position": 5, + "additionalProperties": false + }, + "subdomainRules": { + "type": "object", + "properties": { + "allowSubdomains": { + "type": "boolean", + "description": "This option defines who can create subdomains: true - anyone; false - only the domain owner", + "$comment": "Only the domain owner is allowed to create subdomains for non top-level domains", + "position": 0 + } + }, + "position": 6, + "description": "Subdomain rules allow domain owners to define rules for subdomains", + "additionalProperties": false, + "required": [ + "allowSubdomains" + ] + } + }, + "required": [ + "$createdAt", + "$updatedAt", + "$transferredAt", + "label", + "normalizedLabel", + "normalizedParentDomainName", + "preorderSalt", + "records", + "subdomainRules" + ], + "transient": [ + "preorderSalt" + ], + "additionalProperties": false, + "$comment": "In order to register a domain you need to create a preorder. The preorder step is needed to prevent man-in-the-middle attacks. normalizedLabel + '.' + normalizedParentDomain must not be longer than 253 chars length as defined by RFC 1035. Domain documents are immutable: modification and deletion are restricted" + }, + "preorder": { + "documentsMutable": false, + "canBeDeleted": true, + "type": "object", + "indices": [ + { + "name": "saltedHash", + "properties": [ + { + "saltedDomainHash": "asc" + } + ], + "unique": true + } + ], + "properties": { + "saltedDomainHash": { + "type": "array", + "byteArray": true, + "minItems": 32, + "maxItems": 32, + "position": 0, + "description": "Double sha-256 of the concatenation of a 32 byte random salt and a normalized domain name" + } + }, + "required": [ + "saltedDomainHash" + ], + "additionalProperties": false, + "$comment": "Preorder documents are immutable: modification and deletion are restricted" + } + } + } + ) + } +} diff --git a/src/main.rs b/src/main.rs index 6a4ec0d..bcf0847 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,6 +5,7 @@ mod factories; pub(crate) mod utils; mod errors; mod logger; +mod constants; use clap::{Parser, Subcommand}; use dpp::{BlsModule, ProtocolError, PublicKeyValidationError};