cfx_types/
address_util.rs1use 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
99pub 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}