Repository: paritytech/ink
Pull request #797 (2021-05-26 02:01:51)

Add example usage comments to `EnvAccess` methods
Closes https://github.com/paritytech/ink/issues/644.

cmichi: I updated the PR, the code in the doc comment examples is compiled now. So please give it another round of review.

I briefly investigated using a proc. macro to reduce the code duplication, but quickly ran into issues with generating only part of a doc comment.
cmichi: @Robbepop I updated the PR, could you take another look please?

I experimented with a macro to reduce the code duplication in https://github.com/paritytech/ink/pull/797/commits/f7319126a8c1cdda67fa814f2863b570f3915e6d, but always ran into macro hygiene errors, which from my understanding are not easy to resolve.
Robbepop: > I experimented with a macro to reduce the code duplication in f731912, but always ran into macro hygiene errors, which from my understanding are not easy to resolve.

Yep, this is exactly what I expected unfortunately. I think for now we cannot do much about this.

Patch:
diff --git a/.config/cargo_spellcheck.dic b/.config/cargo_spellcheck.dic
index 9f385471ff..d001711c7c 100644
--- a/.config/cargo_spellcheck.dic
+++ b/.config/cargo_spellcheck.dic
@@ -1,71 +1,81 @@
 80
 
-WebAssembly
-Wasm
-Wasm32
-validator
-ERC
-fuzzer
-SHA
-BLAKE2
-KECCAK
 ABI
+AST
+BLAKE2
+DApp
+ERC
 FFI
+Gnosis
+KECCAK
+Polkadot
+RPC
+SHA
 UI
-crypto
-deploy
-layed
-dispatchable
-encodable
-decodable
+Wasm
+Wasm32
+WebAssembly
+adjunctive
+bitvector
+bitwise
 callee
-prefilled
-defrag
-defragmentation
-growable
 codegen
+const
+crypto
+cryptographic
 deallocate
 deallocation
-getter
-bitvector
+decodable
+decrement
+defrag
+defragmentation
+deploy
 dereferencing
-recurse
-kB
-scalability
-scalable
-adjunctive
-invariants
 deserializes
-DApp
-RPC
-AST
-untyped
-variadic
+dispatchable
+encodable
 evaluable
+fuzzer
+getter
+growable
+interoperate
+invariants
+kB
+layed
 multisig
-Gnosis
+multi
+postfix
+prefilled
+recurse
+refcount
+scalability
+scalable
 stdin
 stdout
-interoperate
-cryptographic
-Polkadot
-bitwise
+tuple
+unordered
+untyped
+validator
+variadic
 
+Django/S
+IP/S
+NFT/S
+accessor/S
+allocator/S
+backend/S
+blockchain/S
+defragment/SD
+encoding/S
+endian/P
+enum/S
 hasher/S
 hashmap/S
-vector/S
-vec/S
-enum/S
-struct/S
 instantiation/S
-allocator/S
-defragment/SD
 layout/JG
-endian/P
-accessor/S
-NFT/S
-encoding/S
-blockchain/S
-backend/S
 namespace/S
+parameterize/SD
 runtime/S
+struct/S
+vec/S
+vector/S
diff --git a/.config/cargo_spellcheck.toml b/.config/cargo_spellcheck.toml
index 58efcc5295..f5c0b7b3dc 100644
--- a/.config/cargo_spellcheck.toml
+++ b/.config/cargo_spellcheck.toml
@@ -3,6 +3,16 @@ lang = "en_US"
 search_dirs = ["."]
 extra_dictionaries = ["cargo_spellcheck.dic"]
 
+# If set to `true`, the OS specific default search paths are skipped and only explicitly
+# specified ones are used.
+skip_os_lookups = true
+
+# Use the builtin dictionaries if none were found in in the configured lookup paths.
+# Usually combined with `skip_os_lookups=true` to enforce the `builtin` usage for
+# consistent results across distributions and CI runs.  Setting this will still use the
+# dictionaries specified in `extra_dictionaries = [..]` for topic specific lingo.
+use_builtin = true
+
 [Hunspell.quirks]
 allow_concatenation = true
 allow_dashes = true
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index ce75f1c9c7..14b7b0aa03 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -153,12 +153,12 @@ spellcheck:
     stage:                           workspace
     <<:                              *docker-env
     script:
