diff --git a/README.md b/README.md index d34e57aaa0a..22b6273ac68 100644 --- a/README.md +++ b/README.md @@ -228,7 +228,7 @@ See [here](https://paritytech.github.io/ink/ink_lang/attr.contract.html) for a m ### Trait Definitions -Use`#[ink::trait_definition]` to define your very own trait definitions that are then implementable by ink! smart contracts. +Use `#[ink::trait_definition]` to define your very own trait definitions that are then implementable by ink! smart contracts. See e.g. the [`examples/trait-erc20`](https://github.com/paritytech/ink/blob/master/examples/trait-erc20/lib.rs#L49-L51) contract on how to utilize it or [the documentation](https://paritytech.github.io/ink/ink_lang/attr.trait_definition.html) for details. ### Off-chain Testing diff --git a/crates/env/src/engine/off_chain/test_api.rs b/crates/env/src/engine/off_chain/test_api.rs index da2dce7215e..ff3e9c8236c 100644 --- a/crates/env/src/engine/off_chain/test_api.rs +++ b/crates/env/src/engine/off_chain/test_api.rs @@ -14,18 +14,18 @@ //! Operations on the off-chain testing environment. -use super::{ +pub use super::{ chain_extension::ChainExtension, + db::ChainSpec, + CallData, + EmittedEvent, +}; +use super::{ db::ExecContext, AccountError, EnvInstance, OnInstance, }; -pub use super::{ - db::ChainSpec, - CallData, - EmittedEvent, -}; use crate::{ Environment, Result, diff --git a/examples/rand-extension/lib.rs b/examples/rand-extension/lib.rs index 9c045880ac1..3ee7dd65792 100755 --- a/examples/rand-extension/lib.rs +++ b/examples/rand-extension/lib.rs @@ -17,10 +17,11 @@ use ink_env::Environment; use ink_lang as ink; -/// This is an example of how ink! contract should -/// call substrate runtime `RandomnessCollectiveFlip::random_seed`. - -/// Define the operations to interact with the substrate runtime +/// This is an example of how an ink! contract may call the Substrate +/// runtime function `RandomnessCollectiveFlip::random_seed`. See the +/// file `runtime/chain-extension-example.rs` for that implementation. +/// +/// Here we define the operations to interact with the Substrate runtime. #[ink::chain_extension] pub trait FetchRandom { type ErrorCode = RandomReadErr; @@ -69,8 +70,9 @@ impl Environment for CustomEnvironment { mod rand_extension { use super::RandomReadErr; - /// Defines the storage of your contract. - /// Here we store the random seed fetched from the chain + /// Defines the storage of our contract. + /// + /// Here we store the random seed fetched from the chain. #[ink(storage)] pub struct RandExtension { /// Stores a single `bool` value on the storage. @@ -92,19 +94,19 @@ mod rand_extension { /// Constructor that initializes the `bool` value to `false`. /// - /// Constructors can delegate to other constructors. + /// Constructors may delegate to other constructors. #[ink(constructor)] pub fn default() -> Self { Self::new(Default::default()) } - /// update the value from runtime random source + /// Update the value from the runtimes random source. #[ink(message)] pub fn update(&mut self) -> Result<(), RandomReadErr> { // Get the on-chain random seed let new_random = self.env().extension().fetch_random()?; self.value = new_random; - // emit the RandomUpdated event when the random seed + // Emit the `RandomUpdated` event when the random seed // is successfully fetched. self.env().emit_event(RandomUpdated { new: new_random }); Ok(()) @@ -130,5 +132,38 @@ mod rand_extension { let rand_extension = RandExtension::default(); assert_eq!(rand_extension.get(), [0; 32]); } + + #[ink::test] + fn chain_extension_works() { + // given + struct MockedExtension; + impl ink_env::test::ChainExtension for MockedExtension { + /// The static function id of the chain extension. + fn func_id(&self) -> u32 { + 1101 + } + + /// The chain extension is called with the given input. + /// + /// Returns an error code and may fill the `output` buffer with a + /// SCALE encoded result. The error code is taken from the + /// `ink_env::chain_extension::FromStatusCode` implementation for + /// `RandomReadErr`. + fn call(&mut self, _input: &[u8], output: &mut Vec) -> u32 { + let ret: [u8; 32] = [1; 32]; + scale::Encode::encode_to(&ret, output); + 0 + } + } + ink_env::test::register_chain_extension(MockedExtension); + let mut rand_extension = RandExtension::default(); + assert_eq!(rand_extension.get(), [0; 32]); + + // when + rand_extension.update().expect("update must work"); + + // then + assert_eq!(rand_extension.get(), [1; 32]); + } } }