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 const TRUST_BACKED_ASSETS_PRECOMPILE_INDEX: u16;
312
313 const POOL_ASSETS_PRECOMPILE_INDEX: u16;
316
317 type AccountId: 'static
319 + scale::Codec
320 + scale::MaxEncodedLen
321 + CodecAsType
322 + Clone
323 + PartialEq
324 + Eq
325 + Ord
326 + AsRef<[u8]>
327 + AsMut<[u8]>;
328
329 type Balance: 'static
331 + scale::Codec
332 + CodecAsType
333 + Copy
334 + Clone
335 + PartialEq
336 + Eq
337 + AtLeast32BitUnsigned
338 + Into<U256>
339 + FromLittleEndian;
340
341 type Hash: 'static
343 + scale::Codec
344 + scale::MaxEncodedLen
345 + CodecAsType
346 + Copy
347 + Clone
348 + Clear
349 + PartialEq
350 + Eq
351 + Ord
352 + AsRef<[u8]>
353 + AsMut<[u8]>;
354
355 type Timestamp: 'static
357 + scale::Codec
358 + CodecAsType
359 + Copy
360 + Clone
361 + PartialEq
362 + Eq
363 + AtLeast32BitUnsigned
364 + FromLittleEndian;
365
366 type BlockNumber: 'static
368 + scale::Codec
369 + CodecAsType
370 + Copy
371 + Clone
372 + PartialEq
373 + Eq
374 + AtLeast32BitUnsigned
375 + FromLittleEndian;
376
377 type EventRecord: 'static + scale::Codec;
379
380 fn native_to_eth(value: Self::Balance) -> U256 {
390 value
391 .saturating_mul(Self::NATIVE_TO_ETH_RATIO.into())
392 .into()
393 }
394}
395
396#[derive(Debug, Clone, PartialEq, Eq)]
398#[cfg_attr(feature = "std", derive(TypeInfo))]
399pub enum DefaultEnvironment {}
400
401impl Environment for DefaultEnvironment {
402 const NATIVE_TO_ETH_RATIO: u32 = 100_000_000;
406
407 const TRUST_BACKED_ASSETS_PRECOMPILE_INDEX: u16 = 0x0120;
410 const POOL_ASSETS_PRECOMPILE_INDEX: u16 = 0x0320;
411
412 type AccountId = AccountId;
413 type Balance = Balance;
414 type Hash = Hash;
415 type Timestamp = Timestamp;
416 type BlockNumber = BlockNumber;
417 type EventRecord = EventRecord;
418}
419
420pub type Balance = u128;
422
423pub type Timestamp = u64;
425
426pub type Gas = u64;
428
429pub type BlockNumber = u32;
431
432#[derive(Encode, Decode, MaxEncodedLen, Debug)]
434pub struct RuntimeEvent();
435
436pub type EventRecord = EventRecordSpec<RuntimeEvent, Hash>;
438
439#[derive(Encode, Decode, Debug)]
440#[cfg_attr(feature = "std", derive(TypeInfo))]
441pub struct EventRecordSpec<E, H> {
442 pub phase: Phase,
444 pub event: E,
446 pub topics: ink_prelude::vec::Vec<H>,
448}
449
450#[derive(Debug, Encode, Decode, MaxEncodedLen)]
452#[cfg_attr(feature = "std", derive(PartialEq, Eq, Clone, TypeInfo))]
453pub enum Phase {
454 ApplyExtrinsic(u32),
456 Finalization,
458 Initialization,
460}
461
462#[derive(Clone, ::scale::Encode, ::scale::Decode, PartialEq)]
464#[cfg_attr(feature = "std", derive(::scale_info::TypeInfo))]
465pub enum Origin<E: Environment> {
466 Root,
467 Signed(E::AccountId),
468}
469
470pub struct AccountIdMapper {}
472impl AccountIdMapper {
473 pub fn to_address(account_id: &[u8]) -> Address {
474 let mut account_bytes: [u8; 32] = [0u8; 32];
475 account_bytes.copy_from_slice(&account_id[..32]);
476 if Self::is_eth_derived(account_id) {
477 Address::from_slice(&account_bytes[..20])
480 } else {
481 let account_hash = keccak_256(account_bytes.as_ref());
484 Address::from_slice(&account_hash[12..])
485 }
486 }
487
488 fn is_eth_derived(account_bytes: &[u8]) -> bool {
495 account_bytes[20..] == [0xEE; 12]
496 }
497}