0

i need to create nft pallet with substrate . i have write these codes but when i run this command : cargo build --release it show me this errors :

  --- stderr
     Compiling base-nft v4.0.0-dev (/home/kianoush/blockchain_project/substrate_nft/pallets/base-nft)
  error[E0433]: failed to resolve: use of undeclared crate or module `sp_runtime`
    --> /home/kianoush/blockchain_project/substrate_nft/pallets/base-nft/src/lib.rs:14:5
     |
  14 | use sp_runtime::{
     |     ^^^^^^^^^^ use of undeclared crate or module `sp_runtime`

  error[E0432]: unresolved import `sp_runtime`
    --> /home/kianoush/blockchain_project/substrate_nft/pallets/base-nft/src/lib.rs:14:5
     |
  14 | use sp_runtime::{
     |     ^^^^^^^^^^ help: a similar path exists: `frame_support::sp_runtime`

whats the problem ? how can i solve this error ?

My Codes :

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

use frame_support::{
    inherent::Vec,
    pallet_prelude::{ValueQuery, *},
    traits::Currency,Twox64Concat,
};
use frame_system::pallet_prelude::*;
/// Edit this file to define custom logic or remove it if it is not needed.
/// Learn more about FRAME and the core library of Substrate FRAME pallets:
/// <https://docs.substrate.io/v3/runtime/frame>
pub use pallet::*;
use sp_runtime::{
    traits::{
        AtLeast32BitUnsigned, CheckedAdd, CheckedSub, Hash, MaybeSerializeDeserialize, Member, One,
        Zero,
    },
    DispatchError, DispatchResult,
};

/// Class info
#[derive(Clone, Encode, Decode, PartialEq, RuntimeDebug, TypeInfo)]
#[scale_info(skip_type_params(TokenId, AccountId, Data))]
pub struct ClassInfo<TokenId, AccountId, Data> {
    /// Class metadata
    pub metadata: Vec<u8>,
    /// Total issuance for the class
    pub total_issuance: TokenId,
    /// Class owner
    pub owner: AccountId,
    /// Class Properties
    pub data: Data,
}

#[derive(Clone, Encode, Decode, PartialEq, RuntimeDebug, TypeInfo)]
#[scale_info(skip_type_params(AccountId, Data))]
pub struct TokenInfo<AccountId, Data> {
    /// Token metadata
    pub metadata: Vec<u8>,
    /// Token owner
    pub owners: Vec<AccountId>,
    /// Token Properties
    pub data: Data,
}

#[frame_support::pallet]
pub mod pallet {

    use super::*;

    #[derive(Default, Encode, Decode, Clone, Eq, PartialEq, RuntimeDebug)]
    pub struct TokenByOwnerData {
        pub percent_owned: u8,
        pub token_id: u32,
    }

    #[pallet::config]
    pub trait Config: frame_system::Config {
        type Event: From<Event<Self>> + IsType<<Self as frame_system::Config>::Event>;
        /// The class ID type
        type ClassId: Parameter + Member + Default + Copy;
        /// The token ID type
        type TokenId: Parameter + Member + Default + Copy;
        /// The class properties type
        type ClassData: Parameter + Member + Default;
        /// The token properties type
        type TokenData: Parameter + Member + Default;
    }

    pub type ClassInfoOf<T> = ClassInfo<
        <T as Config>::TokenId,
        <T as frame_system::Config>::AccountId,
        <T as Config>::ClassData,
    >;
    pub type TokenInfoOf<T> =
        TokenInfo<<T as frame_system::Config>::AccountId, <T as Config>::TokenData>;

    pub type GenesisTokenData<T> = (
        <T as frame_system::Config>::AccountId, // Token owner
        Vec<u8>,                                // Token metadata
        <T as Config>::TokenData,
    );
    pub type GenesisTokens<T> = (
        <T as frame_system::Config>::AccountId, // Token class owner
        Vec<u8>,                                // Token class metadata
        <T as Config>::ClassData,
        Vec<GenesisTokenData<T>>, // Vector of tokens belonging to this class
    );

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

    /// Next available class ID.
    #[pallet::storage]
    #[pallet::getter(fn next_class_id)]
    pub type NextClassId<T: Config> = StorageValue<_, T::ClassId, ValueQuery>;

    /// Next available token ID.
    #[pallet::storage]
    #[pallet::getter(fn next_token_id)]
    pub type NextTokenId<T: Config> =
        StorageMap<_, Twox64Concat, T::ClassId, T::TokenId, ValueQuery>;

    /// Store class info.
    ///
    /// Returns `None` if class info not set or removed.
    #[pallet::storage]
    #[pallet::getter(fn classes)]
    pub type Classes<T: Config> = StorageMap<_, Twox64Concat, T::ClassId, ClassInfoOf<T>>;

    /// Store token info.
    ///
    /// Returns `None` if token info not set or removed.
    #[pallet::storage]
    #[pallet::getter(fn tokens)]
    pub type Tokens<T: Config> =
        StorageDoubleMap<_, Twox64Concat, T::ClassId, Twox64Concat, T::TokenId, TokenInfoOf<T>>;

    // Pallets use events to inform users when important changes are made.
    // https://docs.substrate.io/v3/runtime/events-and-errors
    #[pallet::event]
    #[pallet::generate_deposit(pub(super) fn deposit_event)]
    pub enum Event<T: Config> {
        /// Event documentation should end with an array that provides descriptive names for event
        /// parameters. [something, who]
        SomethingStored(u32, T::AccountId),
    }

    /// Error for non-fungible-token module.
    #[pallet::error]
    pub enum Error<T> {
        /// No available class ID
        NoAvailableClassId,
        /// No available token ID
        NoAvailableTokenId,
        /// Token(ClassId, TokenId) not found
        TokenNotFound,
        /// Class not found
        ClassNotFound,
        /// The operator is not the owner of the token and has no permission
        NoPermission,
        /// Arithmetic calculation overflow
        NumOverflow,
        /// Can not destroy class
        /// Total issuance is not 0
        CannotDestroyClass,
        /// Sender tried to send more ownership than they have
        SenderInsufficientPercentage,
        /// Wrong arguments
        WrongArguments,
    }

    #[pallet::call]
    impl<T: Config> Pallet<T> {}
}

impl<T: Config> Pallet<T> {
    pub fn create_class(
        origin: OriginFor<T>,
        metadata: Vec<u8>,
        data: T::ClassData,
    ) -> DispatchResult {
        let who = ensure_signed(origin)?;

        let class_id = NextClassId::<T>::try_mutate(|id| -> Result<T::ClassId, DispatchError> {
            let current_id = *id;
            *id = id.checked_add(&One::one()).ok_or(Error::<T>::NoAvailableClassId)?;
            Ok(current_id)
        })?;

        let info =
            ClassInfo { metadata, total_issuance: Default::default(), owner: who.clone(), data };
        Classes::<T>::insert(class_id, info);

        Ok(class_id)
    }
}

1 Answer 1

3

You should add sp-runtime to your pallet's Cargo.toml file:

...
sp-runtime = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "master" }
...

Or try to do what the compiler is telling you "help: a similar path exists: frame_support::sp_runtime"

use frame_support::sp_runtime::{<Module1>, <Module2>, ...},
1
  • 1
    And dont forget to add the crate to std features Aug 25, 2022 at 18:06

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.