1use crate::rlp::{Decodable, Encodable, RLPError};
4use crate::utils::keccak;
5use ethereum_types::Address as WrappedAddress;
6pub use secp256k1::{PublicKey, SecretKey as PrivateKey};
7#[cfg(feature = "serde")]
8use serde::{Deserialize, Serialize};
9use std::{
10 ops::{Deref, DerefMut},
11 str::FromStr,
12};
13
14#[cfg_attr(feature = "serde", serde_with::serde_as)]
15#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
16#[cfg_attr(feature = "serde", serde(remote = "ethereum_types::H160"))]
17struct _Address(#[cfg_attr(feature = "serde", serde_as(as = "crate::utils::unhex::Hex"))] [u8; 20]);
18
19#[cfg_attr(feature = "serde", serde_with::serde_as)]
21#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
22#[derive(Copy, Clone, Debug, PartialEq, Eq)]
23pub struct Address(#[cfg_attr(feature = "serde", serde_as(as = "_Address"))] WrappedAddress);
24
25impl DerefMut for Address {
26 fn deref_mut(&mut self) -> &mut WrappedAddress {
27 &mut self.0
28 }
29}
30impl Deref for Address {
31 type Target = WrappedAddress;
32
33 fn deref(&self) -> &Self::Target {
34 &self.0
35 }
36}
37impl Encodable for Address {
38 fn encode(&self, out: &mut dyn bytes::BufMut) {
39 self.0.encode(out)
40 }
41}
42impl Decodable for Address {
43 fn decode(buf: &mut &[u8]) -> Result<Self, RLPError> {
44 Ok(Self(WrappedAddress::decode(buf)?))
45 }
46}
47impl FromStr for Address {
48 type Err = rustc_hex::FromHexError;
49
50 fn from_str(s: &str) -> Result<Self, Self::Err> {
51 Ok(Self(WrappedAddress::from_str(s)?))
52 }
53}
54impl<T: Into<WrappedAddress>> From<T> for Address {
55 fn from(s: T) -> Self {
56 Self(s.into())
57 }
58}
59
60impl Address {
61 pub const WIDTH: usize = 20;
63
64 pub fn to_hex(&self) -> String {
65 format!("{:02x?}", self.0)
67 }
68
69 pub fn to_checksum_address(&self) -> String {
70 let body = self.to_hex();
73 let hash = keccak(&body.clone()[2..42]);
74
75 "0x".chars()
76 .chain(
77 body.chars()
78 .skip(2)
79 .zip(itertools::interleave(
80 hash.iter().map(|x| x >> 4),
81 hash.iter().map(|x| x & 15),
82 ))
83 .map(|(ch, h)| if h >= 8 { ch.to_ascii_uppercase() } else { ch }),
84 )
85 .collect()
86 }
87}
88
89pub trait AddressConvertible {
91 fn address(&self) -> Address;
93}
94
95impl AddressConvertible for secp256k1::PublicKey {
96 fn address(&self) -> Address {
97 let hash = keccak(&self.serialize_uncompressed()[1..]);
100 let suffix: [u8; 20] = hash[12..32].try_into().expect("Preset slice length");
102 Address(WrappedAddress::from_slice(&suffix))
103 }
104}