use core::{
array::TryFromSliceError,
borrow::Borrow,
};
use derive_more::From;
use primitive_types::{
H160,
U256,
};
use scale::{
Decode,
Encode,
MaxEncodedLen,
};
use sp_core::keccak_256;
#[cfg(feature = "std")]
use {
scale_decode::DecodeAsType,
scale_encode::EncodeAsType,
scale_info::TypeInfo,
};
use crate::arithmetic::AtLeast32BitUnsigned;
#[derive(
Debug,
Copy,
Clone,
PartialEq,
Eq,
Ord,
PartialOrd,
Hash,
Decode,
Encode,
MaxEncodedLen,
From,
)]
#[cfg_attr(feature = "std", derive(TypeInfo, DecodeAsType, EncodeAsType))]
pub struct AccountId(pub [u8; 32]);
impl AsRef<[u8; 32]> for AccountId {
#[inline]
fn as_ref(&self) -> &[u8; 32] {
&self.0
}
}
impl AsMut<[u8; 32]> for AccountId {
#[inline]
fn as_mut(&mut self) -> &mut [u8; 32] {
&mut self.0
}
}
impl AsRef<[u8]> for AccountId {
#[inline]
fn as_ref(&self) -> &[u8] {
&self.0[..]
}
}
impl AsMut<[u8]> for AccountId {
#[inline]
fn as_mut(&mut self) -> &mut [u8] {
&mut self.0[..]
}
}
impl<'a> TryFrom<&'a [u8]> for AccountId {
type Error = TryFromSliceError;
fn try_from(bytes: &'a [u8]) -> Result<Self, TryFromSliceError> {
let address = <[u8; 32]>::try_from(bytes)?;
Ok(Self(address))
}
}
impl Borrow<[u8; 32]> for AccountId {
fn borrow(&self) -> &[u8; 32] {
&self.0
}
}
pub type Address = H160;
#[derive(
Debug,
Copy,
Clone,
PartialEq,
Eq,
Ord,
PartialOrd,
Hash,
Decode,
Encode,
MaxEncodedLen,
From,
Default,
)]
#[cfg_attr(feature = "std", derive(TypeInfo, DecodeAsType, EncodeAsType))]
pub struct Hash([u8; 32]);
impl<'a> TryFrom<&'a [u8]> for Hash {
type Error = TryFromSliceError;
fn try_from(bytes: &'a [u8]) -> Result<Self, TryFromSliceError> {
let hash = <[u8; 32]>::try_from(bytes)?;
Ok(Self(hash))
}
}
impl AsRef<[u8]> for Hash {
fn as_ref(&self) -> &[u8] {
&self.0[..]
}
}
impl AsMut<[u8]> for Hash {
fn as_mut(&mut self) -> &mut [u8] {
&mut self.0[..]
}
}
impl From<Hash> for [u8; 32] {
fn from(hash: Hash) -> Self {
hash.0
}
}
impl Borrow<[u8; 32]> for Hash {
fn borrow(&self) -> &[u8; 32] {
&self.0
}
}
pub trait Clear {
const CLEAR_HASH: Self;
fn is_clear(&self) -> bool;
}
impl Clear for [u8; 32] {
const CLEAR_HASH: Self = [0x00; 32];
fn is_clear(&self) -> bool {
self == &Self::CLEAR_HASH
}
}
impl Clear for Hash {
const CLEAR_HASH: Self = Self(<[u8; 32] as Clear>::CLEAR_HASH);
fn is_clear(&self) -> bool {
<[u8; 32] as Clear>::is_clear(&self.0)
}
}
#[derive(Debug, Clone, Eq, PartialEq, Encode, Decode)]
#[cfg_attr(
feature = "std",
derive(
scale_info::TypeInfo,
EncodeAsType,
serde::Serialize,
serde::Deserialize
)
)]
pub enum DepositLimit<Balance> {
Unchecked,
Balance(Balance),
}
impl<T> From<T> for DepositLimit<T> {
fn from(value: T) -> Self {
Self::Balance(value)
}
}
pub trait FromLittleEndian {
type Bytes: Default + AsRef<[u8]> + AsMut<[u8]>;
fn from_le_bytes(bytes: Self::Bytes) -> Self;
}
impl FromLittleEndian for u8 {
type Bytes = [u8; 1];
#[inline]
fn from_le_bytes(bytes: Self::Bytes) -> Self {
u8::from_le_bytes(bytes)
}
}
impl FromLittleEndian for u16 {
type Bytes = [u8; 2];
#[inline]
fn from_le_bytes(bytes: Self::Bytes) -> Self {
u16::from_le_bytes(bytes)
}
}
impl FromLittleEndian for u32 {
type Bytes = [u8; 4];
#[inline]
fn from_le_bytes(bytes: Self::Bytes) -> Self {
u32::from_le_bytes(bytes)
}
}
impl FromLittleEndian for u64 {
type Bytes = [u8; 8];
#[inline]
fn from_le_bytes(bytes: Self::Bytes) -> Self {
u64::from_le_bytes(bytes)
}
}
impl FromLittleEndian for u128 {
type Bytes = [u8; 16];
#[inline]
fn from_le_bytes(bytes: Self::Bytes) -> Self {
u128::from_le_bytes(bytes)
}
}
impl FromLittleEndian for U256 {
type Bytes = [u8; 32];
#[inline]
fn from_le_bytes(bytes: Self::Bytes) -> Self {
U256::from_little_endian(&bytes)
}
}
pub trait AccountIdGuard {}
impl AccountIdGuard for AccountId {}
impl AccountIdGuard for Address {}
cfg_if::cfg_if! {
if #[cfg(feature = "std")] {
pub trait CodecAsType: scale_decode::DecodeAsType + scale_encode::EncodeAsType {}
impl<T: scale_decode::DecodeAsType + scale_encode::EncodeAsType> CodecAsType for T {}
} else {
pub trait CodecAsType {}
impl<T> CodecAsType for T {}
}
}
pub trait Environment: Clone {
const MAX_EVENT_TOPICS: usize;
type AccountId: 'static
+ scale::Codec
+ scale::MaxEncodedLen
+ CodecAsType
+ Clone
+ PartialEq
+ Eq
+ Ord
+ AsRef<[u8]>
+ AsMut<[u8]>;
type Balance: 'static
+ scale::Codec
+ CodecAsType
+ Copy
+ Clone
+ PartialEq
+ Eq
+ AtLeast32BitUnsigned
+ FromLittleEndian;
type Hash: 'static
+ scale::Codec
+ scale::MaxEncodedLen
+ CodecAsType
+ Copy
+ Clone
+ Clear
+ PartialEq
+ Eq
+ Ord
+ AsRef<[u8]>
+ AsMut<[u8]>;
type Timestamp: 'static
+ scale::Codec
+ CodecAsType
+ Copy
+ Clone
+ PartialEq
+ Eq
+ AtLeast32BitUnsigned
+ FromLittleEndian;
type BlockNumber: 'static
+ scale::Codec
+ CodecAsType
+ Copy
+ Clone
+ PartialEq
+ Eq
+ AtLeast32BitUnsigned
+ FromLittleEndian;
type ChainExtension;
type EventRecord: 'static + scale::Codec;
}
#[cfg_attr(feature = "std", derive(TypeInfo))]
pub enum NoChainExtension {}
#[derive(Debug, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "std", derive(TypeInfo))]
pub enum DefaultEnvironment {}
impl Environment for DefaultEnvironment {
const MAX_EVENT_TOPICS: usize = 4;
type AccountId = AccountId;
type Balance = Balance;
type Hash = Hash;
type Timestamp = Timestamp;
type BlockNumber = BlockNumber;
type ChainExtension = NoChainExtension;
type EventRecord = EventRecord;
}
pub type Balance = u128;
pub type Timestamp = u64;
pub type Gas = u64;
pub type BlockNumber = u32;
#[derive(Encode, Decode, MaxEncodedLen, Debug)]
pub struct RuntimeEvent();
pub type EventRecord = EventRecordSpec<RuntimeEvent, Hash>;
#[derive(Encode, Decode, Debug)]
#[cfg_attr(feature = "std", derive(TypeInfo))]
pub struct EventRecordSpec<E, H> {
pub phase: Phase,
pub event: E,
pub topics: ink_prelude::vec::Vec<H>,
}
#[derive(Debug, Encode, Decode, MaxEncodedLen)]
#[cfg_attr(feature = "std", derive(PartialEq, Eq, Clone, TypeInfo))]
pub enum Phase {
ApplyExtrinsic(u32),
Finalization,
Initialization,
}
#[derive(Clone, ::scale::Encode, ::scale::Decode, PartialEq)]
#[cfg_attr(feature = "std", derive(::scale_info::TypeInfo))]
pub enum Origin<E: Environment> {
Root,
Signed(E::AccountId),
}
pub struct AccountIdMapper {}
impl AccountIdMapper {
pub fn to_address(account_id: &[u8]) -> Address {
let mut account_bytes: [u8; 32] = [0u8; 32];
account_bytes.copy_from_slice(&account_id[..32]);
if Self::is_eth_derived(account_id) {
Address::from_slice(&account_bytes[..20])
} else {
let account_hash = keccak_256(account_bytes.as_ref());
Address::from_slice(&account_hash[12..])
}
}
fn is_eth_derived(account_bytes: &[u8]) -> bool {
account_bytes[20..] == [0xEE; 12]
}
}