-        - cargo spellcheck check --cfg=.config/cargo_spellcheck.toml --checkers hunspell --code 1
+        - cargo spellcheck check -vvv --cfg=.config/cargo_spellcheck.toml --checkers hunspell --code 1
         - for example in examples/*/; do
-            cargo spellcheck check --cfg=.config/cargo_spellcheck.toml --checkers hunspell --code 1 ${example};
+            cargo spellcheck check -vvv --cfg=.config/cargo_spellcheck.toml --checkers hunspell --code 1 ${example};
           done
         - for contract in ${DELEGATOR_SUBCONTRACTS}; do
-            cargo spellcheck check --cfg=.config/cargo_spellcheck.toml --checkers hunspell --code 1 examples/delegator/${contract}/;
+            cargo spellcheck check -vvv --cfg=.config/cargo_spellcheck.toml --checkers hunspell --code 1 examples/delegator/${contract}/;
           done
 
 codecov:
diff --git a/crates/env/src/api.rs b/crates/env/src/api.rs
index ed69f42835..3a9081db16 100644
--- a/crates/env/src/api.rs
+++ b/crates/env/src/api.rs
@@ -90,7 +90,7 @@ where
 /// # Errors
 ///
 /// If the returned value cannot be properly decoded.
-pub fn gas_left<T>() -> Result<T::Balance>
+pub fn gas_left<T>() -> Result<u64>
 where
     T: Environment,
 {
@@ -436,7 +436,8 @@ pub fn restore_contract<T>(
     })
 }
 
-/// Terminates the existence of the currently executed smart contract.
+/// Terminates the existence of the currently executed smart contract
+/// without creating a tombstone.
 ///
 /// This removes the calling account and transfers all remaining balance
 /// to the given beneficiary.
@@ -561,6 +562,15 @@ pub fn debug_message(message: &str) {
 }
 
 /// Conducts the crypto hash of the given input and stores the result in `output`.
+///
+/// # 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);
+/// ```
 pub fn hash_bytes<H>(input: &[u8], output: &mut <H as HashOutput>::Type)
 where
     H: CryptoHash,
diff --git a/crates/env/src/backend.rs b/crates/env/src/backend.rs
index 150b7a8504..f4525b977f 100644
--- a/crates/env/src/backend.rs
+++ b/crates/env/src/backend.rs
@@ -203,7 +203,7 @@ pub trait TypedEnvBackend: EnvBackend {
     /// # Note
     ///
     /// For more details visit: [`gas_left`][`crate::gas_left`]
-    fn gas_left<T: Environment>(&mut self) -> Result<T::Balance>;
+    fn gas_left<T: Environment>(&mut self) -> Result<u64>;
 
     /// Returns the timestamp of the current block.
     ///
diff --git a/crates/env/src/call/call_builder.rs b/crates/env/src/call/call_builder.rs
index fc30223050..e3488755a3 100644
--- a/crates/env/src/call/call_builder.rs
+++ b/crates/env/src/call/call_builder.rs
@@ -302,6 +302,7 @@ mod seal {
     impl Sealed for () {}
     impl<T> Sealed for super::ReturnType<T> {}
 }
+
 /// Types that can be used in [`CallBuilder::returns`] to signal return type.
 pub trait IndicateReturnType: Default + self::seal::Sealed {}
 impl IndicateReturnType for () {}
diff --git a/crates/env/src/engine/experimental_off_chain/impls.rs b/crates/env/src/engine/experimental_off_chain/impls.rs
index 90f00e384f..171a630b9d 100644
--- a/crates/env/src/engine/experimental_off_chain/impls.rs
+++ b/crates/env/src/engine/experimental_off_chain/impls.rs
@@ -284,8 +284,8 @@ impl TypedEnvBackend for EnvInstance {
         self.get_property::<T::Balance>(Engine::value_transferred)
     }
 
-    fn gas_left<T: Environment>(&mut self) -> Result<T::Balance> {
-        self.get_property::<T::Balance>(Engine::gas_left)
+    fn gas_left<T: Environment>(&mut self) -> Result<u64> {
+        self.get_property::<u64>(Engine::gas_left)
     }
 
     fn block_timestamp<T: Environment>(&mut self) -> Result<T::Timestamp> {
diff --git a/crates/env/src/engine/off_chain/db/exec_context.rs b/crates/env/src/engine/off_chain/db/exec_context.rs
index 1d9a70ca56..ba1536dd52 100644
--- a/crates/env/src/engine/off_chain/db/exec_context.rs
+++ b/crates/env/src/engine/off_chain/db/exec_context.rs
@@ -37,7 +37,7 @@ pub struct ExecContext {
     /// The transferred value from caller to callee.
     pub transferred_value: OffBalance,
     /// The gas provided for the whole execution.
-    pub gas: OffBalance,
+    pub gas: u64,
     /// The inputs provided for the whole execution.
     ///
     /// # Note
@@ -82,11 +82,11 @@ impl ExecContext {
     }
 
     /// Returns the gas.
-    pub fn gas<T>(&self) -> Result<T::Balance>
+    pub fn gas<T>(&self) -> u64
     where
         T: Environment,
     {
-        self.gas.decode().map_err(Into::into)
+        self.gas
     }
 
     /// Returns the call data.
@@ -122,7 +122,7 @@ where
     /// The transferred value from caller to callee.
     transferred_value: Option<T::Balance>,
     /// The gas provided for the contract execution from caller to callee.
-    gas: Option<T::Balance>,
+    gas: Option<u64>,
     /// The inputs given to the contract execution.
     call_data: Option<CallData>,
 }
@@ -173,7 +173,7 @@ where
     /// # Panics
     ///
     /// If there has already been set provided gas.
-    pub fn gas(mut self, gas: T::Balance) -> Self {
+    pub fn gas(mut self, gas: u64) -> Self {
         if self.gas.is_some() {
             panic!("already has provided gas");
         }
@@ -223,7 +223,7 @@ where
             caller: TypedEncoded::new(&caller),
             callee: TypedEncoded::new(&callee),
             transferred_value: TypedEncoded::new(&transferred_value),
-            gas: TypedEncoded::new(&gas),
+            gas,
             call_data: self.call_data.unwrap(),
             output: None,
         }
diff --git a/crates/env/src/engine/off_chain/impls.rs b/crates/env/src/engine/off_chain/impls.rs
index 17909e7059..00a260777d 100644
--- a/crates/env/src/engine/off_chain/impls.rs
+++ b/crates/env/src/engine/off_chain/impls.rs
@@ -316,12 +316,11 @@ impl TypedEnvBackend for EnvInstance {
             .saturating_mul(gas.try_into().unwrap_or_else(|_| Bounded::max_value())))
     }
 
-    fn gas_left<T: Environment>(&mut self) -> Result<T::Balance> {
-        self.exec_context()
+    fn gas_left<T: Environment>(&mut self) -> Result<u64> {
+        Ok(self
+            .exec_context()
             .expect(UNINITIALIZED_EXEC_CONTEXT)
-            .gas::<T>()
-            .map_err(|_| scale::Error::from("could not decode gas left"))
-            .map_err(Into::into)
+            .gas::<T>())
     }
 
     fn block_timestamp<T: Environment>(&mut self) -> Result<T::Timestamp> {
diff --git a/crates/env/src/engine/off_chain/mod.rs b/crates/env/src/engine/off_chain/mod.rs
index 8df55ddfbb..6ff31e65d8 100644
--- a/crates/env/src/engine/off_chain/mod.rs
+++ b/crates/env/src/engine/off_chain/mod.rs
@@ -205,7 +205,7 @@ impl EnvInstance {
             ExecContext::build::<T>()
                 .caller(default_accounts.alice)
                 .callee(contract_account_id)
-                .gas(T::Balance::from(500_000u32))
+                .gas(500_000u64)
                 .transferred_value(T::Balance::from(500u32))
                 .call_data(CallData::new(Selector::new(selector_bytes_for_call)))
                 .finish(),
diff --git a/crates/env/src/engine/on_chain/impls.rs b/crates/env/src/engine/on_chain/impls.rs
index 6fd5809715..f5b801aa6f 100644
--- a/crates/env/src/engine/on_chain/impls.rs
+++ b/crates/env/src/engine/on_chain/impls.rs
@@ -309,8 +309,8 @@ impl TypedEnvBackend for EnvInstance {
         self.get_property::<T::Balance>(ext::value_transferred)
     }
 
-    fn gas_left<T: Environment>(&mut self) -> Result<T::Balance> {
-        self.get_property::<T::Balance>(ext::gas_left)
+    fn gas_left<T: Environment>(&mut self) -> Result<u64> {
+        self.get_property::<u64>(ext::gas_left)
     }
 
     fn block_timestamp<T: Environment>(&mut self) -> Result<T::Timestamp> {
diff --git a/crates/lang/Cargo.toml b/crates/lang/Cargo.toml
index 462057aeb7..97db22d95a 100644
--- a/crates/lang/Cargo.toml
+++ b/crates/lang/Cargo.toml
@@ -26,6 +26,10 @@ scale = { package = "parity-scale-codec", version = "2.1", default-features = fa
 derive_more = { version = "0.99", default-features = false, features = ["from"] }
 static_assertions = "1.1"
 
+[dev-dependencies]
+# required for the doctest of `env_access::EnvAccess::instantiate_contract`
+scale-info = { version = "0.6", default-features = false, features = ["derive"] }
+
 [features]
 default = ["std"]
 std = [
diff --git a/crates/lang/ir/src/ir/contract.rs b/crates/lang/ir/src/ir/contract.rs
index 056ce4feb3..f7533a8bb7 100644
--- a/crates/lang/ir/src/ir/contract.rs
+++ b/crates/lang/ir/src/ir/contract.rs
@@ -102,7 +102,7 @@ impl Contract {
     ///            types.
     /// - `storage-alloc`: If `true` enables the dynamic storage allocator
     ///                    facilities and code generation of the ink! smart
-    ///                    contract. Does incure some overhead. The default is
+    ///                    contract. Does incur some overhead. The default is
     ///                    `true`.
     /// - `as-dependency`: If `true` compiles this ink! smart contract always as
     ///                    if it was a dependency of another smart contract.
diff --git a/crates/lang/ir/src/ir/utils.rs b/crates/lang/ir/src/ir/utils.rs
index 81b3992245..51b2bd5b8d 100644
--- a/crates/lang/ir/src/ir/utils.rs
+++ b/crates/lang/ir/src/ir/utils.rs
@@ -16,7 +16,7 @@ use crate::format_err;
 use proc_macro2::Span;
 use syn::spanned::Spanned as _;
 
-/// Ensures that the given visibility is `pub` and anotherwise returns an appropriate error.
+/// Ensures that the given visibility is `pub` and otherwise returns an appropriate error.
 ///
 /// # Note
 ///
diff --git a/crates/lang/src/env_access.rs b/crates/lang/src/env_access.rs
index cff3ae743b..66924b9f20 100644
--- a/crates/lang/src/env_access.rs
+++ b/crates/lang/src/env_access.rs
@@ -112,6 +112,32 @@ where
 {
     /// Returns the address of the caller of the executed contract.
     ///
+    /// # Example
+    ///
+    /// ```
+    /// # use ink_lang as ink;
+    /// #
+    /// # #[ink::contract]
+    /// # pub mod my_contract {
+    /// #     #[ink(storage)]
+    /// #     pub struct MyContract { }
+    /// #
+    /// #     impl MyContract {
+    /// #         #[ink(constructor)]
+    /// #         pub fn new() -> Self {
+    /// #             Self {}
+    /// #         }
+    /// #
+    /// #[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`]
@@ -121,6 +147,34 @@ where
 
     /// Returns the transferred balance for the contract execution.
     ///
+    /// # Example
+    ///
+    /// ```
+    /// # use ink_lang as ink;
+    /// #
+    /// # #[ink::contract]
+    /// # pub mod my_contract {
+    /// #     #[ink(storage)]
+    /// #     pub struct MyContract { }
+    /// #
+    /// #     impl MyContract {
+    /// #         #[ink(constructor)]
+    /// #         pub fn new() -> Self {
+    /// #             Self {}
+    /// #         }
+    /// #
+    /// /// Allows funding the contract. Prints a debug message with the transferred balance.
+    /// #[ink(message, payable)]
+    /// pub fn fund(&self) {
+    ///     let caller = self.env().caller();
+    ///     let value = self.env().transferred_balance();
+    ///     ink_env::debug_println!("thanks for the funding of {:?} from {:?}", value, caller);
+    /// }
+    /// #
+    /// #     }
+    /// # }
+    /// ```
+    ///
     /// # Note
     ///
     /// For more details visit: [`ink_env::transferred_balance`]
@@ -130,6 +184,40 @@ where
 
     /// Returns the price for the specified amount of gas.
     ///
+    /// # Example
+    ///
+    /// ```
+    /// # use ink_lang as ink;
+    /// #
+    /// # #[ink::contract]
+    /// # pub mod my_contract {
+    /// #     #[ink(storage)]
+    /// #     pub struct MyContract { }
+    /// #
+    /// #     impl MyContract {
+    /// #         #[ink(constructor)]
+    /// #         pub fn new() -> Self {
+    /// #             Self {}
+    /// #         }
+    /// #
+    /// /// 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`]
@@ -139,15 +227,76 @@ where
 
     /// Returns the amount of gas left for the contract execution.
     ///
+    /// # Example
+    ///
+    /// ```
+    /// # use ink_lang as ink;
+    /// # #[ink::contract]
+    /// # pub mod my_contract {
+    /// #     #[ink(storage)]
+    /// #     pub struct MyContract { }
+    /// #
+    /// #     impl MyContract {
+    /// #         #[ink(constructor)]
+    /// #         pub fn new() -> Self {
+    /// #             Self {}
+    /// #         }
+    /// #
+    /// /// 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`]
-    pub fn gas_left(self) -> T::Balance {
+    pub fn gas_left(self) -> u64 {
         ink_env::gas_left::<T>().expect("couldn't decode 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()
+    ///             }
+    ///         }
+    ///
+    ///         /// The function can be executed at most once every 100 blocks.
+    ///         #[ink(message)]
+    ///         pub fn execute_me(&mut self) {
+    ///             let now = self.env().block_timestamp();
+    ///             assert!(now - self.last_invocation > 100);
+    ///             self.last_invocation = now;
+    ///         }
+    ///     }
+    /// }
+    /// ```
+    ///
     /// # Note
     ///
     /// For more details visit: [`ink_env::block_timestamp`]
@@ -157,6 +306,43 @@ where
 
     /// 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`]
@@ -166,6 +352,31 @@ where
 
     /// Returns the balance of the executed contract.
     ///
+    /// # Example
+    ///
+    /// ```
+    /// # use ink_lang as ink;
+    /// # #[ink::contract]
+    /// # pub mod my_contract {
+    /// #     #[ink(storage)]
+    /// #     pub struct MyContract { }
+    /// #
+    /// #     impl MyContract {
+    /// #         #[ink(constructor)]
+    /// #         pub fn new() -> Self {
+    /// #             Self {}
+    /// #         }
+    /// #
+    /// /// Returns the contract's balance.
+    /// #[ink(message)]
+    /// pub fn my_balance(&self) -> Balance {
+    ///     self.env().balance()
+    /// }
+    /// #
+    /// #     }
+    /// # }
+    /// ```
+    ///
     /// # Note
     ///
     /// For more details visit: [`ink_env::balance`]
@@ -175,6 +386,32 @@ where
 
     /// Returns the current rent allowance for the executed contract.
     ///
+    /// # Example
+    ///
+    /// ```
+    /// # use ink_lang as ink;
+    /// # #[ink::contract]
+    /// # pub mod my_contract {
+    /// #     #[ink(storage)]
+    /// #     pub struct MyContract { }
+    /// #
+    /// #     impl MyContract {
+    /// #         #[ink(constructor)]
+    /// #         pub fn new() -> Self {
+    /// #             Self {}
+    /// #         }
+    /// #
+    /// /// Returns the amount of the contract's balance which
+    /// /// can be used for paying rent.
+    /// #[ink(message)]
+    /// pub fn rent_allowance(&self) -> Balance {
+    ///     self.env().rent_allowance()
+    /// }
+    /// #
+    /// #     }
+    /// # }
+    /// ```
+    ///
     /// # Note
     ///
     /// For more details visit: [`ink_env::rent_allowance`]
@@ -182,8 +419,69 @@ where
         ink_env::rent_allowance::<T>().expect("couldn't decode contract rent allowance")
     }
 
+    /// Sets the rent allowance of the executed contract to the new value.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// # use ink_lang as ink;
+    /// # #[ink::contract]
+    /// # pub mod my_contract {
+    /// #     #[ink(storage)]
+    /// #     pub struct MyContract { }
+    /// #
+    /// #     impl MyContract {
+    /// #         #[ink(constructor)]
+    /// #         pub fn new() -> Self {
+    /// #             Self {}
+    /// #         }
+    /// #
+    /// /// Limits the amount of contract balance which can be used for paying rent
+    /// /// to half of the contract's total balance.
+    /// #[ink(message)]
+    /// pub fn limit_rent_allowance(&self) {
+    ///     self.env().set_rent_allowance(self.env().balance() / 2);
+    /// }
+    /// #
+    /// #     }
+    /// # }
+    /// ```
+    ///
+    /// # Note
+    ///
+    /// For more details visit: [`ink_env::set_rent_allowance`]
+    pub fn set_rent_allowance(self, new_value: T::Balance) {
+        ink_env::set_rent_allowance::<T>(new_value)
+    }
+
     /// Returns information needed for rent calculations.
     ///
+    /// # Example
+    ///
+    /// ```
+    /// # use ink_lang as ink;
+    /// # #[ink::contract]
+    /// # pub mod my_contract {
+    /// #     #[ink(storage)]
+    /// #     pub struct MyContract { }
+    /// #
+    /// #     impl MyContract {
+    /// #         #[ink(constructor)]
+    /// #         pub fn new() -> Self {
+    /// #             Self {}
+    /// #         }
+    /// #
+    /// /// Returns the balance every contract needs to deposit on this chain
+    /// /// to stay alive indefinitely.
+    /// #[ink(message)]
+    /// pub fn deposit_per_contract(&self) -> Balance {
+    ///     self.env().rent_params().deposit_per_contract
+    /// }
+    /// #
+    /// #     }
+    /// # }
+    /// ```
+    ///
     /// # Note
     ///
     /// For more details visit: [`ink_env::RentParams`]
@@ -214,6 +512,30 @@ where
 
     /// Returns the current block number.
     ///
+    /// # Example
+    ///
+    /// ```
+    /// # use ink_lang as ink;
+    /// # #[ink::contract]
+    /// # pub mod my_contract {
+    /// #     #[ink(storage)]
+    /// #     pub struct MyContract { }
+    /// #
+    /// #     impl MyContract {
+    /// #         #[ink(constructor)]
+    /// #         pub fn new() -> Self {
+    /// #             Self {}
+    /// #         }
+    /// #
+    /// #[ink(message)]
+    /// pub fn block_number(&self) -> BlockNumber {
+    ///     self.env().block_number()
+    /// }
+    /// #
+    /// #     }
+    /// # }
+    /// ```
+    ///
     /// # Note
     ///
     /// For more details visit: [`ink_env::block_number`]
@@ -223,6 +545,30 @@ where
 
     /// Returns the minimum balance that is required for creating an account.
     ///
+    /// # Example
+    ///
+    /// ```
+    /// # use ink_lang as ink;
+    /// # #[ink::contract]
+    /// # pub mod my_contract {
+    /// #     #[ink(storage)]
+    /// #     pub struct MyContract { }
+    /// #
+    /// #     impl MyContract {
+    /// #         #[ink(constructor)]
+    /// #         pub fn new() -> Self {
+    /// #             Self {}
+    /// #         }
+    /// #
+    /// #[ink(message)]
+    /// pub fn minimum_balance(&self) -> Balance {
+    ///     self.env().minimum_balance()
+    /// }
+    /// #
+    /// #     }
+    /// # }
+    /// ```
+    ///
     /// # Note
     ///
     /// For more details visit: [`ink_env::minimum_balance`]
@@ -232,6 +578,30 @@ where
 
     /// Returns the tombstone deposit for the contracts chain.
     ///
+    /// # Example
+    ///
+    /// ```
+    /// # use ink_lang as ink;
+    /// # #[ink::contract]
+    /// # pub mod my_contract {
+    /// #     #[ink(storage)]
+    /// #     pub struct MyContract { }
+    /// #
+    /// #     impl MyContract {
+    /// #         #[ink(constructor)]
+    /// #         pub fn new() -> Self {
+    /// #             Self {}
+    /// #         }
+    /// #
+    /// #[ink(message)]
+    /// pub fn tombstone_deposit(&self) -> Balance {
+    ///     self.env().tombstone_deposit()
+    /// }
+    /// #
+    /// #     }
+    /// # }
+    /// ```
+    ///
     /// # Note
     ///
     /// For more details visit: [`ink_env::tombstone_deposit`]
@@ -239,16 +609,132 @@ where
         ink_env::tombstone_deposit::<T>().expect("couldn't decode tombstone deposits")
     }
 
-    /// Sets the rent allowance of the executed contract to the new value.
+    /// Instantiates another contract.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// # use ink_lang as ink;
+    /// # #[ink::contract]
+    /// # pub mod my_contract {
+    /// #     use ink_lang as ink;
+    /// #     #[ink::contract(compile_as_dependency = true)]
+    /// #     pub mod other_contract {
+    /// #         #[ink(storage)]
+    /// #         pub struct OtherContract { }
+    /// #
+    /// #         impl OtherContract {
+    /// #             #[ink(constructor)]
+    /// #             pub fn new() -> Self {
+    /// #                 Self {}
+    /// #             }
+    /// #
+    /// #             #[ink(message)]
+    /// #             pub fn some_operation(&self) {
+    /// #                 // ...
+    /// #             }
+    /// #         }
+    /// #     }
+    /// #
+    /// use ink_env::{
+    ///     DefaultEnvironment,
+    ///     call::{build_create, Selector, ExecutionInput}
+    /// };
+    /// use other_contract::OtherContract;
+    /// #
+    /// #     #[ink(storage)]
+    /// #     pub struct MyContract { }
+    /// #
+    /// #     impl MyContract {
+    /// #         #[ink(constructor)]
+    /// #         pub fn new() -> Self {
+    /// #             Self {}
+    /// #         }
+    /// #
+    ///
+    /// /// Instantiates another contract.
+    /// #[ink(message)]
+    /// pub fn instantiate_contract(&self) -> AccountId {
+    ///     let create_params = build_create::<DefaultEnvironment, OtherContract>()
+    ///         .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](https://github.com/paritytech/ink/tree/master/examples/delegator)
+    /// for a complete contract example.
     ///
     /// # Note
     ///
-    /// For more details visit: [`ink_env::set_rent_allowance`]
-    pub fn set_rent_allowance(self, new_value: T::Balance) {
-        ink_env::set_rent_allowance::<T>(new_value)
+    /// For more details visit: [`ink_env::instantiate_contract`]
+    pub fn instantiate_contract<Args, Salt, C>(
+        self,
+        params: &CreateParams<T, Args, Salt, C>,
+    ) -> Result<T::AccountId>
+    where
+        Args: scale::Encode,
+        Salt: AsRef<[u8]>,
+    {
+        ink_env::instantiate_contract::<T, Args, Salt, C>(params)
     }
 
-    /// Invokes a contract message.
+    /// Invokes a contract message without fetching its result.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// # use ink_lang as ink;
+    /// # #[ink::contract]
+    /// # pub mod my_contract {
+    /// use ink_env::{
+    ///     DefaultEnvironment,
+    ///     call::{build_call, Selector, ExecutionInput}
+    /// };
+    ///
+    /// #
+    /// #     #[ink(storage)]
+    /// #     pub struct MyContract { }
+    /// #
+    /// #     impl MyContract {
+    /// #         #[ink(constructor)]
+    /// #         pub fn new() -> Self {
+    /// #             Self {}
+    /// #         }
+    /// #
+    /// /// Invokes another contract message without fetching the result.
+    /// #[ink(message)]
+    /// pub fn invoke_contract(&self) {
+    ///     let call_params = build_call::<DefaultEnvironment>()
+    ///         .callee(AccountId::from([0x42; 32]))
+    ///         .gas_limit(5000)
+    ///         .transferred_value(10)
+    ///         .exec_input(
+    ///             ExecutionInput::new(Selector::new([0xCA, 0xFE, 0xBA, 0xBE]))
+    ///                 .push_arg(42)
+    ///                 .push_arg(true)
+    ///                 .push_arg(&[0x10u8; 32])
+    ///         )
+    ///         .returns::<()>()
+    ///         .params();
+    ///     self.env().invoke_contract(&call_params).expect("call invocation must succeed");
+    /// }
+    /// #
+    /// #     }
+    /// # }
+    /// ```
     ///
     /// # Note
     ///
@@ -262,6 +748,49 @@ where
 
     /// Evaluates a contract message and returns its result.
     ///
+    /// # Example
+    ///
+    /// ```
+    /// # use ink_lang as ink;
+    /// # #[ink::contract]
+    /// # pub mod my_contract {
+    /// use ink_env::{
+    ///     DefaultEnvironment,
+    ///     call::{build_call, Selector, ExecutionInput, utils::ReturnType}
+    /// };
+    ///
+    /// #
+    /// #     #[ink(storage)]
+    /// #     pub struct MyContract { }
+    /// #
+    /// #     impl MyContract {
+    /// #         #[ink(constructor)]
+    /// #         pub fn new() -> Self {
+    /// #             Self {}
+    /// #         }
+    /// #
+    /// /// Evaluates a contract message and fetches the result.
+    /// #[ink(message)]
+    /// pub fn evaluate_contract(&self) -> i32 {
+    ///     let call_params = build_call::<DefaultEnvironment>()
+    ///         .callee(AccountId::from([0x42; 32]))
+    ///         .gas_limit(5000)
+    ///         .transferred_value(10)
+    ///         .exec_input(
+    ///             ExecutionInput::new(Selector::new([0xCA, 0xFE, 0xBA, 0xBE]))
+    ///                 .push_arg(42)
+    ///                 .push_arg(true)
+    ///                 .push_arg(&[0x10u8; 32])
+    ///         )
+    ///         .returns::<ReturnType<i32>>()
+    ///         .params();
+    ///     self.env().eval_contract(&call_params).expect("call invocation must succeed")
+    /// }
+    /// #
+    /// #     }
+    /// # }
+    /// ```
+    ///
     /// # Note
     ///
     /// For more details visit: [`ink_env::eval_contract`]
@@ -276,23 +805,37 @@ where
         ink_env::eval_contract::<T, Args, R>(params)
     }
 
-    /// Instantiates another contract.
-    ///
-    /// # Note
-    ///
-    /// For more details visit: [`ink_env::instantiate_contract`]
-    pub fn instantiate_contract<Args, Salt, C>(
-        self,
-        params: &CreateParams<T, Args, Salt, C>,
-    ) -> Result<T::AccountId>
-    where
-        Args: scale::Encode,
-        Salt: AsRef<[u8]>,
-    {
-        ink_env::instantiate_contract::<T, Args, Salt, C>(params)
-    }
-
-    /// Restores a smart contract in tombstone state.
+    /// Restores a smart contract from its tombstone state.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// # use ink_lang as ink;
+    /// # #[ink::contract]
+    /// # pub mod my_contract {
+    /// #     #[ink(storage)]
+    /// #     pub struct MyContract { }
+    /// #
+    /// #     impl MyContract {
+    /// #         #[ink(constructor)]
+    /// #         pub fn new() -> Self {
+    /// #             Self {}
+    /// #         }
+    /// #
+    /// /// Simple resurrection of a contract.
+    /// #[ink(message)]
+    /// pub fn resurrect(&self, contract: AccountId) {
+    ///     self.env().restore_contract(
+    ///         contract,
+    ///         Hash::from([0x42; 32]),
+    ///         1000,
+    ///         &[]
+    ///     )
+    /// }
+    /// #
+    /// #     }
+    /// # }
+    /// ```
     ///
     /// # Note
     ///
@@ -312,7 +855,32 @@ where
         )
     }
 
-    /// Terminates the existence of a smart contract.
+    /// Terminates the existence of a contract without creating a tombstone.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// # use ink_lang as ink;
+    /// # #[ink::contract]
+    /// # pub mod my_contract {
+    /// #     #[ink(storage)]
+    /// #     pub struct MyContract { }
+    /// #
+    /// #     impl MyContract {
+    /// #         #[ink(constructor)]
+    /// #         pub fn new() -> Self {
+    /// #             Self {}
+    /// #         }
+    /// #
+    /// /// Terminates with the caller as beneficiary.
+    /// #[ink(message)]
+    /// pub fn terminate_me(&mut self) {
+    ///     self.env().terminate_contract(self.env().caller());
+    /// }
+    /// #
+    /// #     }
+    /// # }
+    /// ```
     ///
     /// # Note
     ///
@@ -323,6 +891,32 @@ where
 
     /// Transfers value from the contract to the destination account ID.
     ///
+    /// # Example
+    ///
+    /// ```
+    /// # use ink_lang as ink;
+    /// # #[ink::contract]
+    /// # pub mod my_contract {
+    /// #     #[ink(storage)]
+    /// #     pub struct MyContract { }
+    /// #
+    /// #     impl MyContract {
+    /// #         #[ink(constructor)]
+    /// #         pub fn new() -> Self {
+    /// #             Self {}
+    /// #         }
+    /// #
+    /// /// 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`]
@@ -332,6 +926,32 @@ where
 
     /// Returns a random hash seed.
     ///
+    /// # Example
+    ///
+    /// ```
+    /// # use ink_lang as ink;
+    /// # #[ink::contract]
+    /// # pub mod my_contract {
+    /// #     #[ink(storage)]
+    /// #     pub struct MyContract { }
+    /// #
+    /// #     impl MyContract {
+    /// #         #[ink(constructor)]
+    /// #         pub fn new() -> Self {
+    /// #             Self {}
+    /// #         }
+    /// #
+    /// #[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`]
@@ -341,6 +961,16 @@ where
 
     /// 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`]
@@ -355,6 +985,22 @@ where
 
     /// 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`]
diff --git a/examples/dns/lib.rs b/examples/dns/lib.rs
index d3e6618a14..a59aa704e7 100644
--- a/examples/dns/lib.rs
+++ b/examples/dns/lib.rs
@@ -185,7 +185,7 @@ mod dns {
 
         const DEFAULT_CALLEE_HASH: [u8; 32] = [0x07; 32];
         const DEFAULT_ENDOWMENT: Balance = 1_000_000;
-        const DEFAULT_GAS_LIMIT: Balance = 1_000_000;
+        const DEFAULT_GAS_LIMIT: u64 = 1_000_000;
 
         fn default_accounts(
         ) -> ink_env::test::DefaultAccounts<ink_env::DefaultEnvironment> {


Test patch:
diff --git a/crates/env/src/engine/off_chain/test_api.rs b/crates/env/src/engine/off_chain/test_api.rs
index 0554e2e2b2..da2dce7215 100644
--- a/crates/env/src/engine/off_chain/test_api.rs
+++ b/crates/env/src/engine/off_chain/test_api.rs
@@ -44,7 +44,7 @@ use std::panic::UnwindSafe;
 pub fn push_execution_context<T>(
     caller: T::AccountId,
     callee: T::AccountId,
-    gas_limit: T::Balance,
+    gas_limit: u64,
     endowment: T::Balance,
     call_data: CallData,
 ) where
diff --git a/crates/lang/macro/tests/ui/pass/08-static-env.rs b/crates/lang/macro/tests/ui/pass/08-static-env.rs
index dcf71a39f9..80e967db2d 100644
--- a/crates/lang/macro/tests/ui/pass/08-static-env.rs
+++ b/crates/lang/macro/tests/ui/pass/08-static-env.rs
@@ -13,7 +13,7 @@ mod static_env {
         }
 
         #[ink(message)]
-        pub fn gas_left(&mut self) -> Balance {
+        pub fn gas_left(&mut self) -> u64 {
             Self::env().gas_left()
         }
     }