2

I was following the substrate kitties tutorial where i needed to create a storage map where the id is mapped to the kitty struct which is created. But i am getting the following error.

error[E0277]: the trait bound `Kitty<T>: TypeInfo` is not satisfied
  --> pallets/mykitties/src/lib.rs:85:12
   |
85 |     #[pallet::storage]
   |               ^^^^^^^ the trait `TypeInfo` is not implemented for `Kitty<T>`
   |
   = help: the following other types implement trait `TypeInfo`:
             &T
             &mut T
             ()
             (A, B)
             (A, B, C)
             (A, B, C, D)
             (A, B, C, D, E)
             (A, B, C, D, E, F)
           and 167 others
   = note: required because of the requirements on the impl of `StaticTypeInfo` for `Kitty<T>`
   = note: required because of the requirements on the impl of `StorageEntryMetadataBuilder` for `frame_support::pallet_prelude::StorageMap<_GeneratedPrefixForStorageKitties<T>, frame_support::Twox64Concat, <T as frame_system::Config>::Hash, Kitty<T>>`

This is my pallet code below(pallets/mykitties/src/lib.rs)

#![cfg_attr(not(feature = "std"), no_std)]

pub use pallet::*;

#[frame_support::pallet]
pub mod pallet {
    use frame_support::{
        dispatch::{DispatchResult, DispatchResultWithPostInfo},
        pallet_prelude::*,
        sp_runtime::traits::{Hash, Zero},
        traits::{Currency, ExistenceRequirement, Randomness},
    };
    use frame_system::pallet_prelude::*;
    use sp_io::hashing::blake2_128;

    #[cfg(feature = "std")]
    use serde::{Deserialize, Serialize};

    type AccountOf<T> = <T as frame_system::Config>::AccountId;
    type BalanceOf<T> =
        <<T as Config>::Currency as Currency<<T as frame_system::Config>::AccountId>>::Balance;

    #[derive(Encode, Decode, Debug, Clone, PartialEq)]
    #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
    pub enum Gender {
        Male,
        Female,
    }

    impl Default for Gender {
        fn default() -> Self {
            Gender::Male
        }
    }

    #[derive(Clone, Encode, Decode, PartialEq)]
    pub struct Kitty<T: Config> {
        pub dna: [u8; 16],
        pub price: Option<BalanceOf<T>>,
        pub gender: Gender,
        pub owner: AccountOf<T>,
    }

    // TODO Part II: Struct for holding Kitty information.

    // TODO Part II: Enum and implementation to handle Gender type in Kitty struct.

    #[pallet::pallet]
    #[pallet::generate_store(trait Store)]
    pub struct Pallet<T>(_);

    /// Configure the pallet by specifying the parameters and types it depends on.
    #[pallet::config]
    pub trait Config: pallet_balances::Config + frame_system::Config {
        /// Because this pallet emits events, it depends on the runtime's definition of an event.
        type Event: From<Event<Self>> + IsType<<Self as frame_system::Config>::Event>;

        // The Currency handler for the Kitties pallet.
        type Currency: Currency<Self::AccountId>;

        // TODO Part II: Specify the custom types for our runtime.
        type KittyRandomness: Randomness<Self::Hash, Self::BlockNumber>;

        #[pallet::constant]
        type MaxKittyOwned: Get<u32>;
    }

    // Errors.
    #[pallet::error]
    pub enum Error<T> {
        // TODO Part III
    }

    #[pallet::event]
    // #[pallet::metadata(T::AccountId = "AccountId")]
    #[pallet::generate_deposit(pub(super) fn deposit_event)]
    pub enum Event<T: Config> {
        // TODO Part III
    }

    #[pallet::storage]
    #[pallet::getter(fn all_kitties_count)]
    pub(super) type AllKittiesCount<T: Config> = StorageValue<_, u64, ValueQuery>;

    #[pallet::storage]
    #[pallet::getter(fn kitties)]
    /// Stores a Kitty's unique traits, owner and price.
    pub(super) type Kitties<T: Config> = StorageMap<_, Twox64Concat, T::Hash, Kitty<T>>;

    #[pallet::storage]
    #[pallet::getter(fn kitties_owned)]
    pub(super) type KittiesOwned<T: Config> = StorageMap<
        _,
        Twox64Concat,
        T::AccountId,
        BoundedVec<T::Hash, T::MaxKittyOwned>,
        ValueQuery,
    >;

    // TODO Part II: Remaining storage items.

    // TODO Part III: Our pallet's genesis configuration.

    #[pallet::call]
    impl<T: Config> Pallet<T> {
        // TODO Part III: create_kitty

        // TODO Part III: set_price

        // TODO Part III: transfer

        // TODO Part III: buy_kitty

        // TODO Part III: breed_kitty
    }

    impl<T: Config> Kitty<T> {
        pub fn gender(dna: T::Hash) -> Gender {
            if dna.as_ref()[0] % 2 == 0 {
                Gender::Male
            } else {
                Gender::Female
            }
        }
    }

    impl<T: Config> Pallet<T> {
        // TODO Part III: helper functions for dispatchable functions

        // TODO: increment_nonce, random_hash, mint, transfer_from

        fn gen_gender() -> Gender {
            let random = T::KittyRandomness::random(&b"gender"[..]).0;
            match random.as_ref()[0] % 2 {
                0 => Gender::Male,
                _ => Gender::Female,
            }
        }

        fn gen_dna() -> [u8; 16] {
            let payload = (
                T::KittyRandomness::random(&b"gender"[..]).0,
                <frame_system::Pallet<T>>::block_number(),
            );

            payload.using_encoded(blake2_128)
        }
    }
}

Here is the code: https://github.com/dhruvja/substrate-kitties

Please can anybody help me to solve this issue?

1

3 Answers 3

6

Add TypeInfo and #[scale_info(skip_type_params(T))] . Because your struct define Generic type

#[derive(Clone, Encode, Decode, PartialEq, RuntimeDebug, TypeInfo)]
#[scale_info(skip_type_params(T))]
pub struct Kitty<T: Config> {
      pub dna: [u8; 16],
      pub price: Option<BalanceOf<T>>,
      pub gender: Gender,
      pub owner: AccountOf<T>,
    }
1

You need to implement TypeInfo Trait to Kitty's Struct like below.

#[derive(Clone, Encode, Decode, PartialEq, TypeInfo)]
pub struct Kitty<T: Config> {
    pub dna: [u8; 16],
    pub price: Option<BalanceOf<T>>,
    pub gender: Gender,
    pub owner: AccountOf<T>,
}
1
  • the trait bound `T: scale_info::TypeInfo` is not satisfied I am getting this after adding the above TypeInfo Commented Aug 4, 2022 at 18:39
0

#[scale_info(skip_type_params(T))] annotating the struct worked for me.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.