cfx_types/
address_util.rs

1use super::Address;
2use crate::{space_util::AddressSpaceUtil, AddressWithSpace};
3use keccak_hash::keccak;
4
5pub const TYPE_BITS_BUILTIN: u8 = 0x00;
6pub const TYPE_BITS_CONTRACT: u8 = 0x80;
7pub const TYPE_BITS_USER_ACCOUNT: u8 = 0x10;
8
9pub trait AddressUtil: Sized + Ord {
10    fn type_byte(&self) -> &u8;
11
12    fn type_byte_mut(&mut self) -> &mut u8;
13
14    fn is_null_address(&self) -> bool;
15
16    fn evm_map(&self) -> AddressWithSpace;
17
18    #[inline]
19    fn address_type_bits(&self) -> u8 { self.type_byte() & 0xf0 }
20
21    #[inline]
22    fn set_address_type_bits(&mut self, type_bits: u8) {
23        let type_byte = self.type_byte_mut();
24        *type_byte &= 0x0f;
25        *type_byte |= type_bits;
26    }
27
28    #[cfg(feature = "storage_benchmark_no_account_space_check")]
29    #[inline]
30    fn is_genesis_valid_address(&self) -> bool { true }
31
32    #[cfg(not(feature = "storage_benchmark_no_account_space_check"))]
33    #[inline]
34    fn is_genesis_valid_address(&self) -> bool {
35        self.is_contract_address()
36            || self.is_user_account_address()
37            || self.is_builtin_address()
38            || self.is_null_address()
39    }
40
41    #[inline]
42    fn is_contract_address(&self) -> bool {
43        self.address_type_bits() == TYPE_BITS_CONTRACT
44    }
45
46    #[inline]
47    fn is_user_account_address(&self) -> bool {
48        self.address_type_bits() == TYPE_BITS_USER_ACCOUNT
49    }
50
51    #[inline]
52    fn is_builtin_address(&self) -> bool {
53        self.address_type_bits() == TYPE_BITS_BUILTIN && !self.is_null_address()
54    }
55
56    #[inline]
57    fn set_contract_type_bits(&mut self) {
58        self.set_address_type_bits(TYPE_BITS_CONTRACT);
59    }
60
61    #[inline]
62    fn set_user_account_type_bits(&mut self) {
63        self.set_address_type_bits(TYPE_BITS_USER_ACCOUNT);
64    }
65}
66
67impl AddressUtil for Address {
68    #[inline]
69    fn type_byte(&self) -> &u8 { &self.as_fixed_bytes()[0] }
70
71    #[inline]
72    fn type_byte_mut(&mut self) -> &mut u8 { &mut self.as_fixed_bytes_mut()[0] }
73
74    #[inline]
75    fn is_null_address(&self) -> bool { self.is_zero() }
76
77    #[inline]
78    fn evm_map(&self) -> AddressWithSpace {
79        Address::from(keccak(&self)).with_evm_space()
80    }
81}
82
83impl AddressUtil for &[u8] {
84    #[inline]
85    fn type_byte(&self) -> &u8 { &self[0] }
86
87    #[inline]
88    fn type_byte_mut(&mut self) -> &mut u8 { unreachable!() }
89
90    #[inline]
91    fn is_null_address(&self) -> bool { self.iter().all(|&byte| byte == 0u8) }
92
93    #[inline]
94    fn evm_map(&self) -> AddressWithSpace {
95        Address::from(keccak(&self)).with_evm_space()
96    }
97}
98
99// parse hex string(support 0x prefix) to Address
100// Address::from_str does not support 0x prefix
101pub fn hex_to_address(hex_literal: &str) -> Result<Address, hex::FromHexError> {
102    let hex_literal = hex_literal.strip_prefix("0x").unwrap_or(hex_literal);
103    let raw_bytes = hex::decode(hex_literal)?;
104    Ok(Address::from_slice(&raw_bytes))
105}
106
107#[cfg(test)]
108mod tests {
109    use super::{hex_to_address, Address, AddressUtil};
110
111    #[test]
112    fn test_set_type_bits() {
113        let mut address = Address::default();
114
115        address.set_contract_type_bits();
116        assert!(address.is_contract_address());
117        assert!(!address.is_user_account_address());
118
119        address.set_user_account_type_bits();
120        assert!(address.is_user_account_address());
121
122        for types in 0..16 {
123            let type_bits = types << 4;
124            address.set_address_type_bits(type_bits);
125            assert_eq!(address.address_type_bits(), type_bits);
126        }
127    }
128
129    #[test]
130    fn test_address_util() {
131        let addr =
132            hex_to_address("0000000000000000000000000000000000000000").unwrap();
133        assert_eq!(addr, Address::zero());
134
135        let addr_err = hex_to_address("123");
136        assert!(addr_err.is_err());
137
138        let addr = hex_to_address("0x0000000000000000000000000000000000000000")
139            .unwrap();
140        assert_eq!(addr, Address::zero());
141
142        use std::str::FromStr;
143        let addr =
144            Address::from_str("1234567890AbcdEF1234567890aBcdef12345678")
145                .unwrap();
146        let addr2 =
147            hex_to_address("0x1234567890abcdef1234567890abcdef12345678")
148                .unwrap();
149        assert_eq!(addr, addr2);
150    }
151}