1use std::collections::BTreeMap;
2
3use super::Address;
4use super::Identifier;
5use super::ObjectDigest;
6use super::ObjectId;
7use super::StructTag;
8use super::TransactionDigest;
9
10pub type Version = u64;
11
12#[derive(Clone, Debug, PartialEq, Eq)]
24#[cfg_attr(
25 feature = "serde",
26 derive(serde_derive::Serialize, serde_derive::Deserialize)
27)]
28#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
29pub struct ObjectReference {
30 object_id: ObjectId,
32 version: Version,
34 digest: ObjectDigest,
36}
37
38impl ObjectReference {
39 pub fn new(object_id: ObjectId, version: Version, digest: ObjectDigest) -> Self {
41 Self {
42 object_id,
43 version,
44 digest,
45 }
46 }
47
48 pub fn object_id(&self) -> &ObjectId {
50 &self.object_id
51 }
52
53 pub fn version(&self) -> Version {
55 self.version
56 }
57
58 pub fn digest(&self) -> &ObjectDigest {
60 &self.digest
61 }
62
63 pub fn into_parts(self) -> (ObjectId, Version, ObjectDigest) {
65 let Self {
66 object_id,
67 version,
68 digest,
69 } = self;
70
71 (object_id, version, digest)
72 }
73}
74
75#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
90#[cfg_attr(
91 feature = "serde",
92 derive(serde_derive::Serialize, serde_derive::Deserialize),
93 serde(rename_all = "lowercase")
94)]
95#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
96pub enum Owner {
97 Address(Address),
99 Object(ObjectId),
101 Shared(
103 Version,
105 ),
106 Immutable,
108
109 ConsensusAddress {
111 start_version: Version,
115
116 owner: Address,
118 },
119}
120
121#[derive(Clone, Debug, PartialEq, Eq, Hash)]
134#[cfg_attr(
135 feature = "serde",
136 derive(serde_derive::Serialize, serde_derive::Deserialize)
137)]
138#[allow(clippy::large_enum_variant)]
139#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
140pub enum ObjectData {
142 Struct(MoveStruct),
144 Package(MovePackage),
146 }
148
149#[derive(Eq, PartialEq, Debug, Clone, Hash)]
163#[cfg_attr(
164 feature = "serde",
165 derive(serde_derive::Serialize, serde_derive::Deserialize)
166)]
167#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
168pub struct MovePackage {
169 pub id: ObjectId,
171
172 pub version: Version,
183
184 #[cfg_attr(
186 feature = "serde",
187 serde(with = "::serde_with::As::<BTreeMap<::serde_with::Same, ::serde_with::Bytes>>")
188 )]
189 #[cfg_attr(
190 feature = "proptest",
191 strategy(
192 proptest::collection::btree_map(proptest::arbitrary::any::<Identifier>(), proptest::collection::vec(proptest::arbitrary::any::<u8>(), 0..=1024), 0..=5)
193 )
194 )]
195 pub modules: BTreeMap<Identifier, Vec<u8>>,
196
197 #[cfg_attr(feature = "proptest", any(proptest::collection::size_range(0..=1).lift()))]
200 pub type_origin_table: Vec<TypeOrigin>,
201
202 #[cfg_attr(
205 feature = "proptest",
206 strategy(
207 proptest::collection::btree_map(proptest::arbitrary::any::<ObjectId>(), proptest::arbitrary::any::<UpgradeInfo>(), 0..=5)
208 )
209 )]
210 pub linkage_table: BTreeMap<ObjectId, UpgradeInfo>,
211}
212
213#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
223#[cfg_attr(
224 feature = "serde",
225 derive(serde_derive::Serialize, serde_derive::Deserialize)
226)]
227#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
228pub struct TypeOrigin {
229 pub module_name: Identifier,
230 pub struct_name: Identifier,
231 pub package: ObjectId,
232}
233
234#[derive(Eq, PartialEq, Debug, Clone, Hash)]
244#[cfg_attr(
245 feature = "serde",
246 derive(serde_derive::Serialize, serde_derive::Deserialize)
247)]
248#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
249pub struct UpgradeInfo {
250 pub upgraded_id: ObjectId,
252 pub upgraded_version: Version,
254}
255
256#[derive(Eq, PartialEq, Debug, Clone, Hash)]
275#[cfg_attr(
277 feature = "serde",
278 derive(serde_derive::Serialize, serde_derive::Deserialize)
279)]
280#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
281pub struct MoveStruct {
282 #[cfg_attr(
284 feature = "serde",
285 serde(with = "::serde_with::As::<serialization::BinaryMoveStructType>")
286 )]
287 pub(crate) type_: StructTag,
288
289 has_public_transfer: bool,
292
293 version: Version,
296
297 #[cfg_attr(
299 feature = "serde",
300 serde(with = "crate::_serde::ReadableBase64Encoded")
301 )]
302 #[cfg_attr(feature = "proptest", any(proptest::collection::size_range(32..=1024).lift()))]
303 pub(crate) contents: Vec<u8>,
304}
305
306impl MoveStruct {
307 pub fn new(
309 type_: StructTag,
310 has_public_transfer: bool,
311 version: Version,
312 contents: Vec<u8>,
313 ) -> Option<Self> {
314 id_opt(&contents).map(|_| Self {
315 type_,
316 has_public_transfer,
317 version,
318 contents,
319 })
320 }
321
322 pub fn object_type(&self) -> &StructTag {
324 &self.type_
325 }
326
327 #[doc(hidden)]
334 pub fn has_public_transfer(&self) -> bool {
335 self.has_public_transfer
336 }
337
338 pub fn version(&self) -> Version {
340 self.version
341 }
342
343 pub fn contents(&self) -> &[u8] {
345 &self.contents
346 }
347
348 pub fn object_id(&self) -> ObjectId {
350 id_opt(self.contents()).unwrap()
351 }
352}
353
354#[derive(Clone, Ord, PartialOrd, Eq, PartialEq, Debug)]
356pub enum ObjectType {
357 Package,
359 Struct(StructTag),
361}
362
363#[derive(Clone, Debug, PartialEq, Eq)]
373#[cfg_attr(
374 feature = "serde",
375 derive(serde_derive::Serialize, serde_derive::Deserialize)
376)]
377#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
378pub struct Object {
379 pub(crate) data: ObjectData,
381
382 owner: Owner,
384
385 previous_transaction: TransactionDigest,
387
388 storage_rebate: u64,
392}
393
394impl Object {
395 pub fn new(
397 data: ObjectData,
398 owner: Owner,
399 previous_transaction: TransactionDigest,
400 storage_rebate: u64,
401 ) -> Self {
402 Self {
403 data,
404 owner,
405 previous_transaction,
406 storage_rebate,
407 }
408 }
409
410 pub fn object_id(&self) -> ObjectId {
412 match &self.data {
413 ObjectData::Struct(struct_) => id_opt(&struct_.contents).unwrap(),
414 ObjectData::Package(package) => package.id,
415 }
416 }
417
418 pub fn version(&self) -> Version {
420 match &self.data {
421 ObjectData::Struct(struct_) => struct_.version,
422 ObjectData::Package(package) => package.version,
423 }
424 }
425
426 pub fn object_type(&self) -> ObjectType {
428 match &self.data {
429 ObjectData::Struct(struct_) => ObjectType::Struct(struct_.type_.clone()),
430 ObjectData::Package(_) => ObjectType::Package,
431 }
432 }
433
434 pub fn as_struct(&self) -> Option<&MoveStruct> {
436 match &self.data {
437 ObjectData::Struct(struct_) => Some(struct_),
438 _ => None,
439 }
440 }
441
442 pub fn owner(&self) -> &Owner {
444 &self.owner
445 }
446
447 pub fn data(&self) -> &ObjectData {
449 &self.data
450 }
451
452 pub fn previous_transaction(&self) -> TransactionDigest {
454 self.previous_transaction
455 }
456
457 pub fn storage_rebate(&self) -> u64 {
462 self.storage_rebate
463 }
464}
465
466fn id_opt(contents: &[u8]) -> Option<ObjectId> {
467 if ObjectId::LENGTH > contents.len() {
468 return None;
469 }
470
471 Some(ObjectId::from(
472 Address::from_bytes(&contents[..ObjectId::LENGTH]).unwrap(),
473 ))
474}
475
476#[derive(Clone, Debug, PartialEq, Eq)]
489#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
490pub struct GenesisObject {
491 data: ObjectData,
492 owner: Owner,
493}
494
495impl GenesisObject {
496 pub fn new(data: ObjectData, owner: Owner) -> Self {
497 Self { data, owner }
498 }
499
500 pub fn object_id(&self) -> ObjectId {
501 match &self.data {
502 ObjectData::Struct(struct_) => id_opt(&struct_.contents).unwrap(),
503 ObjectData::Package(package) => package.id,
504 }
505 }
506
507 pub fn version(&self) -> Version {
508 match &self.data {
509 ObjectData::Struct(struct_) => struct_.version,
510 ObjectData::Package(package) => package.version,
511 }
512 }
513
514 pub fn object_type(&self) -> ObjectType {
515 match &self.data {
516 ObjectData::Struct(struct_) => ObjectType::Struct(struct_.type_.clone()),
517 ObjectData::Package(_) => ObjectType::Package,
518 }
519 }
520
521 pub fn owner(&self) -> &Owner {
522 &self.owner
523 }
524
525 pub fn data(&self) -> &ObjectData {
526 &self.data
527 }
528}
529
530#[cfg(feature = "serde")]
532#[cfg_attr(doc_cfg, doc(cfg(feature = "serde")))]
533mod serialization {
534 use serde::Deserialize;
535 use serde::Deserializer;
536 use serde::Serialize;
537 use serde::Serializer;
538 use serde_with::DeserializeAs;
539 use serde_with::SerializeAs;
540
541 use super::*;
542 use crate::TypeTag;
543
544 #[derive(serde_derive::Deserialize)]
549 enum MoveStructType {
550 Other(StructTag),
552 GasCoin,
554 StakedSui,
556 Coin(TypeTag),
558 }
562
563 #[derive(serde_derive::Serialize)]
565 enum MoveStructTypeRef<'a> {
566 Other(&'a StructTag),
568 GasCoin,
570 StakedSui,
572 Coin(&'a TypeTag),
574 }
578
579 impl MoveStructType {
580 fn into_struct_tag(self) -> StructTag {
581 match self {
582 MoveStructType::Other(tag) => tag,
583 MoveStructType::GasCoin => StructTag::gas_coin(),
584 MoveStructType::StakedSui => StructTag::staked_sui(),
585 MoveStructType::Coin(type_tag) => StructTag::coin(type_tag),
586 }
587 }
588 }
589
590 impl<'a> MoveStructTypeRef<'a> {
591 fn from_struct_tag(s: &'a StructTag) -> Self {
592 let StructTag {
593 address,
594 module,
595 name,
596 type_params,
597 } = s;
598
599 if let Some(coin_type) = s.is_coin() {
600 if let TypeTag::Struct(s_inner) = coin_type {
601 let StructTag {
602 address,
603 module,
604 name,
605 type_params,
606 } = s_inner.as_ref();
607
608 if address == &Address::TWO
609 && module == "sui"
610 && name == "SUI"
611 && type_params.is_empty()
612 {
613 return Self::GasCoin;
614 }
615 }
616
617 Self::Coin(coin_type)
618 } else if address == &Address::THREE
619 && module == "staking_pool"
620 && name == "StakedSui"
621 && type_params.is_empty()
622 {
623 Self::StakedSui
624 } else {
625 Self::Other(s)
626 }
627 }
628 }
629
630 pub(super) struct BinaryMoveStructType;
631
632 impl SerializeAs<StructTag> for BinaryMoveStructType {
633 fn serialize_as<S>(source: &StructTag, serializer: S) -> Result<S::Ok, S::Error>
634 where
635 S: Serializer,
636 {
637 let move_object_type = MoveStructTypeRef::from_struct_tag(source);
638 move_object_type.serialize(serializer)
639 }
640 }
641
642 impl<'de> DeserializeAs<'de, StructTag> for BinaryMoveStructType {
643 fn deserialize_as<D>(deserializer: D) -> Result<StructTag, D::Error>
644 where
645 D: Deserializer<'de>,
646 {
647 let struct_type = MoveStructType::deserialize(deserializer)?;
648 Ok(struct_type.into_struct_tag())
649 }
650 }
651
652 #[derive(serde_derive::Serialize, serde_derive::Deserialize)]
653 enum BinaryGenesisObject {
654 RawObject { data: ObjectData, owner: Owner },
655 }
656
657 impl Serialize for GenesisObject {
658 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
659 where
660 S: Serializer,
661 {
662 let binary = BinaryGenesisObject::RawObject {
663 data: self.data.clone(),
664 owner: self.owner,
665 };
666 binary.serialize(serializer)
667 }
668 }
669
670 impl<'de> Deserialize<'de> for GenesisObject {
671 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
672 where
673 D: Deserializer<'de>,
674 {
675 let BinaryGenesisObject::RawObject { data, owner } =
676 Deserialize::deserialize(deserializer)?;
677
678 Ok(GenesisObject { data, owner })
679 }
680 }
681
682 #[cfg(test)]
683 mod test {
684 use crate::object::Object;
685
686 #[cfg(target_arch = "wasm32")]
687 use wasm_bindgen_test::wasm_bindgen_test as test;
688
689 #[test]
690 fn object_fixture() {
691 const SUI_COIN: &[u8] = &[
692 0, 1, 1, 32, 79, 43, 0, 0, 0, 0, 0, 40, 35, 95, 175, 213, 151, 87, 206, 190, 35,
693 131, 79, 35, 254, 22, 15, 181, 40, 108, 28, 77, 68, 229, 107, 254, 191, 160, 196,
694 186, 42, 2, 122, 53, 52, 133, 199, 58, 0, 0, 0, 0, 0, 79, 255, 208, 0, 85, 34, 190,
695 75, 192, 41, 114, 76, 127, 15, 110, 215, 9, 58, 107, 243, 160, 155, 144, 230, 47,
696 97, 220, 21, 24, 30, 26, 62, 32, 17, 197, 192, 38, 64, 173, 142, 143, 49, 111, 15,
697 211, 92, 84, 48, 160, 243, 102, 229, 253, 251, 137, 210, 101, 119, 173, 228, 51,
698 141, 20, 15, 85, 96, 19, 15, 0, 0, 0, 0, 0,
699 ];
700
701 const SUI_STAKE: &[u8] = &[
702 0, 2, 1, 154, 1, 52, 5, 0, 0, 0, 0, 80, 3, 112, 71, 231, 166, 234, 205, 164, 99,
703 237, 29, 56, 97, 170, 21, 96, 105, 158, 227, 122, 22, 251, 60, 162, 12, 97, 151,
704 218, 71, 253, 231, 239, 116, 138, 12, 233, 128, 195, 128, 77, 33, 38, 122, 77, 53,
705 154, 197, 198, 75, 212, 12, 182, 163, 224, 42, 82, 123, 69, 248, 40, 207, 143, 211,
706 13, 106, 1, 0, 0, 0, 0, 0, 0, 59, 81, 183, 246, 112, 0, 0, 0, 0, 79, 255, 208, 0,
707 85, 34, 190, 75, 192, 41, 114, 76, 127, 15, 110, 215, 9, 58, 107, 243, 160, 155,
708 144, 230, 47, 97, 220, 21, 24, 30, 26, 62, 32, 247, 239, 248, 71, 247, 102, 190,
709 149, 232, 153, 138, 67, 169, 209, 203, 29, 255, 215, 223, 57, 159, 44, 40, 218,
710 166, 13, 80, 71, 14, 188, 232, 68, 0, 0, 0, 0, 0, 0, 0, 0,
711 ];
712
713 const NFT: &[u8] = &[
714 0, 0, 97, 201, 195, 159, 216, 97, 133, 173, 96, 215, 56, 212, 229, 43, 208, 139,
715 218, 7, 29, 54, 106, 205, 224, 126, 7, 195, 145, 106, 45, 117, 168, 22, 12, 100,
716 105, 115, 116, 114, 105, 98, 117, 116, 105, 111, 110, 11, 68, 69, 69, 80, 87, 114,
717 97, 112, 112, 101, 114, 0, 0, 124, 24, 223, 4, 0, 0, 0, 0, 40, 31, 8, 18, 84, 38,
718 164, 252, 84, 115, 250, 246, 137, 132, 128, 186, 156, 36, 62, 18, 140, 21, 4, 90,
719 209, 105, 85, 84, 92, 214, 97, 81, 207, 64, 194, 198, 208, 21, 0, 0, 0, 0, 79, 255,
720 208, 0, 85, 34, 190, 75, 192, 41, 114, 76, 127, 15, 110, 215, 9, 58, 107, 243, 160,
721 155, 144, 230, 47, 97, 220, 21, 24, 30, 26, 62, 32, 170, 4, 94, 114, 207, 155, 31,
722 80, 62, 254, 220, 206, 240, 218, 83, 54, 204, 197, 255, 239, 41, 66, 199, 150, 56,
723 189, 86, 217, 166, 216, 128, 241, 64, 205, 21, 0, 0, 0, 0, 0,
724 ];
725
726 const FUD_COIN: &[u8] = &[
727 0, 3, 7, 118, 203, 129, 155, 1, 171, 237, 80, 43, 238, 138, 112, 43, 76, 45, 84,
728 117, 50, 193, 47, 37, 0, 28, 157, 234, 121, 90, 94, 99, 28, 38, 241, 3, 102, 117,
729 100, 3, 70, 85, 68, 0, 1, 193, 89, 252, 3, 0, 0, 0, 0, 40, 33, 214, 90, 11, 56,
730 243, 115, 10, 250, 121, 250, 28, 34, 237, 104, 130, 148, 40, 130, 29, 248, 137,
731 244, 27, 138, 94, 150, 28, 182, 104, 162, 185, 0, 152, 247, 62, 93, 1, 0, 0, 0, 42,
732 95, 32, 226, 13, 31, 128, 91, 188, 127, 235, 12, 75, 73, 116, 112, 3, 227, 244,
733 126, 59, 81, 214, 118, 144, 243, 195, 17, 82, 216, 119, 170, 32, 239, 247, 71, 249,
734 241, 98, 133, 53, 46, 37, 100, 242, 94, 231, 241, 184, 8, 69, 192, 69, 67, 1, 116,
735 251, 229, 226, 99, 119, 79, 255, 71, 43, 64, 242, 19, 0, 0, 0, 0, 0,
736 ];
737
738 const BULLSHARK_PACKAGE: &[u8] = &[
739 1, 135, 35, 29, 28, 138, 126, 114, 145, 204, 122, 145, 8, 244, 199, 188, 26, 10,
740 28, 14, 182, 55, 91, 91, 97, 10, 245, 202, 35, 223, 14, 140, 86, 1, 0, 0, 0, 0, 0,
741 0, 0, 1, 9, 98, 117, 108, 108, 115, 104, 97, 114, 107, 162, 6, 161, 28, 235, 11, 6,
742 0, 0, 0, 10, 1, 0, 12, 2, 12, 36, 3, 48, 61, 4, 109, 12, 5, 121, 137, 1, 7, 130, 2,
743 239, 1, 8, 241, 3, 96, 6, 209, 4, 82, 10, 163, 5, 5, 12, 168, 5, 75, 0, 7, 1, 16,
744 2, 9, 2, 21, 2, 22, 2, 23, 0, 0, 2, 0, 1, 3, 7, 1, 0, 0, 2, 1, 12, 1, 0, 1, 2, 2,
745 12, 1, 0, 1, 2, 4, 12, 1, 0, 1, 4, 5, 2, 0, 5, 6, 7, 0, 0, 12, 0, 1, 0, 0, 13, 2,
746 1, 0, 0, 8, 3, 1, 0, 1, 20, 7, 8, 1, 0, 2, 8, 18, 19, 1, 0, 2, 10, 10, 11, 1, 2, 2,
747 14, 17, 1, 1, 0, 3, 17, 7, 1, 1, 12, 3, 18, 16, 1, 1, 12, 4, 19, 13, 14, 0, 5, 15,
748 5, 6, 0, 3, 6, 5, 9, 7, 12, 8, 15, 6, 9, 4, 9, 2, 8, 0, 7, 8, 5, 0, 4, 7, 11, 4, 1,
749 8, 0, 3, 5, 7, 8, 5, 2, 7, 11, 4, 1, 8, 0, 11, 2, 1, 8, 0, 2, 11, 3, 1, 8, 0, 11,
750 4, 1, 8, 0, 1, 10, 2, 1, 8, 6, 1, 9, 0, 1, 11, 1, 1, 9, 0, 1, 8, 0, 7, 9, 0, 2, 10,
751 2, 10, 2, 10, 2, 11, 1, 1, 8, 6, 7, 8, 5, 2, 11, 4, 1, 9, 0, 11, 3, 1, 9, 0, 1, 11,
752 3, 1, 8, 0, 1, 6, 8, 5, 1, 5, 1, 11, 4, 1, 8, 0, 2, 9, 0, 5, 4, 7, 11, 4, 1, 9, 0,
753 3, 5, 7, 8, 5, 2, 7, 11, 4, 1, 9, 0, 11, 2, 1, 9, 0, 1, 3, 9, 66, 85, 76, 76, 83,
754 72, 65, 82, 75, 4, 67, 111, 105, 110, 12, 67, 111, 105, 110, 77, 101, 116, 97, 100,
755 97, 116, 97, 6, 79, 112, 116, 105, 111, 110, 11, 84, 114, 101, 97, 115, 117, 114,
756 121, 67, 97, 112, 9, 84, 120, 67, 111, 110, 116, 101, 120, 116, 3, 85, 114, 108, 9,
757 98, 117, 108, 108, 115, 104, 97, 114, 107, 4, 98, 117, 114, 110, 4, 99, 111, 105,
758 110, 15, 99, 114, 101, 97, 116, 101, 95, 99, 117, 114, 114, 101, 110, 99, 121, 11,
759 100, 117, 109, 109, 121, 95, 102, 105, 101, 108, 100, 4, 105, 110, 105, 116, 4,
760 109, 105, 110, 116, 17, 109, 105, 110, 116, 95, 97, 110, 100, 95, 116, 114, 97,
761 110, 115, 102, 101, 114, 21, 110, 101, 119, 95, 117, 110, 115, 97, 102, 101, 95,
762 102, 114, 111, 109, 95, 98, 121, 116, 101, 115, 6, 111, 112, 116, 105, 111, 110,
763 20, 112, 117, 98, 108, 105, 99, 95, 102, 114, 101, 101, 122, 101, 95, 111, 98, 106,
764 101, 99, 116, 15, 112, 117, 98, 108, 105, 99, 95, 116, 114, 97, 110, 115, 102, 101,
765 114, 6, 115, 101, 110, 100, 101, 114, 4, 115, 111, 109, 101, 8, 116, 114, 97, 110,
766 115, 102, 101, 114, 10, 116, 120, 95, 99, 111, 110, 116, 101, 120, 116, 3, 117,
767 114, 108, 135, 35, 29, 28, 138, 126, 114, 145, 204, 122, 145, 8, 244, 199, 188, 26,
768 10, 28, 14, 182, 55, 91, 91, 97, 10, 245, 202, 35, 223, 14, 140, 86, 0, 0, 0, 0, 0,
769 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
770 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
771 0, 0, 2, 10, 2, 10, 9, 66, 85, 76, 76, 83, 72, 65, 82, 75, 10, 2, 20, 19, 66, 117,
772 108, 108, 32, 83, 104, 97, 114, 107, 32, 83, 117, 105, 70, 114, 101, 110, 115, 10,
773 2, 1, 0, 10, 2, 39, 38, 104, 116, 116, 112, 115, 58, 47, 47, 105, 46, 105, 98, 98,
774 46, 99, 111, 47, 104, 87, 89, 50, 87, 53, 120, 47, 98, 117, 108, 108, 115, 104, 97,
775 114, 107, 46, 112, 110, 103, 0, 2, 1, 11, 1, 0, 0, 0, 0, 4, 20, 11, 0, 49, 6, 7, 0,
776 7, 1, 7, 2, 7, 3, 17, 10, 56, 0, 10, 1, 56, 1, 12, 2, 12, 3, 11, 2, 56, 2, 11, 3,
777 11, 1, 46, 17, 9, 56, 3, 2, 1, 1, 4, 0, 1, 6, 11, 0, 11, 1, 11, 2, 11, 3, 56, 4, 2,
778 2, 1, 4, 0, 1, 5, 11, 0, 11, 1, 56, 5, 1, 2, 0, 1, 9, 98, 117, 108, 108, 115, 104,
779 97, 114, 107, 9, 66, 85, 76, 76, 83, 72, 65, 82, 75, 135, 35, 29, 28, 138, 126,
780 114, 145, 204, 122, 145, 8, 244, 199, 188, 26, 10, 28, 14, 182, 55, 91, 91, 97, 10,
781 245, 202, 35, 223, 14, 140, 86, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
782 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
783 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0,
784 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
785 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
786 0, 0, 0, 0, 0, 0, 0, 2, 4, 0, 0, 0, 0, 0, 0, 0, 3, 32, 87, 145, 191, 231, 147, 185,
787 46, 159, 240, 181, 95, 126, 236, 65, 154, 55, 16, 196, 229, 218, 47, 59, 99, 197,
788 13, 89, 18, 159, 205, 129, 112, 131, 112, 192, 126, 0, 0, 0, 0, 0,
789 ];
790
791 for fixture in [SUI_COIN, SUI_STAKE, NFT, FUD_COIN, BULLSHARK_PACKAGE] {
792 let object: Object = bcs::from_bytes(fixture).unwrap();
793 assert_eq!(bcs::to_bytes(&object).unwrap(), fixture);
794
795 let json = serde_json::to_string_pretty(&object).unwrap();
796 println!("{json}");
797 assert_eq!(object, serde_json::from_str(&json).unwrap());
798 }
799 }
800 }
801}