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