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 address = s.address();
590 let module = s.module();
591 let name = s.name();
592 let type_params = s.type_params();
593
594 if let Some(coin_type) = s.is_coin() {
595 if let TypeTag::Struct(s_inner) = coin_type {
596 let address = s_inner.address();
597 let module = s_inner.module();
598 let name = s_inner.name();
599 let type_params = s_inner.type_params();
600
601 if address == &Address::TWO
602 && module == "sui"
603 && name == "SUI"
604 && type_params.is_empty()
605 {
606 return Self::GasCoin;
607 }
608 }
609
610 Self::Coin(coin_type)
611 } else if address == &Address::THREE
612 && module == "staking_pool"
613 && name == "StakedSui"
614 && type_params.is_empty()
615 {
616 Self::StakedSui
617 } else {
618 Self::Other(s)
619 }
620 }
621 }
622
623 pub(super) struct BinaryMoveStructType;
624
625 impl SerializeAs<StructTag> for BinaryMoveStructType {
626 fn serialize_as<S>(source: &StructTag, serializer: S) -> Result<S::Ok, S::Error>
627 where
628 S: Serializer,
629 {
630 let move_object_type = MoveStructTypeRef::from_struct_tag(source);
631 move_object_type.serialize(serializer)
632 }
633 }
634
635 impl<'de> DeserializeAs<'de, StructTag> for BinaryMoveStructType {
636 fn deserialize_as<D>(deserializer: D) -> Result<StructTag, D::Error>
637 where
638 D: Deserializer<'de>,
639 {
640 let struct_type = MoveStructType::deserialize(deserializer)?;
641 Ok(struct_type.into_struct_tag())
642 }
643 }
644
645 #[derive(serde_derive::Serialize, serde_derive::Deserialize)]
646 enum BinaryGenesisObject {
647 RawObject { data: ObjectData, owner: Owner },
648 }
649
650 impl Serialize for GenesisObject {
651 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
652 where
653 S: Serializer,
654 {
655 let binary = BinaryGenesisObject::RawObject {
656 data: self.data.clone(),
657 owner: self.owner,
658 };
659 binary.serialize(serializer)
660 }
661 }
662
663 impl<'de> Deserialize<'de> for GenesisObject {
664 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
665 where
666 D: Deserializer<'de>,
667 {
668 let BinaryGenesisObject::RawObject { data, owner } =
669 Deserialize::deserialize(deserializer)?;
670
671 Ok(GenesisObject { data, owner })
672 }
673 }
674
675 #[cfg(test)]
676 mod test {
677 use crate::object::Object;
678
679 #[cfg(target_arch = "wasm32")]
680 use wasm_bindgen_test::wasm_bindgen_test as test;
681
682 #[test]
683 fn object_fixture() {
684 const SUI_COIN: &[u8] = &[
685 0, 1, 1, 32, 79, 43, 0, 0, 0, 0, 0, 40, 35, 95, 175, 213, 151, 87, 206, 190, 35,
686 131, 79, 35, 254, 22, 15, 181, 40, 108, 28, 77, 68, 229, 107, 254, 191, 160, 196,
687 186, 42, 2, 122, 53, 52, 133, 199, 58, 0, 0, 0, 0, 0, 79, 255, 208, 0, 85, 34, 190,
688 75, 192, 41, 114, 76, 127, 15, 110, 215, 9, 58, 107, 243, 160, 155, 144, 230, 47,
689 97, 220, 21, 24, 30, 26, 62, 32, 17, 197, 192, 38, 64, 173, 142, 143, 49, 111, 15,
690 211, 92, 84, 48, 160, 243, 102, 229, 253, 251, 137, 210, 101, 119, 173, 228, 51,
691 141, 20, 15, 85, 96, 19, 15, 0, 0, 0, 0, 0,
692 ];
693
694 const SUI_STAKE: &[u8] = &[
695 0, 2, 1, 154, 1, 52, 5, 0, 0, 0, 0, 80, 3, 112, 71, 231, 166, 234, 205, 164, 99,
696 237, 29, 56, 97, 170, 21, 96, 105, 158, 227, 122, 22, 251, 60, 162, 12, 97, 151,
697 218, 71, 253, 231, 239, 116, 138, 12, 233, 128, 195, 128, 77, 33, 38, 122, 77, 53,
698 154, 197, 198, 75, 212, 12, 182, 163, 224, 42, 82, 123, 69, 248, 40, 207, 143, 211,
699 13, 106, 1, 0, 0, 0, 0, 0, 0, 59, 81, 183, 246, 112, 0, 0, 0, 0, 79, 255, 208, 0,
700 85, 34, 190, 75, 192, 41, 114, 76, 127, 15, 110, 215, 9, 58, 107, 243, 160, 155,
701 144, 230, 47, 97, 220, 21, 24, 30, 26, 62, 32, 247, 239, 248, 71, 247, 102, 190,
702 149, 232, 153, 138, 67, 169, 209, 203, 29, 255, 215, 223, 57, 159, 44, 40, 218,
703 166, 13, 80, 71, 14, 188, 232, 68, 0, 0, 0, 0, 0, 0, 0, 0,
704 ];
705
706 const NFT: &[u8] = &[
707 0, 0, 97, 201, 195, 159, 216, 97, 133, 173, 96, 215, 56, 212, 229, 43, 208, 139,
708 218, 7, 29, 54, 106, 205, 224, 126, 7, 195, 145, 106, 45, 117, 168, 22, 12, 100,
709 105, 115, 116, 114, 105, 98, 117, 116, 105, 111, 110, 11, 68, 69, 69, 80, 87, 114,
710 97, 112, 112, 101, 114, 0, 0, 124, 24, 223, 4, 0, 0, 0, 0, 40, 31, 8, 18, 84, 38,
711 164, 252, 84, 115, 250, 246, 137, 132, 128, 186, 156, 36, 62, 18, 140, 21, 4, 90,
712 209, 105, 85, 84, 92, 214, 97, 81, 207, 64, 194, 198, 208, 21, 0, 0, 0, 0, 79, 255,
713 208, 0, 85, 34, 190, 75, 192, 41, 114, 76, 127, 15, 110, 215, 9, 58, 107, 243, 160,
714 155, 144, 230, 47, 97, 220, 21, 24, 30, 26, 62, 32, 170, 4, 94, 114, 207, 155, 31,
715 80, 62, 254, 220, 206, 240, 218, 83, 54, 204, 197, 255, 239, 41, 66, 199, 150, 56,
716 189, 86, 217, 166, 216, 128, 241, 64, 205, 21, 0, 0, 0, 0, 0,
717 ];
718
719 const FUD_COIN: &[u8] = &[
720 0, 3, 7, 118, 203, 129, 155, 1, 171, 237, 80, 43, 238, 138, 112, 43, 76, 45, 84,
721 117, 50, 193, 47, 37, 0, 28, 157, 234, 121, 90, 94, 99, 28, 38, 241, 3, 102, 117,
722 100, 3, 70, 85, 68, 0, 1, 193, 89, 252, 3, 0, 0, 0, 0, 40, 33, 214, 90, 11, 56,
723 243, 115, 10, 250, 121, 250, 28, 34, 237, 104, 130, 148, 40, 130, 29, 248, 137,
724 244, 27, 138, 94, 150, 28, 182, 104, 162, 185, 0, 152, 247, 62, 93, 1, 0, 0, 0, 42,
725 95, 32, 226, 13, 31, 128, 91, 188, 127, 235, 12, 75, 73, 116, 112, 3, 227, 244,
726 126, 59, 81, 214, 118, 144, 243, 195, 17, 82, 216, 119, 170, 32, 239, 247, 71, 249,
727 241, 98, 133, 53, 46, 37, 100, 242, 94, 231, 241, 184, 8, 69, 192, 69, 67, 1, 116,
728 251, 229, 226, 99, 119, 79, 255, 71, 43, 64, 242, 19, 0, 0, 0, 0, 0,
729 ];
730
731 const BULLSHARK_PACKAGE: &[u8] = &[
732 1, 135, 35, 29, 28, 138, 126, 114, 145, 204, 122, 145, 8, 244, 199, 188, 26, 10,
733 28, 14, 182, 55, 91, 91, 97, 10, 245, 202, 35, 223, 14, 140, 86, 1, 0, 0, 0, 0, 0,
734 0, 0, 1, 9, 98, 117, 108, 108, 115, 104, 97, 114, 107, 162, 6, 161, 28, 235, 11, 6,
735 0, 0, 0, 10, 1, 0, 12, 2, 12, 36, 3, 48, 61, 4, 109, 12, 5, 121, 137, 1, 7, 130, 2,
736 239, 1, 8, 241, 3, 96, 6, 209, 4, 82, 10, 163, 5, 5, 12, 168, 5, 75, 0, 7, 1, 16,
737 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,
738 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,
739 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,
740 14, 17, 1, 1, 0, 3, 17, 7, 1, 1, 12, 3, 18, 16, 1, 1, 12, 4, 19, 13, 14, 0, 5, 15,
741 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,
742 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,
743 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,
744 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,
745 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,
746 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,
747 72, 65, 82, 75, 4, 67, 111, 105, 110, 12, 67, 111, 105, 110, 77, 101, 116, 97, 100,
748 97, 116, 97, 6, 79, 112, 116, 105, 111, 110, 11, 84, 114, 101, 97, 115, 117, 114,
749 121, 67, 97, 112, 9, 84, 120, 67, 111, 110, 116, 101, 120, 116, 3, 85, 114, 108, 9,
750 98, 117, 108, 108, 115, 104, 97, 114, 107, 4, 98, 117, 114, 110, 4, 99, 111, 105,
751 110, 15, 99, 114, 101, 97, 116, 101, 95, 99, 117, 114, 114, 101, 110, 99, 121, 11,
752 100, 117, 109, 109, 121, 95, 102, 105, 101, 108, 100, 4, 105, 110, 105, 116, 4,
753 109, 105, 110, 116, 17, 109, 105, 110, 116, 95, 97, 110, 100, 95, 116, 114, 97,
754 110, 115, 102, 101, 114, 21, 110, 101, 119, 95, 117, 110, 115, 97, 102, 101, 95,
755 102, 114, 111, 109, 95, 98, 121, 116, 101, 115, 6, 111, 112, 116, 105, 111, 110,
756 20, 112, 117, 98, 108, 105, 99, 95, 102, 114, 101, 101, 122, 101, 95, 111, 98, 106,
757 101, 99, 116, 15, 112, 117, 98, 108, 105, 99, 95, 116, 114, 97, 110, 115, 102, 101,
758 114, 6, 115, 101, 110, 100, 101, 114, 4, 115, 111, 109, 101, 8, 116, 114, 97, 110,
759 115, 102, 101, 114, 10, 116, 120, 95, 99, 111, 110, 116, 101, 120, 116, 3, 117,
760 114, 108, 135, 35, 29, 28, 138, 126, 114, 145, 204, 122, 145, 8, 244, 199, 188, 26,
761 10, 28, 14, 182, 55, 91, 91, 97, 10, 245, 202, 35, 223, 14, 140, 86, 0, 0, 0, 0, 0,
762 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,
763 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,
764 0, 0, 2, 10, 2, 10, 9, 66, 85, 76, 76, 83, 72, 65, 82, 75, 10, 2, 20, 19, 66, 117,
765 108, 108, 32, 83, 104, 97, 114, 107, 32, 83, 117, 105, 70, 114, 101, 110, 115, 10,
766 2, 1, 0, 10, 2, 39, 38, 104, 116, 116, 112, 115, 58, 47, 47, 105, 46, 105, 98, 98,
767 46, 99, 111, 47, 104, 87, 89, 50, 87, 53, 120, 47, 98, 117, 108, 108, 115, 104, 97,
768 114, 107, 46, 112, 110, 103, 0, 2, 1, 11, 1, 0, 0, 0, 0, 4, 20, 11, 0, 49, 6, 7, 0,
769 7, 1, 7, 2, 7, 3, 17, 10, 56, 0, 10, 1, 56, 1, 12, 2, 12, 3, 11, 2, 56, 2, 11, 3,
770 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,
771 2, 1, 4, 0, 1, 5, 11, 0, 11, 1, 56, 5, 1, 2, 0, 1, 9, 98, 117, 108, 108, 115, 104,
772 97, 114, 107, 9, 66, 85, 76, 76, 83, 72, 65, 82, 75, 135, 35, 29, 28, 138, 126,
773 114, 145, 204, 122, 145, 8, 244, 199, 188, 26, 10, 28, 14, 182, 55, 91, 91, 97, 10,
774 245, 202, 35, 223, 14, 140, 86, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
775 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,
776 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,
777 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,
778 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,
779 0, 0, 0, 0, 0, 0, 0, 2, 4, 0, 0, 0, 0, 0, 0, 0, 3, 32, 87, 145, 191, 231, 147, 185,
780 46, 159, 240, 181, 95, 126, 236, 65, 154, 55, 16, 196, 229, 218, 47, 59, 99, 197,
781 13, 89, 18, 159, 205, 129, 112, 131, 112, 192, 126, 0, 0, 0, 0, 0,
782 ];
783
784 for fixture in [SUI_COIN, SUI_STAKE, NFT, FUD_COIN, BULLSHARK_PACKAGE] {
785 let object: Object = bcs::from_bytes(fixture).unwrap();
786 assert_eq!(bcs::to_bytes(&object).unwrap(), fixture);
787
788 let json = serde_json::to_string_pretty(&object).unwrap();
789 println!("{json}");
790 assert_eq!(object, serde_json::from_str(&json).unwrap());
791 }
792 }
793 }
794}