git.delta.rocks / unique-network / refs/commits / e67fafd19a27

difftreelog

source

smart_contract/nft/lib.rs5.9 KiBsourcehistory
1#![cfg_attr(not(feature = "std"), no_std)]23use ink_core::env::EnvTypes;4use scale::{Codec, Decode, Encode};5use sp_core::crypto::AccountId32;6use sp_runtime::traits::Member;7use pallet_indices::address::Address;8use core::{array::TryFromSliceError, convert::TryFrom};9use ink_core::env::Clear;1011use ink_lang as ink;1213/// The default SRML hash type.14#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Encode, Decode)]15pub struct Hash([u8; 32]);1617impl From<[u8; 32]> for Hash {18    fn from(hash: [u8; 32]) -> Hash {19        Hash(hash)20    }21}2223impl<'a> TryFrom<&'a [u8]> for Hash {24    type Error = TryFromSliceError;2526    fn try_from(bytes: &'a [u8]) -> Result<Hash, TryFromSliceError> {27        let hash = <[u8; 32]>::try_from(bytes)?;28        Ok(Hash(hash))29    }30}3132impl AsRef<[u8]> for Hash {33    fn as_ref(&self) -> &[u8] {34        &self.0[..]35    }36}3738impl AsMut<[u8]> for Hash {39    fn as_mut(&mut self) -> &mut [u8] {40        &mut self.0[..]41    }42}4344impl Clear for Hash {45    fn is_clear(&self) -> bool {46        self.as_ref().iter().all(|&byte| byte == 0x00)47    }4849    fn clear() -> Self {50        Self([0x00; 32])51    }52}5354/// The default SRML moment type.55pub type Moment = u64;5657/// The default SRML blocknumber type.58pub type BlockNumber = u64;5960/// The default SRML AccountIndex type.61pub type AccountIndex = u32;6263/// The default timestamp type.64pub type Timestamp = u64;6566/// The default SRML balance type.67pub type Balance = u128;6869#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Encode, Decode)]70pub struct AccountId (AccountId32);7172impl From<AccountId32> for AccountId {73    fn from(account: AccountId32) -> Self {74        AccountId(account)75    }76}7778// #[cfg(feature = "ink-generate-abi")]79// impl HasTypeId for AccountId {80//     fn type_id() -> TypeId {81//         TypeIdArray::new(32, MetaType::new::<u8>()).into()82//     }83// }8485// #[cfg(feature = "ink-generate-abi")]86// impl HasTypeDef for AccountId {87//     fn type_def() -> TypeDef {88//         TypeDef::builtin()89//     }90// }9192/// Contract environment types defined in substrate node-runtime93#[cfg_attr(feature = "ink-generate-abi", derive(Metadata))]94#[derive(Clone, Debug, PartialEq, Eq)]95pub enum NodeRuntimeTypes {}9697impl ink_core::env::EnvTypes for NodeRuntimeTypes {98    type AccountId = AccountId;99    type Balance = Balance;100    type Hash = Hash;101    type Timestamp = Timestamp;102    type BlockNumber = BlockNumber;103    type Call = Call;104}105106/// Default runtime Call type, a subset of the runtime Call module variants107///108/// The codec indices of the  modules *MUST* match those in the concrete runtime.109#[derive(Encode, Decode)]110#[cfg_attr(feature = "std", derive(Clone, PartialEq, Eq))]111pub enum Call {112    #[codec(index = "6")]113    Balances(Balances<NodeRuntimeTypes, AccountIndex>),114}115116/// Generic Balance Call, could be used with other runtimes117#[derive(Encode, Decode, Clone, PartialEq, Eq)]118pub enum Balances<T, AccountIndex>119where120    T: EnvTypes,121    T::AccountId: Member + Codec,122    AccountIndex: Member + Codec,123{124    #[allow(non_camel_case_types)]125    transfer(Address<T::AccountId, AccountIndex>, #[codec(compact)] T::Balance),126    #[allow(non_camel_case_types)]127    set_balance(128        Address<T::AccountId, AccountIndex>,129        #[codec(compact)] T::Balance,130        #[codec(compact)] T::Balance,131    ),132}133134#[ink::contract(version = "0.1.0")]135mod nft {136    use ink_core::storage;137138    /// Defines the storage of your contract.139    /// Add new fields to the below struct in order140    /// to add new static storage fields to your contract.141    #[ink(storage)]142    struct Nft {143        /// Stores a single `bool` value on the storage.144        value: storage::Value<bool>,145    }146147    impl Nft {148        /// Constructor that initializes the `bool` value to the given `init_value`.149        #[ink(constructor)]150        fn new(&mut self, init_value: bool) {151            self.value.set(init_value);152        }153154        /// Constructor that initializes the `bool` value to `false`.155        ///156        /// Constructors can delegate to other constructors.157        #[ink(constructor)]158        fn default(&mut self) {159            self.new(false)160        }161162        /// A message that can be called on instantiated contracts.163        /// This one flips the value of the stored `bool` from `true`164        /// to `false` and vice versa.165        #[ink(message)]166        fn flip(&mut self) {167            *self.value = !self.get();168        }169170        /// Simply returns the current value of our `bool`.171        #[ink(message)]172        fn get(&self) -> bool {173            *self.value174        }175    }176}177178179#[cfg(test)]180mod tests {181    use crate::{calls, AccountIndex, NodeRuntimeTypes};182    use super::Call;183184    use node_runtime::{self, Runtime};185    use pallet_indices::address;186    use scale::{Decode, Encode};187188    #[test]189    fn call_balance_transfer() {190        let balance = 10_000;191        let account_index = 0;192193        let contract_address = calls::Address::Index(account_index);194        let contract_transfer =195            calls::Balances::<NodeRuntimeTypes, AccountIndex>::transfer(contract_address, balance);196        let contract_call = Call::Balances(contract_transfer);197198        let srml_address = address::Address::Index(account_index);199        let srml_transfer = node_runtime::BalancesCall::<Runtime>::transfer(srml_address, balance);200        let srml_call = node_runtime::Call::Balances(srml_transfer);201202        let contract_call_encoded = contract_call.encode();203        let srml_call_encoded = srml_call.encode();204205        assert_eq!(srml_call_encoded, contract_call_encoded);206207        let srml_call_decoded: node_runtime::Call =208            Decode::decode(&mut contract_call_encoded.as_slice())209                .expect("Balances transfer call decodes to srml type");210        let srml_call_encoded = srml_call_decoded.encode();211        let contract_call_decoded: Call = Decode::decode(&mut srml_call_encoded.as_slice())212            .expect("Balances transfer call decodes back to contract type");213        assert!(contract_call == contract_call_decoded);214    }215}