diff --git a/substrate/node-template/runtime/src/lib.rs b/substrate/node-template/runtime/src/lib.rs index b6deeddb87..079f11918f 100644 --- a/substrate/node-template/runtime/src/lib.rs +++ b/substrate/node-template/runtime/src/lib.rs @@ -46,6 +46,9 @@ pub type BlockNumber = u64; /// Index of an account's extrinsic in the chain. pub type Nonce = u64; +/// Used for the module template in `./template.rs` +mod template; + /// Opaque types. These are used by the CLI to instantiate machinery that don't need to know /// the specifics of the runtime. They can then be made to be agnostic over specific formats /// of data like extrinsics, allowing for them to continue syncing the network through upgrades @@ -167,6 +170,11 @@ impl sudo::Trait for Runtime { type Proposal = Call; } +/// Used for the module template in `./template.rs` +impl template::Trait for Runtime { + type Event = Event; +} + construct_runtime!( pub enum Runtime with Log(InternalLog: DigestItem) where Block = Block, @@ -180,6 +188,8 @@ construct_runtime!( Indices: indices, Balances: balances, Sudo: sudo, + // Used for the module template in `./template.rs` + TemplateModule: template::{Module, Call, Storage, Event}, } ); diff --git a/substrate/node-template/runtime/src/template.rs b/substrate/node-template/runtime/src/template.rs new file mode 100644 index 0000000000..300b48af11 --- /dev/null +++ b/substrate/node-template/runtime/src/template.rs @@ -0,0 +1,124 @@ +/// A runtime module template with necessary imports + +/// Feel free to remove or edit this file as needed. +/// If you change the name of this file, make sure to update its references in runtime/src/lib.rs +/// If you remove this file, you can remove those references + + +/// For more guidance on Substrate modules, see the example module +/// https://github.com/paritytech/substrate/blob/gav-template/srml/example/src/lib.rs + +use support::{decl_module, decl_storage, decl_event, StorageValue, dispatch::Result}; +use system::ensure_signed; + +/// The module's configuration trait. +pub trait Trait: system::Trait { + // TODO: Add other types and constants required configure this module. + + /// The overarching event type. + type Event: From> + Into<::Event>; +} + +/// This module's storage items. +decl_storage! { + trait Store for Module as TemplateModule { + // Just a dummy storage item. + // Here we are declaring a StorageValue, `Something` as a Option + // `get(something)` is the default getter which returns either the stored `u32` or `None` if nothing stored + Something get(something): Option; + } +} + +decl_module! { + /// The module declaration. + pub struct Module for enum Call where origin: T::Origin { + // Initializing events + // this is needed only if you are using events in your module + fn deposit_event() = default; + + // Just a dummy entry point. + // function that can be called by the external world as an extrinsics call + // takes a parameter of the type `AccountId`, stores it and emits an event + pub fn do_something(origin, something: u32) -> Result { + // TODO: You only need this if you want to check it was signed. + let who = ensure_signed(origin)?; + + // TODO: Code to execute when something calls this. + // For example: the following line stores the passed in u32 in the storage + >::put(something); + + // here we are raising the Something event + Self::deposit_event(RawEvent::SomethingStored(something, who)); + Ok(()) + } + } +} + +decl_event!( + /// An event in this module. + pub enum Event where AccountId = ::AccountId { + // Just a dummy event. + // Event `Something` is declared with a parameter of the type `u32` and `AccountId` + // To emit this event, we call the deposit funtion, from our runtime funtions + SomethingStored(u32, AccountId), + } +); + +/// tests for this module +#[cfg(test)] +mod tests { + use super::*; + + use runtime_io::with_externalities; + use primitives::{H256, Blake2Hasher}; + use support::{impl_outer_origin, assert_ok}; + use runtime_primitives::{ + BuildStorage, + traits::{BlakeTwo256, IdentityLookup}, + testing::{Digest, DigestItem, Header} + }; + + impl_outer_origin! { + pub enum Origin for Test {} + } + + // For testing the module, we construct most of a mock runtime. This means + // first constructing a configuration type (`Test`) which `impl`s each of the + // configuration traits of modules we want to use. + #[derive(Clone, Eq, PartialEq)] + pub struct Test; + impl system::Trait for Test { + type Origin = Origin; + type Index = u64; + type BlockNumber = u64; + type Hash = H256; + type Hashing = BlakeTwo256; + type Digest = Digest; + type AccountId = u64; + type Lookup = IdentityLookup; + type Header = Header; + type Event = (); + type Log = DigestItem; + } + impl Trait for Test { + type Event = (); + } + type TemplateModule = Module; + + // This function basically just builds a genesis storage key/value store according to + // our desired mockup. + fn new_test_ext() -> runtime_io::TestExternalities { + system::GenesisConfig::::default().build_storage().unwrap().0.into() + } + + #[test] + fn it_works_for_default_value() { + with_externalities(&mut new_test_ext(), || { + // Just a dummy test for the dummy funtion `do_something` + // calling the `do_something` function with a value 42 + assert_ok!(TemplateModule::do_something(Origin::signed(1), 42)); + // asserting that the stored value is equal to what we stored + assert_eq!(TemplateModule::something(), Some(42)); + }); + } +}