1use cbor_event::cbor;
2
3use super::*;
4use crate::{
5 address::{Address, AddressError},
6 crypto::BootstrapWitness,
7 genesis::network_info::NetworkInfo,
8};
9use cml_core::{
10 error::{DeserializeError, DeserializeFailure},
11 serialization::{Deserialize, ToBytes},
12};
13use cml_crypto::{
14 chain_crypto::{self, Sha3_256},
15 impl_hash_type, Bip32PrivateKey, Bip32PublicKey, CryptoError, Ed25519Signature,
16 LegacyDaedalusPrivateKey, PublicKey, RawBytesEncoding, TransactionHash,
17};
18use std::{convert::TryFrom, fmt};
19
20#[derive(Debug, thiserror::Error)]
21pub enum ByronAddressError {
22 #[error("UnknownNetwork: {0}")]
23 UnknownNetwork(ProtocolMagic),
24 #[error("InvalidCRC: found {found}, expected {expected}")]
25 InvalidCRC { found: Crc32, expected: Crc32 },
26}
27
28impl_hash_type!(AddressId, 28);
29impl_hash_type!(ByronScript, 32);
31impl_hash_type!(StakeholderId, 28);
32
33impl StakeholderId {
34 pub fn new(pubk: &Bip32PublicKey) -> StakeholderId {
35 let buf = cbor!(pubk.0.as_ref()).unwrap();
38
39 let hash = Sha3_256::new(&buf);
40 StakeholderId(Blake2b224::new(hash.as_ref()).into())
41 }
42}
43
44impl AddrAttributes {
45 pub fn new_bootstrap_era(
46 hdap: Option<HDAddressPayload>,
47 protocol_magic: Option<ProtocolMagic>,
48 ) -> Self {
49 let adjusted_magic = match &protocol_magic {
50 Some(magic) => {
51 if *magic == NetworkInfo::mainnet().protocol_magic() {
52 None
53 } else {
54 protocol_magic
55 }
56 }
57 None => None,
58 };
59 AddrAttributes {
60 derivation_path: hdap,
61 stake_distribution: Some(StakeDistribution::BootstrapEra),
62 protocol_magic: adjusted_magic,
63 }
64 }
65 pub fn new_single_key(
66 pubk: &Bip32PublicKey,
67 hdap: Option<HDAddressPayload>,
68 protocol_magic: ProtocolMagic,
69 ) -> Self {
70 AddrAttributes {
71 derivation_path: hdap,
72 stake_distribution: Some(StakeDistribution::new_single_key(StakeholderId::new(pubk))),
73 protocol_magic: Some(protocol_magic),
74 }
75 }
76}
77
78impl AddressId {
79 pub fn new(
80 addr_type: ByronAddrType,
81 spending_data: &SpendingData,
82 attrs: &AddrAttributes,
83 ) -> Self {
84 let addr_type_uint = addr_type as u32;
87 let buf = cbor!(&(&addr_type_uint, spending_data, attrs))
88 .expect("serialize the AddressId's digest data");
89
90 let hash = Sha3_256::new(&buf);
91 AddressId(*Blake2b224::new(hash.as_ref()).as_hash_bytes())
92 }
93}
94
95impl From<AddressContent> for ByronAddress {
96 fn from(content: AddressContent) -> Self {
97 let content_bytes = content.to_bytes();
98 let crc = super::crc32::crc32(&content_bytes).into();
99 ByronAddress { content, crc }
100 }
101}
102
103impl AddressContent {
104 pub fn hash_and_create(
105 addr_type: ByronAddrType,
106 spending_data: &SpendingData,
107 attributes: AddrAttributes,
108 ) -> AddressContent {
109 let address_id = AddressId::new(addr_type, spending_data, &attributes);
110 AddressContent::new(address_id, attributes, addr_type)
111 }
112
113 pub fn new_redeem(pubkey: PublicKey, protocol_magic: Option<ProtocolMagic>) -> Self {
115 let attributes = AddrAttributes::new_bootstrap_era(None, protocol_magic);
116 let addr_type = ByronAddrType::Redeem;
117 let spending_data = &SpendingData::new_spending_data_redeem(pubkey);
118
119 AddressContent::hash_and_create(addr_type, spending_data, attributes)
120 }
121
122 pub fn new_simple(xpub: Bip32PublicKey, protocol_magic: Option<ProtocolMagic>) -> Self {
124 let attributes = AddrAttributes::new_bootstrap_era(None, protocol_magic);
125 let addr_type = ByronAddrType::PublicKey;
126 let spending_data = SpendingData::new_spending_data_pub_key(xpub);
127
128 AddressContent::hash_and_create(addr_type, &spending_data, attributes)
129 }
130
131 pub fn to_address(&self) -> ByronAddress {
133 self.clone().into()
134 }
135
136 pub fn byron_protocol_magic(&self) -> ProtocolMagic {
139 match self.addr_attributes.protocol_magic {
140 Some(x) => x,
141 None => NetworkInfo::mainnet().protocol_magic(), }
143 }
144
145 pub fn network_id(&self) -> Result<u8, ByronAddressError> {
146 let protocol_magic = self.byron_protocol_magic();
157 if protocol_magic == NetworkInfo::mainnet().protocol_magic() {
158 Ok(NetworkInfo::mainnet().network_id())
159 } else if protocol_magic == NetworkInfo::testnet().protocol_magic()
160 || protocol_magic == NetworkInfo::preprod().protocol_magic()
161 || protocol_magic == NetworkInfo::preview().protocol_magic()
162 || protocol_magic == NetworkInfo::sancho_testnet().protocol_magic()
163 {
164 Ok(NetworkInfo::testnet().network_id())
165 } else {
166 Err(ByronAddressError::UnknownNetwork(protocol_magic))
167 }
168 }
169
170 pub fn icarus_from_key(key: Bip32PublicKey, protocol_magic: ProtocolMagic) -> AddressContent {
172 let filtered_protocol_magic = if protocol_magic == NetworkInfo::mainnet().protocol_magic() {
174 None
175 } else {
176 Some(protocol_magic)
177 };
178 AddressContent::new_simple(key, filtered_protocol_magic)
179 }
180
181 pub fn identical_with_pubkey(&self, xpub: Bip32PublicKey) -> bool {
183 let addr_type = ByronAddrType::PublicKey;
184 let spending_data = SpendingData::new_spending_data_pub_key(xpub);
185 let newea = AddressContent::hash_and_create(
186 addr_type,
187 &spending_data,
188 self.addr_attributes.clone(),
189 );
190
191 *self == newea
192 }
193}
194
195impl ByronAddress {
196 pub fn to_base58(&self) -> String {
197 base58::encode(&self.to_bytes())
198 }
199
200 pub fn from_base58(s: &str) -> Result<ByronAddress, ParseExtendedAddrError> {
201 let bytes = base58::decode(s).map_err(ParseExtendedAddrError::Base58Error)?;
202 Self::from_cbor_bytes(&bytes).map_err(ParseExtendedAddrError::DeserializeError)
204 }
206
207 pub fn is_valid(s: &str) -> bool {
208 use std::str::FromStr;
209 match ByronAddress::from_str(s) {
210 Ok(_v) => true,
211 Err(_err) => false,
212 }
213 }
214
215 pub fn to_address(self) -> Address {
216 self.into()
217 }
218
219 pub fn from_address(addr: &Address) -> Option<Self> {
220 match addr {
221 Address::Byron(byron) => Some(byron.clone()),
222 _ => None,
223 }
224 }
225}
226
227impl TryFrom<Address> for ByronAddress {
228 type Error = AddressError;
229
230 fn try_from(addr: Address) -> Result<Self, Self::Error> {
231 match addr {
232 Address::Byron(byron) => Ok(byron),
233 _ => Err(AddressError::WrongKind(addr.kind())),
234 }
235 }
236}
237
238impl From<ByronAddress> for Address {
239 fn from(byron: ByronAddress) -> Self {
240 Self::Byron(byron)
241 }
242}
243
244impl fmt::Display for ByronAddress {
245 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
246 write!(f, "{}", self.to_base58())
247 }
248}
249
250impl ::std::str::FromStr for ByronAddress {
251 type Err = ParseExtendedAddrError;
252 fn from_str(s: &str) -> Result<Self, Self::Err> {
253 Self::from_base58(s)
254 }
255}
256
257#[derive(Debug, thiserror::Error)]
258pub enum ParseExtendedAddrError {
259 #[error("Deserialize: {0:?}")]
260 DeserializeError(DeserializeError),
261 #[error("Base58: {0:?}")]
262 Base58Error(base58::Error),
263}
264
265pub fn make_daedalus_bootstrap_witness(
266 tx_body_hash: TransactionHash,
267 addr: ByronAddress,
268 key: LegacyDaedalusPrivateKey,
269) -> BootstrapWitness {
270 let chain_code = key.chaincode();
271
272 let pubkey = Bip32PublicKey::from_raw_bytes(key.as_ref().to_public().as_ref()).unwrap();
273 let vkey = pubkey.to_raw_key();
274 let signature =
275 Ed25519Signature::from_raw_bytes(key.as_ref().sign(&tx_body_hash.to_raw_bytes()).as_ref())
276 .unwrap();
277
278 BootstrapWitness::new(vkey, signature, chain_code, addr.content.addr_attributes).unwrap()
279}
280
281pub fn make_icarus_bootstrap_witness(
282 tx_body_hash: TransactionHash,
283 addr: ByronAddress,
284 key: &Bip32PrivateKey,
285) -> BootstrapWitness {
286 let chain_code = key.chaincode();
287
288 let raw_key = key.to_raw_key();
289 let vkey = raw_key.to_public();
290 let signature = raw_key.sign(tx_body_hash.to_raw_bytes());
291
292 BootstrapWitness::new(vkey, signature, chain_code, addr.content.addr_attributes).unwrap()
293}
294
295impl serde::Serialize for ByronAddress {
296 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
297 where
298 S: serde::Serializer,
299 {
300 serializer.serialize_str(&self.to_base58())
301 }
302}
303
304impl<'de> serde::de::Deserialize<'de> for ByronAddress {
305 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
306 where
307 D: serde::de::Deserializer<'de>,
308 {
309 let base58 = <String as serde::de::Deserialize>::deserialize(deserializer)?;
310 Self::from_base58(&base58).map_err(|_e| {
311 serde::de::Error::invalid_value(
312 serde::de::Unexpected::Str(&base58),
313 &"base58 byron address string",
314 )
315 })
316 }
317}
318
319impl schemars::JsonSchema for ByronAddress {
320 fn schema_name() -> String {
321 String::from("ByronAddress")
322 }
323 fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema {
324 String::json_schema(gen)
325 }
326 fn is_referenceable() -> bool {
327 String::is_referenceable()
328 }
329}
330
331#[cfg(test)]
332mod tests {
333 use super::ByronAddress;
334 use crate::genesis::network_info::NetworkInfo;
335 use cml_core::serialization::ToBytes;
336 use cml_crypto::{
337 chain_crypto::{self, Ed25519Bip32},
338 Deserialize,
339 };
340
341 fn assert_same_address(address: ByronAddress, xpub: chain_crypto::PublicKey<Ed25519Bip32>) {
342 assert!(
343 address.content.identical_with_pubkey(xpub.into()),
344 "{}",
345 "expected public key {xpub} to match address {address}",
346 )
347 }
348
349 #[test]
350 fn test_vector_1() {
351 let address: ByronAddress = "DdzFFzCqrhsrcTVhLygT24QwTnNqQqQ8mZrq5jykUzMveU26sxaH529kMpo7VhPrt5pwW3dXeB2k3EEvKcNBRmzCfcQ7dTkyGzTs658C".parse().unwrap();
352 let public_key = chain_crypto::PublicKey::<Ed25519Bip32>::from_binary(&[
353 0x6a, 0x50, 0x96, 0x89, 0xc6, 0x53, 0x17, 0x58, 0x65, 0x98, 0x5a, 0xd1, 0xe0, 0xeb,
354 0x5f, 0xf9, 0xad, 0xa6, 0x99, 0x7a, 0xa4, 0x03, 0xe6, 0x48, 0x61, 0x4b, 0x3b, 0x78,
355 0xfc, 0xba, 0x9c, 0x27, 0x30, 0x82, 0x28, 0xd9, 0x87, 0x2a, 0xf8, 0xb6, 0x5b, 0x98,
356 0x7f, 0xf2, 0x3e, 0x1a, 0x20, 0xcd, 0x90, 0xd8, 0x34, 0x6c, 0x31, 0xf0, 0xed, 0xb8,
357 0x99, 0x89, 0x52, 0xdc, 0x67, 0x66, 0x55, 0x80,
358 ])
359 .unwrap();
360 assert_same_address(address, public_key);
361 }
362
363 #[test]
364 fn test_vector_2() {
365 let address = "DdzFFzCqrht4it4GYgBp4J39FNnKBsPFejSppARXHCf2gGiTJcwXzpRvgDmxPvKQ8aZZmVqcLUz5L66a8Ja46pfKVtFRaKyn9eKdvpaC".parse().unwrap();
366 let public_key = chain_crypto::PublicKey::<Ed25519Bip32>::from_binary(&[
367 0xff, 0x7b, 0xf1, 0x29, 0x9d, 0xf3, 0xd7, 0x17, 0x98, 0xae, 0xfd, 0xc4, 0xae, 0xa7,
368 0xdb, 0x2f, 0x8d, 0xb7, 0x60, 0x46, 0x56, 0x94, 0x41, 0xea, 0xe5, 0x8b, 0x72, 0x23,
369 0xb6, 0x8b, 0x44, 0x04, 0x82, 0x15, 0xcb, 0xac, 0x94, 0xbc, 0xb7, 0xf2, 0xcf, 0x33,
370 0x6c, 0x6c, 0x18, 0xbc, 0x3e, 0x71, 0x3f, 0xfd, 0x82, 0x67, 0x59, 0x4f, 0xf6, 0x34,
371 0x93, 0x32, 0xce, 0x4f, 0x98, 0x04, 0xa7, 0xff,
372 ])
373 .unwrap();
374 assert_same_address(address, public_key)
375 }
376
377 #[test]
378 fn test_vector_3() {
379 let address = "DdzFFzCqrhsvNQtyViTvEdGxfdc5T1E5RorzFWjYodqjhFDy8fQxfDPccmTc4ePbvkiwvRkR8dtqQ1SHpH53fDSoxD17fo9f6WkRjjAA".parse().unwrap();
380 let public_key = chain_crypto::PublicKey::<Ed25519Bip32>::from_binary(&[
381 0x5c, 0x36, 0x51, 0xe0, 0xeb, 0x9d, 0x6d, 0xc9, 0x64, 0x07, 0x13, 0x7c, 0xcc, 0x1f,
382 0x37, 0x7a, 0x87, 0x94, 0x61, 0x77, 0xa5, 0x2c, 0xa3, 0x77, 0x2c, 0x6b, 0x4b, 0xeb,
383 0x72, 0x39, 0x50, 0xdc, 0x50, 0x22, 0x46, 0x68, 0x21, 0x8b, 0x8b, 0x36, 0x62, 0x02,
384 0xfe, 0x5b, 0x7d, 0x55, 0x6f, 0x50, 0x1c, 0x5c, 0x4e, 0x2d, 0x58, 0xe0, 0x54, 0x67,
385 0xe1, 0xab, 0xc0, 0x44, 0xc6, 0xc1, 0xbf, 0x8e,
386 ])
387 .unwrap();
388 assert_same_address(address, public_key)
389 }
390
391 #[test]
392 fn test_vector_4() {
393 let address = "DdzFFzCqrhsn7ZAhKy8mxkzW6G3wryM7K6bH38VAjE2FesJMxia3UviivMvGz146TP1FpDharxTE6nUgCCnZx2fmtKpmxAosg9Tf5b8y".parse().unwrap();
394 let public_key = chain_crypto::PublicKey::<Ed25519Bip32>::from_binary(&[
395 0xcd, 0x84, 0x2e, 0x01, 0x0d, 0x81, 0xa6, 0xbe, 0x1e, 0x16, 0x9f, 0xd6, 0x35, 0x21,
396 0xdb, 0xb9, 0x5f, 0x42, 0x41, 0xfc, 0x82, 0x3f, 0x45, 0xb1, 0xcf, 0x1a, 0x1c, 0xb4,
397 0xc5, 0x89, 0x57, 0x27, 0x1d, 0x4d, 0x14, 0x2a, 0x22, 0x94, 0xea, 0x5f, 0xa3, 0x16,
398 0xa4, 0xad, 0xbf, 0xcd, 0x59, 0x7a, 0x7c, 0x89, 0x6a, 0x52, 0xa9, 0xa3, 0xa9, 0xce,
399 0x49, 0x64, 0x4a, 0x10, 0x2d, 0x00, 0x71, 0x99,
400 ])
401 .unwrap();
402 assert_same_address(address, public_key)
403 }
404
405 #[test]
406 fn test_vector_5() {
407 let address = "DdzFFzCqrhssTCJf4sv664bdQURovAwzx1hNKkMkNLwMNyaxZFuPSDdZTTRMcoDyXHuCiZhbD4umvMJcWGkvFMMzBoBUW5UBdBbDqXGX".parse().unwrap();
408 let public_key = chain_crypto::PublicKey::<Ed25519Bip32>::from_binary(&[
409 0x5a, 0xac, 0x2d, 0xd0, 0xa8, 0xdc, 0x5d, 0x61, 0x0a, 0x4b, 0x6f, 0xdf, 0x3f, 0x5e,
410 0xf1, 0xb6, 0x4a, 0xcb, 0x76, 0xb1, 0xe8, 0x1f, 0x6a, 0x35, 0x70, 0x31, 0xfa, 0x19,
411 0xd5, 0xe6, 0x56, 0x9d, 0xcc, 0x37, 0xb7, 0xae, 0x6f, 0x39, 0x15, 0x82, 0xfb, 0x05,
412 0x4b, 0x72, 0xba, 0xda, 0x90, 0xab, 0x14, 0x6c, 0xdd, 0x01, 0x42, 0x0e, 0x4b, 0x40,
413 0x18, 0xf1, 0xa0, 0x55, 0x29, 0x82, 0xd2, 0x31,
414 ])
415 .unwrap();
416 assert_same_address(address, public_key)
417 }
418
419 #[test]
420 fn test_vector_6() {
421 let address = "DdzFFzCqrhsfi5fFjJUHYPSnfTYrnMohzh3PrrtrVQgwua33HWPKUdTJXo3o77pSGCmDNrjYaAiZmJddaPW9iHyUDatvU2WhX7MgnNMy".parse().unwrap();
422 let public_key = chain_crypto::PublicKey::<Ed25519Bip32>::from_binary(&[
423 0x2a, 0x6a, 0xd1, 0x51, 0x09, 0x96, 0xff, 0x2d, 0x10, 0x89, 0xcb, 0x8e, 0xd5, 0xf5,
424 0xc0, 0x61, 0xf6, 0xad, 0x0a, 0xfb, 0xb5, 0x3d, 0x95, 0x40, 0xa0, 0xfc, 0x89, 0xef,
425 0xc0, 0xa2, 0x63, 0xb9, 0x6d, 0xac, 0x00, 0xbd, 0x0d, 0x7b, 0xda, 0x7d, 0x16, 0x3a,
426 0x08, 0xdb, 0x20, 0xba, 0x64, 0xb6, 0x33, 0x4d, 0xca, 0x34, 0xea, 0xc8, 0x2c, 0xf7,
427 0xb4, 0x91, 0xc3, 0x5f, 0x5c, 0xae, 0xc7, 0xb0,
428 ])
429 .unwrap();
430 assert_same_address(address, public_key)
431 }
432
433 #[test]
434 fn test_vector_7() {
435 let address = "DdzFFzCqrhsy2zYMDQRCF4Nw34C3P7aT5B7JwHFQ6gLAeoHgVXurCLPCm3AeV1nTa1Nd46uDoNt16cnsPFkb4fpLi1J17AmvphCtGFz2".parse().unwrap();
436 let public_key = chain_crypto::PublicKey::<Ed25519Bip32>::from_binary(&[
437 0x0c, 0xd2, 0x15, 0x54, 0xa0, 0xf9, 0xb8, 0x25, 0x9c, 0x46, 0x88, 0xdd, 0x00, 0xfc,
438 0x01, 0x88, 0x43, 0x50, 0x79, 0x76, 0x4f, 0xa5, 0x50, 0xfb, 0x57, 0x38, 0x2b, 0xff,
439 0x43, 0xe2, 0xd8, 0xd8, 0x27, 0x27, 0x4e, 0x2a, 0x12, 0x9f, 0x86, 0xc3, 0x80, 0x88,
440 0x34, 0x37, 0x4d, 0xfe, 0x3f, 0xda, 0xa6, 0x28, 0x48, 0x30, 0xb8, 0xf6, 0xe4, 0x0d,
441 0x29, 0x93, 0xde, 0xa2, 0xfb, 0x0a, 0xbe, 0x82,
442 ])
443 .unwrap();
444 assert_same_address(address, public_key)
445 }
446
447 #[test]
448 fn test_vector_8() {
449 let address = "DdzFFzCqrht8ygB5pLM4uVbS2x4ek2NTDx6R3DJqP7fUaWEkx8RA9UFR8CHitp2R74XLDP876Pe3KLUByHnrWrKWnffpqPpm14rPCxeP".parse().unwrap();
450 let public_key = chain_crypto::PublicKey::<Ed25519Bip32>::from_binary(&[
451 0x1f, 0x0a, 0xb8, 0x33, 0xfd, 0xb1, 0xfa, 0x49, 0x58, 0xce, 0x74, 0x04, 0x81, 0x84,
452 0x5b, 0x3a, 0x26, 0x6e, 0xfa, 0xab, 0x2d, 0x65, 0xd1, 0x6b, 0xdd, 0x3d, 0xfe, 0x7f,
453 0xcb, 0xe4, 0x46, 0x30, 0x25, 0x9e, 0xd1, 0x91, 0x98, 0x93, 0x03, 0x9d, 0xfd, 0x40,
454 0x02, 0x4a, 0x72, 0x03, 0x45, 0x5b, 0x03, 0xd6, 0xd0, 0x0d, 0x0a, 0x5c, 0xd6, 0xee,
455 0x82, 0xde, 0x2e, 0xce, 0x73, 0x8a, 0xa1, 0xbf,
456 ])
457 .unwrap();
458 assert_same_address(address, public_key)
459 }
460
461 #[test]
462 fn test_vector_9() {
463 let address = "DdzFFzCqrhssTywqjv3dw3EakpEydWQcc3phQzR3YF9NPgQN9Ftkx68FfLLnpJ4vhWo9mAjx5EcpM1wNvorSySrpARZGfk5QugHkVs58".parse().unwrap();
464 let public_key = chain_crypto::PublicKey::<Ed25519Bip32>::from_binary(&[
465 0x16, 0xf7, 0xd2, 0x55, 0x32, 0x6d, 0x77, 0x6e, 0xc1, 0xb5, 0xed, 0xd2, 0x5f, 0x75,
466 0xd3, 0xe3, 0xeb, 0xe0, 0xb9, 0xd4, 0x9c, 0xdd, 0xb2, 0x46, 0xd8, 0x0c, 0xf4, 0x1b,
467 0x25, 0x24, 0x64, 0xb6, 0x24, 0x50, 0xa2, 0x4e, 0xf5, 0x98, 0x7b, 0x4b, 0xd6, 0x5e,
468 0x0d, 0x25, 0x23, 0x43, 0xab, 0xa8, 0xef, 0x77, 0x93, 0x34, 0x79, 0xde, 0xa8, 0xdd,
469 0xe2, 0x9e, 0xec, 0x56, 0xcc, 0x6a, 0xc0, 0x69,
470 ])
471 .unwrap();
472 assert_same_address(address, public_key)
473 }
474
475 #[test]
476 fn test_vector_10() {
477 let address = "DdzFFzCqrhsqTG4t3uq5UBqFrxhxGVM6bvF4q1QcZXqUpizFddEEip7dx5rbife2s9o2fRU3hVKhRp4higog7As8z42s4AMw6Pcu8vL4".parse().unwrap();
478 let public_key = chain_crypto::PublicKey::<Ed25519Bip32>::from_binary(&[
479 0x97, 0xb8, 0x6c, 0x69, 0xd1, 0x2a, 0xf1, 0x64, 0xdc, 0x87, 0xf2, 0x71, 0x26, 0x8f,
480 0x33, 0xbc, 0x4d, 0xee, 0xb0, 0xdf, 0xd3, 0x73, 0xc3, 0xfd, 0x3b, 0xac, 0xd4, 0x47,
481 0x53, 0xa3, 0x1d, 0xe7, 0x8f, 0x10, 0xe5, 0x55, 0x03, 0x7c, 0xd4, 0x00, 0x43, 0x6c,
482 0xcf, 0xd5, 0x38, 0x0d, 0xbb, 0xcd, 0x4d, 0x7c, 0x28, 0x0a, 0xef, 0x9e, 0xc7, 0x57,
483 0x4a, 0xe0, 0xac, 0xac, 0x0c, 0xf7, 0x9e, 0x89,
484 ])
485 .unwrap();
486 assert_same_address(address, public_key)
487 }
488
489 #[test]
490 fn byron_magic_parsing() {
491 let addr = ByronAddress::from_base58(
493 "Ae2tdPwUPEZ4YjgvykNpoFeYUxoyhNj2kg8KfKWN2FizsSpLUPv68MpTVDo",
494 )
495 .unwrap();
496 assert_eq!(
497 addr.content.byron_protocol_magic(),
498 NetworkInfo::mainnet().protocol_magic()
499 );
500 assert_eq!(
501 addr.content.network_id().unwrap(),
502 NetworkInfo::mainnet().network_id()
503 );
504
505 let addr = ByronAddress::from_base58(
507 "2cWKMJemoBaipzQe9BArYdo2iPUfJQdZAjm4iCzDA1AfNxJSTgm9FZQTmFCYhKkeYrede",
508 )
509 .unwrap();
510 assert_eq!(
511 addr.content.byron_protocol_magic(),
512 NetworkInfo::testnet().protocol_magic()
513 );
514 assert_eq!(
515 addr.content.network_id().unwrap(),
516 NetworkInfo::testnet().network_id()
517 );
518 }
519
520 #[test]
521 fn round_trip() {
522 let start = "DdzFFzCqrhsqTG4t3uq5UBqFrxhxGVM6bvF4q1QcZXqUpizFddEEip7dx5rbife2s9o2fRU3hVKhRp4higog7As8z42s4AMw6Pcu8vL4";
524 let addr = ByronAddress::from_base58(start).unwrap();
525 let end = addr.content.to_address().to_base58();
526 assert_eq!(start, end);
527
528 let start = "Ae2tdPwUPEZ4YjgvykNpoFeYUxoyhNj2kg8KfKWN2FizsSpLUPv68MpTVDo";
530 let addr = ByronAddress::from_base58(start).unwrap();
531 let end = addr.content.to_address().to_base58();
532 assert_eq!(start, end);
533
534 let start = "2cWKMJemoBaipzQe9BArYdo2iPUfJQdZAjm4iCzDA1AfNxJSTgm9FZQTmFCYhKkeYrede";
536 let addr = ByronAddress::from_base58(start).unwrap();
537 let end = addr.content.to_address().to_base58();
538 assert_eq!(start, end);
539
540 let start = "37btjrVyb4KEg6anTcJ9E4EAvYtNV9xXL6LNpA15YLhgvm9zJ1D2jwme574HikZ36rKdTwaUmpEicCoL1bDw4CtH5PNcFnTRGQNaFd5ai6Wvo6CZsi";
542 let addr = ByronAddress::from_base58(start).unwrap();
543 let end = addr.content.to_address().to_base58();
544 assert_eq!(start, end);
545 }
546
547 #[test]
548 fn parse_redeem_address() {
549 assert!(ByronAddress::is_valid(
550 "Ae2tdPwUPEZ3MHKkpT5Bpj549vrRH7nBqYjNXnCV8G2Bc2YxNcGHEa8ykDp"
551 ));
552 let byron_addr = ByronAddress::from_base58(
553 "Ae2tdPwUPEZ3MHKkpT5Bpj549vrRH7nBqYjNXnCV8G2Bc2YxNcGHEa8ykDp",
554 )
555 .unwrap();
556 assert_eq!(
557 byron_addr.to_base58(),
558 "Ae2tdPwUPEZ3MHKkpT5Bpj549vrRH7nBqYjNXnCV8G2Bc2YxNcGHEa8ykDp"
559 );
560 let byron_addr2 = ByronAddress::from_cbor_bytes(&byron_addr.to_bytes()).unwrap();
561 assert_eq!(
562 byron_addr2.to_base58(),
563 "Ae2tdPwUPEZ3MHKkpT5Bpj549vrRH7nBqYjNXnCV8G2Bc2YxNcGHEa8ykDp"
564 );
565 }
566}