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