pub struct EnvAccess<'a, E> { /* private fields */ }
Expand description
The API behind the self.env()
and Self::env()
syntax in ink!.
This allows ink! messages to make use of the environment efficiently and user friendly while also maintaining access invariants.
Implementations
sourceimpl<'a, E> EnvAccess<'a, E> where
E: Environment,
<E as Environment>::ChainExtension: ChainExtensionInstance,
impl<'a, E> EnvAccess<'a, E> where
E: Environment,
<E as Environment>::ChainExtension: ChainExtensionInstance,
sourcepub fn extension(
self
) -> <<E as Environment>::ChainExtension as ChainExtensionInstance>::Instance
pub fn extension(
self
) -> <<E as Environment>::ChainExtension as ChainExtensionInstance>::Instance
Allows to call one of the available defined chain extension methods.
sourceimpl<'a, E> EnvAccess<'a, E> where
E: Environment,
impl<'a, E> EnvAccess<'a, E> where
E: Environment,
sourcepub fn caller(self) -> E::AccountId
pub fn caller(self) -> E::AccountId
Returns the address of the caller of the executed contract.
Example
#[ink(message)]
pub fn call_me(&self) {
let caller = self.env().caller();
ink_env::debug_println!("got a call from {:?}", &caller);
}
Note
For more details visit: ink_env::caller
sourcepub fn transferred_value(self) -> E::Balance
pub fn transferred_value(self) -> E::Balance
Returns the transferred value for the contract execution.
Example
/// Allows funding the contract. Prints a debug message with the transferred value.
#[ink(message, payable)]
pub fn fund(&self) {
let caller = self.env().caller();
let value = self.env().transferred_value();
ink_env::debug_println!("thanks for the funding of {:?} from {:?}", value, caller);
}
Note
For more details visit: ink_env::transferred_value
sourcepub fn weight_to_fee(self, gas: u64) -> E::Balance
pub fn weight_to_fee(self, gas: u64) -> E::Balance
Returns the price for the specified amount of gas.
Example
/// Returns a tuple of
/// - the result of adding the `rhs` to the `lhs`
/// - the gas costs of this addition operation
/// - the price for the gas
#[ink(message)]
pub fn addition_gas_cost(&self, rhs: i32, lhs: i32) -> (i32, u64, Balance) {
let before = self.env().gas_left();
let result = rhs + lhs;
let after = self.env().gas_left();
let gas_used = after - before;
let gas_cost = self.env().weight_to_fee(gas_used);
(result, gas_used, gas_cost)
}
Note
For more details visit: ink_env::weight_to_fee
sourcepub fn gas_left(self) -> u64
pub fn gas_left(self) -> u64
Returns the amount of gas left for the contract execution.
Example
/// Returns a tuple of
/// - the result of adding the `rhs` to the `lhs` and
/// - the gas used for this addition operation.
#[ink(message)]
pub fn addition_gas_cost(&self, rhs: i32, lhs: i32) -> (i32, u64) {
let before = self.env().gas_left();
let result = rhs + lhs;
let after = self.env().gas_left();
(result, after - before)
}
Note
For more details visit: ink_env::gas_left
sourcepub fn block_timestamp(self) -> E::Timestamp
pub fn block_timestamp(self) -> E::Timestamp
Returns the timestamp of the current block.
Example
use ink_lang as ink;
#[ink::contract]
pub mod my_contract {
#[ink(storage)]
pub struct MyContract {
last_invocation: Timestamp
}
impl MyContract {
#[ink(constructor)]
pub fn new() -> Self {
Self {
last_invocation: Self::env().block_timestamp()
}
}
/// Records the last time the message was invoked.
#[ink(message)]
pub fn execute_me(&mut self) {
self.last_invocation = self.env().block_timestamp();
}
}
}
Note
The Substrate default for the timestamp type is the milliseconds since the Unix epoch. However, this is not guaranteed: the specific timestamp is defined by the chain environment on which this contract runs.
For more details visit: ink_env::block_timestamp
sourcepub fn account_id(self) -> E::AccountId
pub fn account_id(self) -> E::AccountId
Returns the account ID of the executed contract.
Example
use ink_lang as ink;
#[ink::contract]
pub mod only_owner {
#[ink(storage)]
pub struct OnlyOwner {
owner: AccountId,
value: u32,
}
impl OnlyOwner {
#[ink(constructor)]
pub fn new() -> Self {
Self {
owner: Self::env().caller(),
value: 0,
}
}
/// Allows incrementing the contract's `value` only
/// for the owner (i.e. the account which instantiated
/// this contract.
///
/// The contract panics if the caller is not the owner.
#[ink(message)]
pub fn increment(&mut self) {
let caller = self.env().caller();
assert!(self.owner == caller);
self.value = self.value + 1;
}
}
}
Note
For more details visit: ink_env::account_id
sourcepub fn balance(self) -> E::Balance
pub fn balance(self) -> E::Balance
Returns the balance of the executed contract.
Example
/// Returns the contract's balance.
#[ink(message)]
pub fn my_balance(&self) -> Balance {
self.env().balance()
}
Note
For more details visit: ink_env::balance
sourcepub fn block_number(self) -> E::BlockNumber
pub fn block_number(self) -> E::BlockNumber
Returns the current block number.
Example
use ink_lang as ink;
#[ink::contract]
pub mod my_contract {
#[ink(storage)]
pub struct MyContract {
last_invocation: BlockNumber
}
impl MyContract {
#[ink(constructor)]
pub fn new() -> Self {
Self {
last_invocation: Self::env().block_number()
}
}
/// The function can be executed at most once every 100 blocks.
#[ink(message)]
pub fn execute_me(&mut self) {
let now = self.env().block_number();
assert!(now - self.last_invocation > 100);
self.last_invocation = now;
}
}
}
Note
For more details visit: ink_env::block_number
sourcepub fn minimum_balance(self) -> E::Balance
pub fn minimum_balance(self) -> E::Balance
Returns the minimum balance that is required for creating an account (i.e. the chain’s existential deposit).
Example
#[ink(message)]
pub fn minimum_balance(&self) -> Balance {
self.env().minimum_balance()
}
Note
For more details visit: ink_env::minimum_balance
sourcepub fn instantiate_contract<Args, Salt, C>(
self,
params: &CreateParams<E, Args, Salt, C>
) -> Result<E::AccountId> where
Args: Encode,
Salt: AsRef<[u8]>,
pub fn instantiate_contract<Args, Salt, C>(
self,
params: &CreateParams<E, Args, Salt, C>
) -> Result<E::AccountId> where
Args: Encode,
Salt: AsRef<[u8]>,
Instantiates another contract.
Example
use ink_env::{
DefaultEnvironment,
call::{build_create, Selector, ExecutionInput}
};
use other_contract::OtherContractRef;
/// Instantiates another contract.
#[ink(message)]
pub fn instantiate_contract(&self) -> AccountId {
let create_params = build_create::<DefaultEnvironment, OtherContractRef>()
.code_hash(Hash::from([0x42; 32]))
.gas_limit(4000)
.endowment(25)
.exec_input(
ExecutionInput::new(Selector::new([0xCA, 0xFE, 0xBA, 0xBE]))
.push_arg(42)
.push_arg(true)
.push_arg(&[0x10u8; 32])
)
.salt_bytes(&[0xCA, 0xFE, 0xBA, 0xBE])
.params();
self.env().instantiate_contract(&create_params).expect("instantiation must succeed")
}
See our delegator
example
for a complete contract example.
Note
For more details visit: ink_env::instantiate_contract
sourcepub fn invoke_contract<Args, R>(
self,
params: &CallParams<E, Call<E>, Args, R>
) -> Result<R> where
Args: Encode,
R: Decode,
pub fn invoke_contract<Args, R>(
self,
params: &CallParams<E, Call<E>, Args, R>
) -> Result<R> where
Args: Encode,
R: Decode,
Invokes a contract message and returns its result.
Example
use ink_env::{
DefaultEnvironment,
call::{build_call, Call, Selector, ExecutionInput}
};
/// Invokes a contract message and fetches the result.
#[ink(message)]
pub fn invoke_contract(&self) -> i32 {
let call_params = build_call::<DefaultEnvironment>()
.call_type(
Call::new()
.callee(AccountId::from([0x42; 32]))
.gas_limit(5000)
.transferred_value(10))
.exec_input(
ExecutionInput::new(Selector::new([0xCA, 0xFE, 0xBA, 0xBE]))
.push_arg(42u8)
.push_arg(true)
.push_arg(&[0x10u8; 32])
)
.returns::<i32>()
.params();
self.env().invoke_contract(&call_params).expect("call invocation must succeed")
}
Note
For more details visit: ink_env::invoke_contract
sourcepub fn invoke_contract_delegate<Args, R>(
self,
params: &CallParams<E, DelegateCall<E>, Args, R>
) -> Result<R> where
Args: Encode,
R: Decode,
pub fn invoke_contract_delegate<Args, R>(
self,
params: &CallParams<E, DelegateCall<E>, Args, R>
) -> Result<R> where
Args: Encode,
R: Decode,
Invokes in delegate manner a code message and returns its result.
Example
use ink_env::{
DefaultEnvironment,
Clear,
call::{build_call, DelegateCall, Selector, ExecutionInput, utils::ReturnType}
};
/// Invokes in delegate manner a contract message and fetches the result.
#[ink(message)]
pub fn invoke_contract_delegate(&self) -> i32 {
let call_params = build_call::<DefaultEnvironment>()
.call_type(
DelegateCall::new()
.code_hash(<DefaultEnvironment as ink_env::Environment>::Hash::clear()))
.exec_input(
ExecutionInput::new(Selector::new([0xCA, 0xFE, 0xBA, 0xBE]))
.push_arg(42u8)
.push_arg(true)
.push_arg(&[0x10u8; 32])
)
.returns::<i32>()
.params();
self.env().invoke_contract_delegate(&call_params).expect("call delegate invocation must succeed")
}
Note
For more details visit: ink_env::invoke_contract_delegate
sourcepub fn terminate_contract(self, beneficiary: E::AccountId) -> !
pub fn terminate_contract(self, beneficiary: E::AccountId) -> !
Terminates the existence of a contract.
Example
/// Terminates with the caller as beneficiary.
#[ink(message)]
pub fn terminate_me(&mut self) {
self.env().terminate_contract(self.env().caller());
}
Note
For more details visit: ink_env::terminate_contract
sourcepub fn transfer(
self,
destination: E::AccountId,
value: E::Balance
) -> Result<()>
pub fn transfer(
self,
destination: E::AccountId,
value: E::Balance
) -> Result<()>
Transfers value from the contract to the destination account ID.
Example
/// Transfers the token amount ten to the caller.
#[ink(message)]
pub fn give_me_ten(&mut self) {
let value: Balance = 10;
self.env().transfer(self.env().caller(), value).expect("transfer failed");
}
Note
For more details visit: ink_env::transfer
sourcepub fn random(self, subject: &[u8]) -> (E::Hash, E::BlockNumber)
pub fn random(self, subject: &[u8]) -> (E::Hash, E::BlockNumber)
Returns a random hash seed.
Example
#[ink(message)]
pub fn random_bool(&self) -> bool {
let additional_randomness = b"seed";
let (hash, _block_number) = self.env().random(additional_randomness);
hash.as_ref()[0] != 0
}
Note
For more details visit: ink_env::random
sourcepub fn hash_bytes<H>(self, input: &[u8]) -> <H as HashOutput>::Type where
H: CryptoHash,
pub fn hash_bytes<H>(self, input: &[u8]) -> <H as HashOutput>::Type where
H: CryptoHash,
Computes the hash of the given bytes using the cryptographic hash H
.
Example
use ink_env::hash::{Sha2x256, HashOutput};
let input: &[u8] = &[13, 14, 15];
let mut output = <Sha2x256 as HashOutput>::Type::default(); // 256-bit buffer
let hash = ink_env::hash_bytes::<Sha2x256>(input, &mut output);
Note
For more details visit: ink_env::hash_bytes
sourcepub fn hash_encoded<H, V>(self, value: &V) -> <H as HashOutput>::Type where
H: CryptoHash,
V: Encode,
pub fn hash_encoded<H, V>(self, value: &V) -> <H as HashOutput>::Type where
H: CryptoHash,
V: Encode,
Computes the hash of the given SCALE encoded value using the cryptographic hash H
.
Example
use ink_env::hash::{Sha2x256, HashOutput};
let encodable = (42, "foo", true); // Implements `scale::Encode`
let mut output = <Sha2x256 as HashOutput>::Type::default(); // 256-bit buffer
ink_env::hash_encoded::<Sha2x256, _>(&encodable, &mut output);
const EXPECTED: [u8; 32] = [
243, 242, 58, 110, 205, 68, 100, 244, 187, 55, 188, 248, 29, 136, 145, 115,
186, 134, 14, 175, 178, 99, 183, 21, 4, 94, 92, 69, 199, 207, 241, 179,
];
assert_eq!(output, EXPECTED);
Note
For more details visit: ink_env::hash_encoded
sourcepub fn ecdsa_recover(
self,
signature: &[u8; 65],
message_hash: &[u8; 32]
) -> Result<ECDSAPublicKey>
pub fn ecdsa_recover(
self,
signature: &[u8; 65],
message_hash: &[u8; 32]
) -> Result<ECDSAPublicKey>
Recovers the compressed ECDSA public key for given signature
and message_hash
,
and stores the result in output
.
Example
/// Recovery from pre-defined signature and message hash
#[ink(message)]
pub fn ecdsa_recover(&self) {
const signature: [u8; 65] = [
161, 234, 203, 74, 147, 96, 51, 212, 5, 174, 231, 9, 142, 48, 137, 201,
162, 118, 192, 67, 239, 16, 71, 216, 125, 86, 167, 139, 70, 7, 86, 241,
33, 87, 154, 251, 81, 29, 160, 4, 176, 239, 88, 211, 244, 232, 232, 52,
211, 234, 100, 115, 230, 47, 80, 44, 152, 166, 62, 50, 8, 13, 86, 175,
28,
];
const message_hash: [u8; 32] = [
162, 28, 244, 179, 96, 76, 244, 178, 188, 83, 230, 248, 143, 106, 77, 117,
239, 95, 244, 171, 65, 95, 62, 153, 174, 166, 182, 28, 130, 73, 196, 208
];
let EXPECTED_COMPRESSED_PUBLIC_KEY: [u8; 33] = [
2, 121, 190, 102, 126, 249, 220, 187, 172, 85, 160, 98, 149, 206, 135, 11,
7, 2, 155, 252, 219, 45, 206, 40, 217, 89, 242, 129, 91, 22, 248, 23,
152,
].into();
let result = self.env().ecdsa_recover(&signature, &message_hash);
assert!(result.is_ok());
assert_eq!(result.unwrap().as_ref(), EXPECTED_COMPRESSED_PUBLIC_KEY.as_ref());
// Pass invalid zero message hash
let failed_result = self.env().ecdsa_recover(&signature, &[0; 32]);
assert!(failed_result.is_err());
if let Err(e) = failed_result {
assert_eq!(e, ink_env::Error::EcdsaRecoveryFailed);
}
}
sourcepub fn is_contract(self, account_id: &E::AccountId) -> bool
pub fn is_contract(self, account_id: &E::AccountId) -> bool
Checks whether a specified account belongs to a contract.
Example
#[ink(message)]
pub fn is_contract(&mut self, account_id: AccountId) -> bool {
self.env().is_contract(&account_id)
}
Note
For more details visit: ink_env::is_contract
sourcepub fn caller_is_origin(self) -> bool
pub fn caller_is_origin(self) -> bool
Checks whether the caller of the current contract is the origin of the whole call stack.
Example
#[ink(message)]
pub fn caller_is_origin(&mut self) -> bool {
self.env().caller_is_origin()
}
Note
For more details visit: ink_env::caller_is_origin
Trait Implementations
impl<'a, E: Copy> Copy for EnvAccess<'a, E>
Auto Trait Implementations
impl<'a, E> RefUnwindSafe for EnvAccess<'a, E>
impl<'a, E> Send for EnvAccess<'a, E>
impl<'a, E> Sync for EnvAccess<'a, E>
impl<'a, E> Unpin for EnvAccess<'a, E>
impl<'a, E> UnwindSafe for EnvAccess<'a, E>
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
impl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
sourceimpl<T> ToOwned for T where
T: Clone,
impl<T> ToOwned for T where
T: Clone,
type Owned = T
type Owned = T
The resulting type after obtaining ownership.
sourcefn clone_into(&self, target: &mut T)
fn clone_into(&self, target: &mut T)
toowned_clone_into
)Uses borrowed data to replace owned data, usually by cloning. Read more