use crate::{
call::{
Call,
CallParams,
ConstructorReturnType,
CreateParams,
DelegateCall,
FromAccountId,
},
event::Event,
hash::{
CryptoHash,
HashOutput,
},
Environment,
Result,
};
use ink_storage_traits::Storable;
#[derive(Default)]
pub struct ReturnFlags {
value: u32,
}
impl ReturnFlags {
pub fn new_with_reverted(has_reverted: bool) -> Self {
Self::default().set_reverted(has_reverted)
}
#[must_use]
pub fn set_reverted(mut self, has_reverted: bool) -> Self {
match has_reverted {
true => self.value |= has_reverted as u32,
false => self.value &= !has_reverted as u32,
}
self
}
#[cfg(not(feature = "std"))]
pub(crate) fn into_u32(self) -> u32 {
self.value
}
}
#[must_use]
#[derive(Copy, Clone, Debug, Default)]
pub struct CallFlags {
forward_input: bool,
clone_input: bool,
tail_call: bool,
allow_reentry: bool,
}
impl CallFlags {
pub const fn set_forward_input(mut self, forward_input: bool) -> Self {
self.forward_input = forward_input;
self
}
pub const fn set_clone_input(mut self, clone_input: bool) -> Self {
self.clone_input = clone_input;
self
}
pub const fn set_tail_call(mut self, tail_call: bool) -> Self {
self.tail_call = tail_call;
self
}
pub const fn set_allow_reentry(mut self, allow_reentry: bool) -> Self {
self.allow_reentry = allow_reentry;
self
}
pub(crate) const fn into_u32(self) -> u32 {
self.forward_input as u32
| ((self.clone_input as u32) << 1)
| ((self.tail_call as u32) << 2)
| ((self.allow_reentry as u32) << 3)
}
pub const fn forward_input(&self) -> bool {
self.forward_input
}
pub const fn clone_input(&self) -> bool {
self.clone_input
}
pub const fn tail_call(&self) -> bool {
self.tail_call
}
pub const fn allow_reentry(&self) -> bool {
self.allow_reentry
}
}
pub trait EnvBackend {
fn set_contract_storage<K, V>(&mut self, key: &K, value: &V) -> Option<u32>
where
K: scale::Encode,
V: Storable;
fn get_contract_storage<K, R>(&mut self, key: &K) -> Result<Option<R>>
where
K: scale::Encode,
R: Storable;
fn take_contract_storage<K, R>(&mut self, key: &K) -> Result<Option<R>>
where
K: scale::Encode,
R: Storable;
fn contains_contract_storage<K>(&mut self, key: &K) -> Option<u32>
where
K: scale::Encode;
fn clear_contract_storage<K>(&mut self, key: &K) -> Option<u32>
where
K: scale::Encode;
fn decode_input<T>(&mut self) -> Result<T>
where
T: scale::Decode;
fn return_value<R>(&mut self, flags: ReturnFlags, return_value: &R) -> !
where
R: scale::Encode;
fn debug_message(&mut self, content: &str);
fn hash_bytes<H>(&mut self, input: &[u8], output: &mut <H as HashOutput>::Type)
where
H: CryptoHash;
fn hash_encoded<H, T>(&mut self, input: &T, output: &mut <H as HashOutput>::Type)
where
H: CryptoHash,
T: scale::Encode;
fn ecdsa_recover(
&mut self,
signature: &[u8; 65],
message_hash: &[u8; 32],
output: &mut [u8; 33],
) -> Result<()>;
fn ecdsa_to_eth_address(
&mut self,
pubkey: &[u8; 33],
output: &mut [u8; 20],
) -> Result<()>;
fn sr25519_verify(
&mut self,
signature: &[u8; 64],
message: &[u8],
pub_key: &[u8; 32],
) -> Result<()>;
fn call_chain_extension<I, T, E, ErrorCode, F, D>(
&mut self,
func_id: u32,
input: &I,
status_to_result: F,
decode_to_result: D,
) -> ::core::result::Result<T, E>
where
I: scale::Encode,
T: scale::Decode,
E: From<ErrorCode>,
F: FnOnce(u32) -> ::core::result::Result<(), ErrorCode>,
D: FnOnce(&[u8]) -> ::core::result::Result<T, E>;
fn set_code_hash(&mut self, code_hash: &[u8]) -> Result<()>;
}
pub trait TypedEnvBackend: EnvBackend {
fn caller<E: Environment>(&mut self) -> E::AccountId;
fn transferred_value<E: Environment>(&mut self) -> E::Balance;
fn weight_to_fee<E: Environment>(&mut self, gas: u64) -> E::Balance;
fn gas_left<E: Environment>(&mut self) -> u64;
fn block_timestamp<E: Environment>(&mut self) -> E::Timestamp;
fn account_id<E: Environment>(&mut self) -> E::AccountId;
fn balance<E: Environment>(&mut self) -> E::Balance;
fn block_number<E: Environment>(&mut self) -> E::BlockNumber;
fn minimum_balance<E: Environment>(&mut self) -> E::Balance;
fn emit_event<E, Evt>(&mut self, event: Evt)
where
E: Environment,
Evt: Event;
fn invoke_contract<E, Args, R>(
&mut self,
call_data: &CallParams<E, Call<E>, Args, R>,
) -> Result<ink_primitives::MessageResult<R>>
where
E: Environment,
Args: scale::Encode,
R: scale::Decode;
fn invoke_contract_delegate<E, Args, R>(
&mut self,
call_data: &CallParams<E, DelegateCall<E>, Args, R>,
) -> Result<ink_primitives::MessageResult<R>>
where
E: Environment,
Args: scale::Encode,
R: scale::Decode;
fn instantiate_contract<E, ContractRef, Args, Salt, R>(
&mut self,
params: &CreateParams<E, ContractRef, Args, Salt, R>,
) -> Result<
ink_primitives::ConstructorResult<
<R as ConstructorReturnType<ContractRef>>::Output,
>,
>
where
E: Environment,
ContractRef: FromAccountId<E>,
Args: scale::Encode,
Salt: AsRef<[u8]>,
R: ConstructorReturnType<ContractRef>;
fn terminate_contract<E>(&mut self, beneficiary: E::AccountId) -> !
where
E: Environment;
fn transfer<E>(&mut self, destination: E::AccountId, value: E::Balance) -> Result<()>
where
E: Environment;
#[allow(clippy::wrong_self_convention)]
fn is_contract<E>(&mut self, account: &E::AccountId) -> bool
where
E: Environment;
fn caller_is_origin<E>(&mut self) -> bool
where
E: Environment;
fn code_hash<E>(&mut self, account: &E::AccountId) -> Result<E::Hash>
where
E: Environment;
fn own_code_hash<E>(&mut self) -> Result<E::Hash>
where
E: Environment;
fn call_runtime<E, Call>(&mut self, call: &Call) -> Result<()>
where
E: Environment,
Call: scale::Encode;
}