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

Allows to call one of the available defined chain extension methods.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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);
    }
}

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

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

Returns a copy of the value. Read more

Performs copy-assignment from source. Read more

Formats the value using the given formatter. Read more

Returns the “default value” for a type. Read more

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more

Immutably borrows from an owned value. Read more

Mutably borrows from an owned value. Read more

Returns the argument unchanged.

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Should always be Self

The resulting type after obtaining ownership.

Creates owned data from borrowed data, usually by cloning. Read more

🔬 This is a nightly-only experimental API. (toowned_clone_into)

Uses borrowed data to replace owned data, usually by cloning. Read more

The type returned in the event of a conversion error.

Performs the conversion.

The type returned in the event of a conversion error.

Performs the conversion.