1use core::{
16 array::TryFromSliceError,
17 borrow::Borrow,
18};
19use derive_more::From;
20use primitive_types::{
21 H160,
22 U256,
23};
24use scale::{
25 Decode,
26 Encode,
27 MaxEncodedLen,
28};
29use sp_core::keccak_256;
30#[cfg(feature = "std")]
31use {
32 scale_decode::DecodeAsType,
33 scale_encode::EncodeAsType,
34 scale_info::TypeInfo,
35};
36
37use crate::arithmetic::{
38 AtLeast32BitUnsigned,
39 Saturating,
40};
41
42#[derive(
49 Debug,
50 Copy,
51 Clone,
52 PartialEq,
53 Eq,
54 Ord,
55 PartialOrd,
56 Hash,
57 Decode,
58 Encode,
59 MaxEncodedLen,
60 From,
61)]
62#[cfg_attr(feature = "std", derive(TypeInfo, DecodeAsType, EncodeAsType))]
63pub struct AccountId(pub [u8; 32]);
64
65impl AsRef<[u8; 32]> for AccountId {
66 #[inline]
67 fn as_ref(&self) -> &[u8; 32] {
68 &self.0
69 }
70}
71
72impl AsMut<[u8; 32]> for AccountId {
73 #[inline]
74 fn as_mut(&mut self) -> &mut [u8; 32] {
75 &mut self.0
76 }
77}
78
79impl AsRef<[u8]> for AccountId {
80 #[inline]
81 fn as_ref(&self) -> &[u8] {
82 &self.0[..]
83 }
84}
85
86impl AsMut<[u8]> for AccountId {
87 #[inline]
88 fn as_mut(&mut self) -> &mut [u8] {
89 &mut self.0[..]
90 }
91}
92
93impl<'a> TryFrom<&'a [u8]> for AccountId {
94 type Error = TryFromSliceError;
95
96 fn try_from(bytes: &'a [u8]) -> Result<Self, TryFromSliceError> {
97 let address = <[u8; 32]>::try_from(bytes)?;
98 Ok(Self(address))
99 }
100}
101
102impl Borrow<[u8; 32]> for AccountId {
103 fn borrow(&self) -> &[u8; 32] {
104 &self.0
105 }
106}
107
108pub type Address = H160;
116
117#[derive(
124 Debug,
125 Copy,
126 Clone,
127 PartialEq,
128 Eq,
129 Ord,
130 PartialOrd,
131 Hash,
132 Decode,
133 Encode,
134 MaxEncodedLen,
135 From,
136 Default,
137)]
138#[cfg_attr(feature = "std", derive(TypeInfo, DecodeAsType, EncodeAsType))]
139pub struct Hash([u8; 32]);
140
141impl<'a> TryFrom<&'a [u8]> for Hash {
142 type Error = TryFromSliceError;
143
144 fn try_from(bytes: &'a [u8]) -> Result<Self, TryFromSliceError> {
145 let hash = <[u8; 32]>::try_from(bytes)?;
146 Ok(Self(hash))
147 }
148}
149
150impl AsRef<[u8]> for Hash {
151 fn as_ref(&self) -> &[u8] {
152 &self.0[..]
153 }
154}
155
156impl AsMut<[u8]> for Hash {
157 fn as_mut(&mut self) -> &mut [u8] {
158 &mut self.0[..]
159 }
160}
161
162impl From<Hash> for [u8; 32] {
163 fn from(hash: Hash) -> Self {
164 hash.0
165 }
166}
167
168impl Borrow<[u8; 32]> for Hash {
169 fn borrow(&self) -> &[u8; 32] {
170 &self.0
171 }
172}
173
174pub trait Clear {
178 const CLEAR_HASH: Self;
180
181 fn is_clear(&self) -> bool;
183}
184
185impl Clear for [u8; 32] {
186 const CLEAR_HASH: Self = [0x00; 32];
187
188 fn is_clear(&self) -> bool {
189 self == &Self::CLEAR_HASH
190 }
191}
192
193impl Clear for Hash {
194 const CLEAR_HASH: Self = Self(<[u8; 32] as Clear>::CLEAR_HASH);
195
196 fn is_clear(&self) -> bool {
197 <[u8; 32] as Clear>::is_clear(&self.0)
198 }
199}
200
201pub trait FromLittleEndian {
212 type Bytes: Default + AsRef<[u8]> + AsMut<[u8]>;
214
215 fn from_le_bytes(bytes: Self::Bytes) -> Self;
217}
218
219impl FromLittleEndian for u8 {
220 type Bytes = [u8; 1];
221
222 #[inline]
223 fn from_le_bytes(bytes: Self::Bytes) -> Self {
224 u8::from_le_bytes(bytes)
225 }
226}
227
228impl FromLittleEndian for u16 {
229 type Bytes = [u8; 2];
230
231 #[inline]
232 fn from_le_bytes(bytes: Self::Bytes) -> Self {
233 u16::from_le_bytes(bytes)
234 }
235}
236
237impl FromLittleEndian for u32 {
238 type Bytes = [u8; 4];
239
240 #[inline]
241 fn from_le_bytes(bytes: Self::Bytes) -> Self {
242 u32::from_le_bytes(bytes)
243 }
244}
245
246impl FromLittleEndian for u64 {
247 type Bytes = [u8; 8];
248
249 #[inline]
250 fn from_le_bytes(bytes: Self::Bytes) -> Self {
251 u64::from_le_bytes(bytes)
252 }
253}
254
255impl FromLittleEndian for u128 {
256 type Bytes = [u8; 16];
257
258 #[inline]
259 fn from_le_bytes(bytes: Self::Bytes) -> Self {
260 u128::from_le_bytes(bytes)
261 }
262}
263
264impl FromLittleEndian for U256 {
265 type Bytes = [u8; 32];
266
267 #[inline]
268 fn from_le_bytes(bytes: Self::Bytes) -> Self {
269 U256::from_little_endian(&bytes)
270 }
272}
273
274pub trait AccountIdGuard {}
282
283impl AccountIdGuard for AccountId {}
286
287impl AccountIdGuard for Address {}
288
289cfg_if::cfg_if! {
290 if #[cfg(feature = "std")] {
291 pub trait CodecAsType: scale_decode::DecodeAsType + scale_encode::EncodeAsType {}
292 impl<T: scale_decode::DecodeAsType + scale_encode::EncodeAsType> CodecAsType for T {}
293 } else {
294 pub trait CodecAsType {}
295 impl<T> CodecAsType for T {}
296 }
297}
298
299pub trait Environment: Clone {
305 const NATIVE_TO_ETH_RATIO: u32;
308
309 type AccountId: 'static
311 + scale::Codec
312 + scale::MaxEncodedLen
313 + CodecAsType
314 + Clone
315 + PartialEq
316 + Eq
317 + Ord
318 + AsRef<[u8]>
319 + AsMut<[u8]>;
320
321 type Balance: 'static
323 + scale::Codec
324 + CodecAsType
325 + Copy
326 + Clone
327 + PartialEq
328 + Eq
329 + AtLeast32BitUnsigned
330 + Into<U256>
331 + FromLittleEndian;
332
333 type Hash: 'static
335 + scale::Codec
336 + scale::MaxEncodedLen
337 + CodecAsType
338 + Copy
339 + Clone
340 + Clear
341 + PartialEq
342 + Eq
343 + Ord
344 + AsRef<[u8]>
345 + AsMut<[u8]>;
346
347 type Timestamp: 'static
349 + scale::Codec
350 + CodecAsType
351 + Copy
352 + Clone
353 + PartialEq
354 + Eq
355 + AtLeast32BitUnsigned
356 + FromLittleEndian;
357
358 type BlockNumber: 'static
360 + scale::Codec
361 + CodecAsType
362 + Copy
363 + Clone
364 + PartialEq
365 + Eq
366 + AtLeast32BitUnsigned
367 + FromLittleEndian;
368
369 type EventRecord: 'static + scale::Codec;
371
372 fn native_to_eth(value: Self::Balance) -> U256 {
382 value
383 .saturating_mul(Self::NATIVE_TO_ETH_RATIO.into())
384 .into()
385 }
386}
387
388#[derive(Debug, Clone, PartialEq, Eq)]
390#[cfg_attr(feature = "std", derive(TypeInfo))]
391pub enum DefaultEnvironment {}
392
393impl Environment for DefaultEnvironment {
394 const NATIVE_TO_ETH_RATIO: u32 = 100_000_000;
398
399 type AccountId = AccountId;
400 type Balance = Balance;
401 type Hash = Hash;
402 type Timestamp = Timestamp;
403 type BlockNumber = BlockNumber;
404 type EventRecord = EventRecord;
405}
406
407pub type Balance = u128;
409
410pub type Timestamp = u64;
412
413pub type Gas = u64;
415
416pub type BlockNumber = u32;
418
419#[derive(Encode, Decode, MaxEncodedLen, Debug)]
421pub struct RuntimeEvent();
422
423pub type EventRecord = EventRecordSpec<RuntimeEvent, Hash>;
425
426#[derive(Encode, Decode, Debug)]
427#[cfg_attr(feature = "std", derive(TypeInfo))]
428pub struct EventRecordSpec<E, H> {
429 pub phase: Phase,
431 pub event: E,
433 pub topics: ink_prelude::vec::Vec<H>,
435}
436
437#[derive(Debug, Encode, Decode, MaxEncodedLen)]
439#[cfg_attr(feature = "std", derive(PartialEq, Eq, Clone, TypeInfo))]
440pub enum Phase {
441 ApplyExtrinsic(u32),
443 Finalization,
445 Initialization,
447}
448
449#[derive(Clone, ::scale::Encode, ::scale::Decode, PartialEq)]
451#[cfg_attr(feature = "std", derive(::scale_info::TypeInfo))]
452pub enum Origin<E: Environment> {
453 Root,
454 Signed(E::AccountId),
455}
456
457pub struct AccountIdMapper {}
459impl AccountIdMapper {
460 pub fn to_address(account_id: &[u8]) -> Address {
461 let mut account_bytes: [u8; 32] = [0u8; 32];
462 account_bytes.copy_from_slice(&account_id[..32]);
463 if Self::is_eth_derived(account_id) {
464 Address::from_slice(&account_bytes[..20])
467 } else {
468 let account_hash = keccak_256(account_bytes.as_ref());
471 Address::from_slice(&account_hash[12..])
472 }
473 }
474
475 fn is_eth_derived(account_bytes: &[u8]) -> bool {
482 account_bytes[20..] == [0xEE; 12]
483 }
484}