1use alloc::{borrow::Cow, string::String, vec::Vec};
2use core::fmt;
3use core::ops::Deref;
4use schemars::JsonSchema;
5use serde::{Deserialize, Serialize};
6use sha2::{
7 digest::{Digest, Update},
8 Sha256,
9};
10
11use crate::Binary;
12use crate::{HexBinary, __internal::forward_ref_partial_eq};
13
14#[derive(
31 Serialize, Deserialize, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, JsonSchema,
32)]
33pub struct Addr(String);
34
35forward_ref_partial_eq!(Addr, Addr);
36
37impl Addr {
38 pub fn unchecked(input: impl Into<String>) -> Addr {
54 Addr(input.into())
55 }
56
57 #[inline]
58 pub fn as_str(&self) -> &str {
59 self.0.as_str()
60 }
61
62 #[inline]
66 pub fn as_bytes(&self) -> &[u8] {
67 self.0.as_bytes()
68 }
69
70 #[inline]
72 pub fn into_string(self) -> String {
73 self.0
74 }
75}
76
77impl fmt::Display for Addr {
78 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
79 write!(f, "{}", &self.0)
80 }
81}
82
83impl AsRef<str> for Addr {
84 #[inline]
85 fn as_ref(&self) -> &str {
86 self.as_str()
87 }
88}
89
90impl From<Addr> for String {
94 fn from(addr: Addr) -> Self {
95 addr.0
96 }
97}
98
99impl From<&Addr> for String {
100 fn from(addr: &Addr) -> Self {
101 addr.0.clone()
102 }
103}
104
105impl From<Addr> for Cow<'_, Addr> {
106 fn from(addr: Addr) -> Self {
107 Cow::Owned(addr)
108 }
109}
110
111impl<'a> From<&'a Addr> for Cow<'a, Addr> {
112 fn from(addr: &'a Addr) -> Self {
113 Cow::Borrowed(addr)
114 }
115}
116
117#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, Hash, schemars::JsonSchema)]
133pub struct CanonicalAddr(Binary);
134
135impl PartialEq<Binary> for CanonicalAddr {
137 fn eq(&self, rhs: &Binary) -> bool {
138 &self.0 == rhs
139 }
140}
141
142impl PartialEq<CanonicalAddr> for Binary {
144 fn eq(&self, rhs: &CanonicalAddr) -> bool {
145 self == &rhs.0
146 }
147}
148
149impl PartialEq<HexBinary> for CanonicalAddr {
151 fn eq(&self, rhs: &HexBinary) -> bool {
152 self.as_slice() == rhs.as_slice()
153 }
154}
155
156impl PartialEq<CanonicalAddr> for HexBinary {
158 fn eq(&self, rhs: &CanonicalAddr) -> bool {
159 self.as_slice() == rhs.0.as_slice()
160 }
161}
162
163impl From<&[u8]> for CanonicalAddr {
164 fn from(source: &[u8]) -> Self {
165 Self(source.into())
166 }
167}
168
169impl<const LENGTH: usize> From<&[u8; LENGTH]> for CanonicalAddr {
171 fn from(source: &[u8; LENGTH]) -> Self {
172 Self(source.into())
173 }
174}
175
176impl<const LENGTH: usize> From<[u8; LENGTH]> for CanonicalAddr {
178 fn from(source: [u8; LENGTH]) -> Self {
179 Self(source.into())
180 }
181}
182
183impl From<Vec<u8>> for CanonicalAddr {
185 fn from(source: Vec<u8>) -> Self {
186 Self(source.into())
187 }
188}
189
190impl From<CanonicalAddr> for Vec<u8> {
192 fn from(source: CanonicalAddr) -> Vec<u8> {
193 source.0.into()
194 }
195}
196
197impl From<Binary> for CanonicalAddr {
199 fn from(source: Binary) -> Self {
200 Self(source)
201 }
202}
203
204impl From<CanonicalAddr> for Binary {
206 fn from(source: CanonicalAddr) -> Binary {
207 source.0
208 }
209}
210
211impl From<HexBinary> for CanonicalAddr {
213 fn from(source: HexBinary) -> Self {
214 Self(source.into())
215 }
216}
217
218impl From<CanonicalAddr> for HexBinary {
220 fn from(source: CanonicalAddr) -> HexBinary {
221 source.0.into()
222 }
223}
224
225impl Deref for CanonicalAddr {
231 type Target = [u8];
232
233 fn deref(&self) -> &Self::Target {
234 self.as_slice()
235 }
236}
237
238impl CanonicalAddr {
239 pub fn as_slice(&self) -> &[u8] {
240 self.0.as_slice()
241 }
242}
243
244impl fmt::Display for CanonicalAddr {
245 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
246 for byte in self.0.as_slice() {
247 write!(f, "{byte:02X}")?;
248 }
249 Ok(())
250 }
251}
252
253#[derive(Debug, PartialEq, Eq, thiserror::Error)]
254pub enum Instantiate2AddressError {
255 InvalidChecksumLength,
257 InvalidSaltLength,
259}
260
261impl fmt::Display for Instantiate2AddressError {
262 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
263 match self {
264 Instantiate2AddressError::InvalidChecksumLength => write!(f, "invalid checksum length"),
265 Instantiate2AddressError::InvalidSaltLength => write!(f, "invalid salt length"),
266 }
267 }
268}
269
270pub fn instantiate2_address(
310 checksum: &[u8],
311 creator: &CanonicalAddr,
312 salt: &[u8],
313) -> Result<CanonicalAddr, Instantiate2AddressError> {
314 let msg = b"";
317 let len = 32;
318 instantiate2_address_impl(checksum, creator, salt, msg, len)
319}
320
321#[doc(hidden)]
354#[inline] pub fn instantiate2_address_impl(
356 checksum: &[u8],
357 creator: &CanonicalAddr,
358 salt: &[u8],
359 msg: &[u8],
360 len: usize,
361) -> Result<CanonicalAddr, Instantiate2AddressError> {
362 if checksum.len() != 32 {
363 return Err(Instantiate2AddressError::InvalidChecksumLength);
364 }
365
366 if salt.is_empty() || salt.len() > 64 {
367 return Err(Instantiate2AddressError::InvalidSaltLength);
368 };
369
370 let mut key = Vec::<u8>::new();
371 key.extend_from_slice(b"wasm\0");
372 key.extend_from_slice(&(checksum.len() as u64).to_be_bytes());
373 key.extend_from_slice(checksum);
374 key.extend_from_slice(&(creator.len() as u64).to_be_bytes());
375 key.extend_from_slice(creator);
376 key.extend_from_slice(&(salt.len() as u64).to_be_bytes());
377 key.extend_from_slice(salt);
378 key.extend_from_slice(&(msg.len() as u64).to_be_bytes());
379 key.extend_from_slice(msg);
380 let mut address_data = hash("module", &key);
381
382 if len != 32 {
386 debug_assert!(len <= 32);
387 debug_assert!(len > 0);
388 address_data.truncate(len);
389 }
390
391 Ok(address_data.into())
392}
393
394fn hash(ty: &str, key: &[u8]) -> Vec<u8> {
397 let inner = Sha256::digest(ty.as_bytes());
398 Sha256::new().chain(inner).chain(key).finalize().to_vec()
399}
400
401#[cfg(test)]
402mod tests {
403 use super::*;
404 use crate::assert_hash_works;
405 use crate::HexBinary;
406
407 use hex_literal::hex;
408
409 #[test]
410 fn addr_unchecked_works() {
411 let a = Addr::unchecked("123");
412 let aa = Addr::unchecked(String::from("123"));
413 let b = Addr::unchecked("be");
414 assert_eq!(a, aa);
415 assert_ne!(a, b);
416 }
417
418 #[test]
419 fn addr_as_str_works() {
420 let addr = Addr::unchecked("literal-string");
421 assert_eq!(addr.as_str(), "literal-string");
422 }
423
424 #[test]
425 fn addr_as_bytes_works() {
426 let addr = Addr::unchecked("literal-string");
427 assert_eq!(
428 addr.as_bytes(),
429 [108, 105, 116, 101, 114, 97, 108, 45, 115, 116, 114, 105, 110, 103]
430 );
431 }
432
433 #[test]
434 fn addr_implements_display() {
435 let addr = Addr::unchecked("cos934gh9034hg04g0h134");
436 let embedded = format!("Address: {addr}");
437 assert_eq!(embedded, "Address: cos934gh9034hg04g0h134");
438 assert_eq!(addr.to_string(), "cos934gh9034hg04g0h134");
439 }
440
441 #[test]
442 fn addr_implements_as_ref_for_str() {
443 let addr = Addr::unchecked("literal-string");
444 assert_eq!(addr.as_ref(), "literal-string");
445 }
446
447 #[test]
448 fn addr_implements_partial_eq_addr_ref() {
449 let addr = Addr::unchecked("cos934gh9034hg04g0h134");
450 let addr_ref = &addr;
451 let addr_ref2 = &addr;
452
453 assert_eq!(addr, addr_ref);
455 assert_eq!(addr_ref, addr);
457 assert_eq!(addr_ref, addr_ref2);
459 }
460
461 #[test]
462 fn addr_implements_into_string() {
463 let addr = Addr::unchecked("cos934gh9034hg04g0h134");
465 let string: String = addr.into();
466 assert_eq!(string, "cos934gh9034hg04g0h134");
467
468 let addr = Addr::unchecked("cos934gh9034hg04g0h134");
470 let addr_ref = &addr;
471 let string: String = addr_ref.into();
472 assert_eq!(string, "cos934gh9034hg04g0h134");
473 }
474
475 #[test]
477 fn canonical_addr_from_slice() {
478 let bytes: &[u8] = &[0u8, 187, 61, 11, 250, 0];
480 let canonical_addr_slice = CanonicalAddr::from(bytes);
481 assert_eq!(canonical_addr_slice.as_slice(), &[0u8, 187, 61, 11, 250, 0]);
482
483 let bytes: Vec<u8> = vec![0u8, 187, 61, 11, 250, 0];
485 let canonical_addr_vec = CanonicalAddr::from(bytes);
486 assert_eq!(canonical_addr_vec.as_slice(), &[0u8, 187, 61, 11, 250, 0]);
487 }
488
489 #[test]
490 fn canonical_addr_implements_partial_eq_with_binary() {
491 let addr = CanonicalAddr::from([1, 2, 3]);
492 let bin1 = Binary::from([1, 2, 3]);
493 let bin2 = Binary::from([42, 43]);
494
495 assert_eq!(addr, bin1);
496 assert_eq!(bin1, addr);
497 assert_ne!(addr, bin2);
498 assert_ne!(bin2, addr);
499 }
500
501 #[test]
502 fn canonical_addr_implements_partial_eq_with_hex_binary() {
503 let addr = CanonicalAddr::from([1, 2, 3]);
504 let bin1 = HexBinary::from([1, 2, 3]);
505 let bin2 = HexBinary::from([42, 43]);
506
507 assert_eq!(addr, bin1);
508 assert_eq!(bin1, addr);
509 assert_ne!(addr, bin2);
510 assert_ne!(bin2, addr);
511 }
512
513 #[test]
514 fn canonical_addr_implements_from_array() {
515 let array = [1, 2, 3];
516 let addr = CanonicalAddr::from(array);
517 assert_eq!(addr.as_slice(), [1, 2, 3]);
518
519 let array_ref = b"foo";
520 let addr = CanonicalAddr::from(array_ref);
521 assert_eq!(addr.as_slice(), [0x66, 0x6f, 0x6f]);
522 }
523
524 #[test]
525 fn canonical_addr_implements_from_and_to_vector() {
526 let original = vec![0u8, 187, 61, 11, 250, 0];
529 let original_ptr = original.as_ptr();
530 let addr: CanonicalAddr = original.into();
531 assert_eq!(addr.as_slice(), [0u8, 187, 61, 11, 250, 0]);
532 assert_eq!(
533 (addr.0).as_slice().as_ptr(),
534 original_ptr,
535 "must not be copied"
536 );
537
538 let original = vec![0u8, 187, 61, 11, 250, 0];
540 let original_ptr = original.as_ptr();
541 let addr = CanonicalAddr::from(original);
542 assert_eq!(addr.as_slice(), [0u8, 187, 61, 11, 250, 0]);
543 assert_eq!(
544 (addr.0).as_slice().as_ptr(),
545 original_ptr,
546 "must not be copied"
547 );
548
549 let original = CanonicalAddr::from(vec![0u8, 187, 61, 11, 250, 0]);
552 let original_ptr = (original.0).as_slice().as_ptr();
553 let vec: Vec<u8> = original.into();
554 assert_eq!(vec.as_slice(), [0u8, 187, 61, 11, 250, 0]);
555 assert_eq!(vec.as_ptr(), original_ptr, "must not be copied");
556
557 let original = CanonicalAddr::from(vec![7u8, 35, 49, 101, 0, 255]);
559 let original_ptr = (original.0).as_slice().as_ptr();
560 let vec = Vec::<u8>::from(original);
561 assert_eq!(vec.as_slice(), [7u8, 35, 49, 101, 0, 255]);
562 assert_eq!(vec.as_ptr(), original_ptr, "must not be copied");
563 }
564
565 #[test]
566 fn canonical_addr_implements_from_and_to_binary() {
567 let original = Binary::from([0u8, 187, 61, 11, 250, 0]);
569 let original_ptr = original.as_ptr();
570 let addr = CanonicalAddr::from(original);
571 assert_eq!(addr.as_slice(), [0u8, 187, 61, 11, 250, 0]);
572 assert_eq!(
573 (addr.0).as_slice().as_ptr(),
574 original_ptr,
575 "must not be copied"
576 );
577
578 let original = CanonicalAddr::from(vec![7u8, 35, 49, 101, 0, 255]);
580 let original_ptr = (original.0).as_slice().as_ptr();
581 let bin = Binary::from(original);
582 assert_eq!(bin.as_slice(), [7u8, 35, 49, 101, 0, 255]);
583 assert_eq!(bin.as_ptr(), original_ptr, "must not be copied");
584 }
585
586 #[test]
587 fn canonical_addr_implements_from_and_to_hex_binary() {
588 let original = HexBinary::from([0u8, 187, 61, 11, 250, 0]);
590 let original_ptr = original.as_ptr();
591 let addr = CanonicalAddr::from(original);
592 assert_eq!(addr.as_slice(), [0u8, 187, 61, 11, 250, 0]);
593 assert_eq!(
594 (addr.0).as_slice().as_ptr(),
595 original_ptr,
596 "must not be copied"
597 );
598
599 let original = CanonicalAddr::from(vec![7u8, 35, 49, 101, 0, 255]);
601 let original_ptr = (original.0).as_slice().as_ptr();
602 let bin = HexBinary::from(original);
603 assert_eq!(bin.as_slice(), [7u8, 35, 49, 101, 0, 255]);
604 assert_eq!(bin.as_ptr(), original_ptr, "must not be copied");
605 }
606
607 #[test]
608 fn canonical_addr_len() {
609 let bytes: &[u8] = &[0u8, 187, 61, 11, 250, 0];
610 let canonical_addr = CanonicalAddr::from(bytes);
611 assert_eq!(canonical_addr.len(), bytes.len());
612 }
613
614 #[test]
615 fn canonical_addr_is_empty() {
616 let bytes: &[u8] = &[0u8, 187, 61, 11, 250, 0];
617 let canonical_addr = CanonicalAddr::from(bytes);
618 assert!(!canonical_addr.is_empty());
619 let empty_canonical_addr = CanonicalAddr::from(vec![]);
620 assert!(empty_canonical_addr.is_empty());
621 }
622
623 #[test]
624 fn canonical_addr_implements_display() {
625 let bytes: &[u8] = &[
626 0x12, 0x03, 0xab, 0x00, 0xff,
631 ];
632 let address = CanonicalAddr::from(bytes);
633 let embedded = format!("Address: {address}");
634 assert_eq!(embedded, "Address: 1203AB00FF");
635 assert_eq!(address.to_string(), "1203AB00FF");
636 }
637
638 #[test]
639 fn canonical_addr_implements_deref() {
640 let bytes: &[u8] = &[0u8, 187, 61, 11, 250, 0];
642 let canonical_addr = CanonicalAddr::from(bytes);
643 assert_eq!(*canonical_addr, [0u8, 187, 61, 11, 250, 0]);
644
645 let bytes: &[u8] = &[0u8, 187, 61, 11, 250, 0];
647 let canonical_addr = CanonicalAddr::from(bytes);
648 assert_eq!(canonical_addr.len(), 6);
649 let canonical_addr_slice: &[u8] = &canonical_addr;
650 assert_eq!(canonical_addr_slice, &[0u8, 187, 61, 11, 250, 0]);
651 }
652
653 #[test]
656 fn canonical_addr_implements_hash_eq() {
657 let alice = CanonicalAddr::from([0, 187, 61, 11, 250, 0]);
658 let bob = CanonicalAddr::from([16, 21, 33, 0, 255, 9]);
659 assert_hash_works!(alice, bob);
660 }
661
662 fn flexible<'a>(a: impl Into<Cow<'a, Addr>>) -> String {
664 a.into().into_owned().to_string()
665 }
666
667 #[test]
668 fn addr_into_cow() {
669 let value = "wasmeucn0ur0ncny2308ry";
671 let addr = Addr::unchecked(value);
672
673 assert_eq!(value, &flexible(&addr));
675 assert_eq!(value, &flexible(addr));
677 }
678
679 #[test]
680 fn instantiate2_address_impl_works() {
681 let checksum1 =
682 HexBinary::from_hex("13a1fc994cc6d1c81b746ee0c0ff6f90043875e0bf1d9be6b7d779fc978dc2a5")
683 .unwrap();
684 let creator1 = CanonicalAddr::from(hex!("9999999999aaaaaaaaaabbbbbbbbbbcccccccccc"));
685 let salt1 = hex!("61");
686 let salt2 = hex!("aabbccddeeffffeeddbbccddaa66551155aaaabbcc787878789900aabbccddeeffffeeddbbccddaa66551155aaaabbcc787878789900aabbbbcc221100acadae");
687 let msg1: &[u8] = b"";
688 let msg2: &[u8] = b"{}";
689 let msg3: &[u8] = b"{\"some\":123,\"structure\":{\"nested\":[\"ok\",true]}}";
690
691 let expected = CanonicalAddr::from(hex!(
693 "5e865d3e45ad3e961f77fd77d46543417ced44d924dc3e079b5415ff6775f847"
694 ));
695 assert_eq!(
696 instantiate2_address_impl(&checksum1, &creator1, &salt1, msg1, 32).unwrap(),
697 expected
698 );
699
700 let expected = CanonicalAddr::from(hex!(
702 "0995499608947a5281e2c7ebd71bdb26a1ad981946dad57f6c4d3ee35de77835"
703 ));
704 assert_eq!(
705 instantiate2_address_impl(&checksum1, &creator1, &salt1, msg2, 32).unwrap(),
706 expected
707 );
708
709 let expected = CanonicalAddr::from(hex!(
711 "83326e554723b15bac664ceabc8a5887e27003abe9fbd992af8c7bcea4745167"
712 ));
713 assert_eq!(
714 instantiate2_address_impl(&checksum1, &creator1, &salt1, msg3, 32).unwrap(),
715 expected
716 );
717
718 let expected = CanonicalAddr::from(hex!(
720 "9384c6248c0bb171e306fd7da0993ec1e20eba006452a3a9e078883eb3594564"
721 ));
722 assert_eq!(
723 instantiate2_address_impl(&checksum1, &creator1, &salt2, b"", 32).unwrap(),
724 expected
725 );
726
727 let empty = Vec::<u8>::new();
729 assert!(matches!(
730 instantiate2_address_impl(&checksum1, &creator1, &empty, b"", 32).unwrap_err(),
731 Instantiate2AddressError::InvalidSaltLength
732 ));
733 let too_long = vec![0x11; 65];
734 assert!(matches!(
735 instantiate2_address_impl(&checksum1, &creator1, &too_long, b"", 32).unwrap_err(),
736 Instantiate2AddressError::InvalidSaltLength
737 ));
738
739 let broken_cs = hex!("13a1fc994cc6d1c81b746ee0c0ff6f90043875e0bf1d9be6b7d779fc978dc2");
741 assert!(matches!(
742 instantiate2_address_impl(&broken_cs, &creator1, &salt1, b"", 32).unwrap_err(),
743 Instantiate2AddressError::InvalidChecksumLength
744 ));
745 let broken_cs = hex!("");
746 assert!(matches!(
747 instantiate2_address_impl(&broken_cs, &creator1, &salt1, b"", 32).unwrap_err(),
748 Instantiate2AddressError::InvalidChecksumLength
749 ));
750 let broken_cs = hex!("13a1fc994cc6d1c81b746ee0c0ff6f90043875e0bf1d9be6b7d779fc978dc2aaaa");
751 assert!(matches!(
752 instantiate2_address_impl(&broken_cs, &creator1, &salt1, b"", 32).unwrap_err(),
753 Instantiate2AddressError::InvalidChecksumLength
754 ));
755 }
756
757 #[test]
758 fn instantiate2_address_impl_truncates_address_data_to_first_len_bytes() {
759 let checksum =
761 HexBinary::from_hex("13a1fc994cc6d1c81b746ee0c0ff6f90043875e0bf1d9be6b7d779fc978dc2a5")
762 .unwrap();
763 let creator = CanonicalAddr::from(hex!("9999999999aaaaaaaaaabbbbbbbbbbcccccccccc"));
764 let salt = hex!("61");
765
766 let data = [
767 (
768 32,
769 "5e865d3e45ad3e961f77fd77d46543417ced44d924dc3e079b5415ff6775f847",
770 ),
771 (
772 31,
773 "5e865d3e45ad3e961f77fd77d46543417ced44d924dc3e079b5415ff6775f8",
774 ),
775 (
776 30,
777 "5e865d3e45ad3e961f77fd77d46543417ced44d924dc3e079b5415ff6775",
778 ),
779 (21, "5e865d3e45ad3e961f77fd77d46543417ced44d924"),
780 (20, "5e865d3e45ad3e961f77fd77d46543417ced44d9"),
781 (19, "5e865d3e45ad3e961f77fd77d46543417ced44"),
782 (16, "5e865d3e45ad3e961f77fd77d4654341"),
783 (8, "5e865d3e45ad3e96"),
784 (1, "5e"),
785 ];
786
787 for (len, expected) in data {
788 let expected = CanonicalAddr::from(HexBinary::from_hex(expected).unwrap());
789 assert_eq!(
790 instantiate2_address_impl(&checksum, &creator, &salt, b"", len).unwrap(),
791 expected
792 );
793 }
794 }
795
796 #[test]
797 fn instantiate2_address_impl_matches_wasmd_for_len_24() {
798 let checksum =
805 HexBinary::from_hex("1122112211221122112211221122112211221122112211221122112211221122")
806 .unwrap();
807 let creator = CanonicalAddr::from(hex!("3333333333333333333333333333333333333333"));
808 let salt = hex!("aabbaabb");
809
810 let expected =
811 CanonicalAddr::from(hex!["da1aaec9d0ddc75b873079eb1b4f7ddd73a0e3170225fec4"]);
812 assert_eq!(
813 instantiate2_address_impl(&checksum, &creator, &salt, b"", 24).unwrap(),
814 expected
815 );
816 }
817
818 #[test]
819 fn instantiate2_address_impl_works_for_cosmjs_test_vectors() {
820 const COSMOS_ED25519_TESTS_JSON: &str = "./testdata/instantiate2_addresses.json";
822
823 #[derive(Deserialize, Debug)]
824 #[serde(rename_all = "camelCase")]
825 #[allow(dead_code)]
826 struct In {
827 checksum: HexBinary,
828 creator: String,
829 creator_data: HexBinary,
830 salt: HexBinary,
831 msg: Option<String>,
832 }
833
834 #[derive(Deserialize, Debug)]
835 #[serde(rename_all = "camelCase")]
836 #[allow(dead_code)]
837 struct Intermediate {
838 key: HexBinary,
839 address_data: HexBinary,
840 }
841
842 #[derive(Deserialize, Debug)]
843 #[serde(rename_all = "camelCase")]
844 #[allow(dead_code)]
845 struct Out {
846 address: String,
847 }
848
849 #[derive(Deserialize, Debug)]
850 #[allow(dead_code)]
851 struct Row {
852 #[serde(rename = "in")]
853 input: In,
854 intermediate: Intermediate,
855 out: Out,
856 }
857
858 fn read_tests() -> Vec<Row> {
859 use std::fs::File;
860 use std::io::BufReader;
861
862 let file = File::open(COSMOS_ED25519_TESTS_JSON).unwrap();
864 let reader = BufReader::new(file);
865
866 serde_json::from_reader(reader).unwrap()
867 }
868
869 for Row {
870 input,
871 intermediate,
872 out: _,
873 } in read_tests()
874 {
875 let msg = input.msg.map(|msg| msg.into_bytes()).unwrap_or_default();
876 let addr = instantiate2_address_impl(
877 &input.checksum,
878 &input.creator_data.into(),
879 &input.salt,
880 &msg,
881 32,
882 )
883 .unwrap();
884 assert_eq!(addr, intermediate.address_data);
885 }
886 }
887
888 #[test]
889 fn hash_works() {
890 let expected = [
892 195, 235, 23, 251, 9, 99, 177, 195, 81, 122, 182, 124, 36, 113, 245, 156, 76, 188, 221,
893 83, 181, 192, 227, 82, 100, 177, 161, 133, 240, 160, 5, 25,
894 ];
895 assert_eq!(hash("1", &[1]), expected);
896 }
897}