dpp/data_contract/conversion/json/
mod.rs

1mod v0;
2pub use v0::*;
3
4use crate::data_contract::v0::DataContractV0;
5use crate::data_contract::{DataContract, DataContractV1};
6use crate::version::PlatformVersion;
7use crate::ProtocolError;
8use serde_json::Value as JsonValue;
9
10impl DataContractJsonConversionMethodsV0 for DataContract {
11    fn from_json(
12        json_value: JsonValue,
13        full_validation: bool,
14        platform_version: &PlatformVersion,
15    ) -> Result<Self, ProtocolError>
16    where
17        Self: Sized,
18    {
19        match platform_version
20            .dpp
21            .contract_versions
22            .contract_structure_version
23        {
24            0 => Ok(
25                DataContractV0::from_json(json_value, full_validation, platform_version)?.into(),
26            ),
27            1 => Ok(
28                DataContractV1::from_json(json_value, full_validation, platform_version)?.into(),
29            ),
30            version => Err(ProtocolError::UnknownVersionMismatch {
31                method: "DataContract::from_json".to_string(),
32                known_versions: vec![0, 1],
33                received: version,
34            }),
35        }
36    }
37
38    fn to_json(&self, platform_version: &PlatformVersion) -> Result<JsonValue, ProtocolError> {
39        match self {
40            DataContract::V0(v0) => v0.to_json(platform_version),
41            DataContract::V1(v1) => v1.to_json(platform_version),
42        }
43    }
44
45    fn to_validating_json(
46        &self,
47        platform_version: &PlatformVersion,
48    ) -> Result<JsonValue, ProtocolError> {
49        match self {
50            DataContract::V0(v0) => v0.to_validating_json(platform_version),
51            DataContract::V1(v1) => v1.to_validating_json(platform_version),
52        }
53    }
54}
55
56#[cfg(test)]
57mod tests {
58    use crate::data_contract::conversion::json::DataContractJsonConversionMethodsV0;
59    use crate::prelude::DataContract;
60    use crate::version::PlatformVersion;
61    use serde_json::json;
62
63    #[test]
64    fn from_json_accepts_stepwise_with_string_keys() {
65        let platform_version = PlatformVersion::latest();
66
67        let owner = "HtQNfXBZJu3WnvjvCFJKgbvfgWYJxWxaFWy23TKoFjg9";
68        let id = "BmKTJeLL3GfH8FxEx7SUbTog4eAKj8vJRDi97gYkxB9p";
69
70        let contract = json!({
71            "$formatVersion": "1",
72            "id": id,
73            "ownerId": owner,
74            "version": 1,
75            "config": {
76                "$formatVersion": "0",
77                "canBeDeleted": false,
78                "readonly": false,
79                "keepsHistory": false,
80                "documentsKeepHistoryContractDefault": false,
81                "documentsMutableContractDefault": true,
82                "documentsCanBeDeletedContractDefault": false,
83                "requiresIdentityEncryptionBoundedKey": null,
84                "requiresIdentityDecryptionBoundedKey": null
85            },
86            "documentSchemas": {},
87            "tokens": {
88                "0": {
89                    "$formatVersion": "0",
90                    "conventions": { "$formatVersion": "0", "decimals": 2, "localizations": {} },
91                    "distributionRules": {
92                        "$formatVersion": "0",
93                        "perpetualDistribution": {
94                            "$formatVersion": "0",
95                            "distributionType": {
96                                "BlockBasedDistribution": {
97                                    "interval": 10,
98                                    "function": {
99                                        "Stepwise": { "0": 100, "10": 50 }
100                                    }
101                                }
102                            },
103                            "distributionRecipient": "ContractOwner"
104                        },
105                        "perpetualDistributionRules": {
106                            "$formatVersion": "0",
107                            "authorizedToMakeChange": "ContractOwner",
108                            "adminActionTakers": "ContractOwner",
109                            "changingAuthorizedActionTakersToNoOneAllowed": false,
110                            "changingAdminActionTakersToNoOneAllowed": false,
111                            "selfChangingAdminActionTakersAllowed": false
112                        },
113                        "preProgrammedDistribution": null,
114                        "preProgrammedDistributionRules": {
115                            "$formatVersion": "0",
116                            "authorizedToMakeChange": "NoOne",
117                            "adminActionTakers": "NoOne",
118                            "changingAuthorizedActionTakersToNoOneAllowed": false,
119                            "changingAdminActionTakersToNoOneAllowed": false,
120                            "selfChangingAdminActionTakersAllowed": false
121                        },
122                        "newTokensDestinationIdentity": null,
123                        "newTokensDestinationIdentityRules": {
124                            "$formatVersion": "0",
125                            "authorizedToMakeChange": "ContractOwner",
126                            "adminActionTakers": "ContractOwner",
127                            "changingAuthorizedActionTakersToNoOneAllowed": false,
128                            "changingAdminActionTakersToNoOneAllowed": false,
129                            "selfChangingAdminActionTakersAllowed": false
130                        },
131                        "mintingAllowChoosingDestination": false,
132                        "mintingAllowChoosingDestinationRules": {
133                            "$formatVersion": "0",
134                            "authorizedToMakeChange": "ContractOwner",
135                            "adminActionTakers": "ContractOwner",
136                            "changingAuthorizedActionTakersToNoOneAllowed": false,
137                            "changingAdminActionTakersToNoOneAllowed": false,
138                            "selfChangingAdminActionTakersAllowed": false
139                        },
140                        "changeDirectPurchasePricingRules": {
141                            "$formatVersion": "0",
142                            "authorizedToMakeChange": "NoOne",
143                            "adminActionTakers": "NoOne",
144                            "changingAuthorizedActionTakersToNoOneAllowed": false,
145                            "changingAdminActionTakersToNoOneAllowed": false,
146                            "selfChangingAdminActionTakersAllowed": false
147                        }
148                    },
149                    "marketplaceRules": {"$formatVersion": "0", "tradeMode": "NotTradeable"},
150                    "manualMintingRules": {
151                        "$formatVersion": "0",
152                        "authorizedToMakeChange": "ContractOwner",
153                        "adminActionTakers": "ContractOwner",
154                        "changingAuthorizedActionTakersToNoOneAllowed": false,
155                        "changingAdminActionTakersToNoOneAllowed": false,
156                        "selfChangingAdminActionTakersAllowed": false
157                    },
158                    "manualBurningRules": {
159                        "$formatVersion": "0",
160                        "authorizedToMakeChange": "ContractOwner",
161                        "adminActionTakers": "ContractOwner",
162                        "changingAuthorizedActionTakersToNoOneAllowed": false,
163                        "changingAdminActionTakersToNoOneAllowed": false,
164                        "selfChangingAdminActionTakersAllowed": false
165                    },
166                    "freezeRules": {
167                        "$formatVersion": "0",
168                        "authorizedToMakeChange": "ContractOwner",
169                        "adminActionTakers": "ContractOwner",
170                        "changingAuthorizedActionTakersToNoOneAllowed": false,
171                        "changingAdminActionTakersToNoOneAllowed": false,
172                        "selfChangingAdminActionTakersAllowed": false
173                    },
174                    "unfreezeRules": {
175                        "$formatVersion": "0",
176                        "authorizedToMakeChange": "ContractOwner",
177                        "adminActionTakers": "ContractOwner",
178                        "changingAuthorizedActionTakersToNoOneAllowed": false,
179                        "changingAdminActionTakersToNoOneAllowed": false,
180                        "selfChangingAdminActionTakersAllowed": false
181                    },
182                    "destroyFrozenFundsRules": {
183                        "$formatVersion": "0",
184                        "authorizedToMakeChange": "ContractOwner",
185                        "adminActionTakers": "ContractOwner",
186                        "changingAuthorizedActionTakersToNoOneAllowed": false,
187                        "changingAdminActionTakersToNoOneAllowed": false,
188                        "selfChangingAdminActionTakersAllowed": false
189                    },
190                    "emergencyActionRules": {
191                        "$formatVersion": "0",
192                        "authorizedToMakeChange": "ContractOwner",
193                        "adminActionTakers": "ContractOwner",
194                        "changingAuthorizedActionTakersToNoOneAllowed": false,
195                        "changingAdminActionTakersToNoOneAllowed": false,
196                        "selfChangingAdminActionTakersAllowed": false
197                    },
198                    "directPurchaseRules": {
199                        "$formatVersion": "0",
200                        "authorizedToMakeChange": "NoOne",
201                        "adminActionTakers": "NoOne",
202                        "changingAuthorizedActionTakersToNoOneAllowed": false,
203                        "changingAdminActionTakersToNoOneAllowed": false,
204                        "selfChangingAdminActionTakersAllowed": false
205                    },
206                    "mainControlGroup": null,
207                    "mainControlGroupCanBeModified": "NoOne"
208                }
209            }
210        });
211
212        let result = DataContract::from_json(contract, true, &platform_version);
213        assert!(
214            result.is_ok(),
215            "Stepwise with string keys should be accepted by from_json"
216        );
217    }
218
219    #[test]
220    fn from_json_accepts_preprogrammed_with_string_timestamp_keys() {
221        let platform_version = PlatformVersion::latest();
222
223        let owner = "HtQNfXBZJu3WnvjvCFJKgbvfgWYJxWxaFWy23TKoFjg9";
224        let id = "BmKTJeLL3GfH8FxEx7SUbTog4eAKj8vJRDi97gYkxB9p";
225
226        let contract = json!({
227            "$formatVersion": "1",
228            "id": id,
229            "ownerId": owner,
230            "version": 1,
231            "config": {
232                "$formatVersion": "0",
233                "canBeDeleted": false,
234                "readonly": false,
235                "keepsHistory": false,
236                "documentsKeepHistoryContractDefault": false,
237                "documentsMutableContractDefault": true,
238                "documentsCanBeDeletedContractDefault": false,
239                "requiresIdentityEncryptionBoundedKey": null,
240                "requiresIdentityDecryptionBoundedKey": null
241            },
242            "documentSchemas": {},
243            "tokens": {
244                "0": {
245                    "$formatVersion": "0",
246                    "conventions": { "$formatVersion": "0", "decimals": 2, "localizations": {} },
247                    "distributionRules": {
248                        "$formatVersion": "0",
249                        "perpetualDistribution": null,
250                        "perpetualDistributionRules": {
251                            "$formatVersion": "0",
252                            "authorizedToMakeChange": "NoOne",
253                            "adminActionTakers": "NoOne",
254                            "changingAuthorizedActionTakersToNoOneAllowed": false,
255                            "changingAdminActionTakersToNoOneAllowed": false,
256                            "selfChangingAdminActionTakersAllowed": false
257                        },
258                        "preProgrammedDistribution": {
259                            "$formatVersion": "0",
260                            "distributions": {
261                                "1735689600000": {
262                                    "HtQNfXBZJu3WnvjvCFJKgbvfgWYJxWxaFWy23TKoFjg9": 1000
263                                }
264                            }
265                        },
266                        "preProgrammedDistributionRules": {
267                            "$formatVersion": "0",
268                            "authorizedToMakeChange": "ContractOwner",
269                            "adminActionTakers": "ContractOwner",
270                            "changingAuthorizedActionTakersToNoOneAllowed": false,
271                            "changingAdminActionTakersToNoOneAllowed": false,
272                            "selfChangingAdminActionTakersAllowed": false
273                        },
274                        "newTokensDestinationIdentity": null,
275                        "newTokensDestinationIdentityRules": {
276                            "$formatVersion": "0",
277                            "authorizedToMakeChange": "ContractOwner",
278                            "adminActionTakers": "ContractOwner",
279                            "changingAuthorizedActionTakersToNoOneAllowed": false,
280                            "changingAdminActionTakersToNoOneAllowed": false,
281                            "selfChangingAdminActionTakersAllowed": false
282                        },
283                        "mintingAllowChoosingDestination": false,
284                        "mintingAllowChoosingDestinationRules": {
285                            "$formatVersion": "0",
286                            "authorizedToMakeChange": "ContractOwner",
287                            "adminActionTakers": "ContractOwner",
288                            "changingAuthorizedActionTakersToNoOneAllowed": false,
289                            "changingAdminActionTakersToNoOneAllowed": false,
290                            "selfChangingAdminActionTakersAllowed": false
291                        },
292                        "changeDirectPurchasePricingRules": {
293                            "$formatVersion": "0",
294                            "authorizedToMakeChange": "NoOne",
295                            "adminActionTakers": "NoOne",
296                            "changingAuthorizedActionTakersToNoOneAllowed": false,
297                            "changingAdminActionTakersToNoOneAllowed": false,
298                            "selfChangingAdminActionTakersAllowed": false
299                        }
300                    },
301                    "marketplaceRules": {"$formatVersion": "0", "tradeMode": "NotTradeable"},
302                    "manualMintingRules": {
303                        "$formatVersion": "0",
304                        "authorizedToMakeChange": "ContractOwner",
305                        "adminActionTakers": "ContractOwner",
306                        "changingAuthorizedActionTakersToNoOneAllowed": false,
307                        "changingAdminActionTakersToNoOneAllowed": false,
308                        "selfChangingAdminActionTakersAllowed": false
309                    },
310                    "manualBurningRules": {
311                        "$formatVersion": "0",
312                        "authorizedToMakeChange": "ContractOwner",
313                        "adminActionTakers": "ContractOwner",
314                        "changingAuthorizedActionTakersToNoOneAllowed": false,
315                        "changingAdminActionTakersToNoOneAllowed": false,
316                        "selfChangingAdminActionTakersAllowed": false
317                    },
318                    "freezeRules": {
319                        "$formatVersion": "0",
320                        "authorizedToMakeChange": "ContractOwner",
321                        "adminActionTakers": "ContractOwner",
322                        "changingAuthorizedActionTakersToNoOneAllowed": false,
323                        "changingAdminActionTakersToNoOneAllowed": false,
324                        "selfChangingAdminActionTakersAllowed": false
325                    },
326                    "unfreezeRules": {
327                        "$formatVersion": "0",
328                        "authorizedToMakeChange": "ContractOwner",
329                        "adminActionTakers": "ContractOwner",
330                        "changingAuthorizedActionTakersToNoOneAllowed": false,
331                        "changingAdminActionTakersToNoOneAllowed": false,
332                        "selfChangingAdminActionTakersAllowed": false
333                    },
334                    "destroyFrozenFundsRules": {
335                        "$formatVersion": "0",
336                        "authorizedToMakeChange": "ContractOwner",
337                        "adminActionTakers": "ContractOwner",
338                        "changingAuthorizedActionTakersToNoOneAllowed": false,
339                        "changingAdminActionTakersToNoOneAllowed": false,
340                        "selfChangingAdminActionTakersAllowed": false
341                    },
342                    "emergencyActionRules": {
343                        "$formatVersion": "0",
344                        "authorizedToMakeChange": "ContractOwner",
345                        "adminActionTakers": "ContractOwner",
346                        "changingAuthorizedActionTakersToNoOneAllowed": false,
347                        "changingAdminActionTakersToNoOneAllowed": false,
348                        "selfChangingAdminActionTakersAllowed": false
349                    },
350                    "directPurchaseRules": {
351                        "$formatVersion": "0",
352                        "authorizedToMakeChange": "NoOne",
353                        "adminActionTakers": "NoOne",
354                        "changingAuthorizedActionTakersToNoOneAllowed": false,
355                        "changingAdminActionTakersToNoOneAllowed": false,
356                        "selfChangingAdminActionTakersAllowed": false
357                    },
358                    "mainControlGroup": null,
359                    "mainControlGroupCanBeModified": "NoOne"
360                }
361            }
362        });
363
364        let result = DataContract::from_json(contract, true, &platform_version);
365        assert!(
366            result.is_ok(),
367            "PreProgrammed with string timestamp keys should be accepted by from_json"
368        );
369    }
370}