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