1

I have an issue. I wold like to store a struct using AccountId as key:

#[derive(Clone, Copy, Encode, Decode, RuntimeDebug, PartialEq, Eq, MaxEncodedLen, TypeInfo)]
    pub struct Contract<Origin, AccountId, Amount> {
        pub origin: Origin,
        pub to: AccountId,
        pub amount: Amount,
        pub current_block_number: u64,
        pub work_days_in_block_number: u64,
        pub take_action_days_in_block: u64,
    }


    #[pallet::storage]
    #[pallet::getter(fn contract_sender)]
    pub(super) type ContractSender<T: Config> =
    StorageMap<_, Blake2_128Concat, T::AccountId, Contract<T::AccountId, T::AccountId, BalanceOf<T>>, ValueQuery>;


    #[pallet::storage]
    #[pallet::getter(fn contract_receiver)]
    pub(super) type ContractReceiver<T: Config> =
    StorageMap<_, Blake2_128Concat, T::AccountId, Contract<T::AccountId, T::AccountId, BalanceOf<T>>, ValueQuery>;

But having this issue:

error[E0277]: the trait bound `Contract<<T as frame_system::Config>::AccountId, <T as frame_system::Config>::AccountId, <<T as pallet::Config>::Currency as Currency<<T as frame_system::Config>::AccountId>>::Balance>: std::default::Default` is not satisfied
  --> pallets/escrow/src/lib.rs:47:12
   |
47 |     #[pallet::pallet]
   |               ^^^^^^ the trait `std::default::Default` is not implemented for `Contract<<T as frame_system::Config>::AccountId, <T as frame_system::Config>::AccountId, <<T as pallet::Config>::Currency as Currency<<T as frame_system::Config>::AccountId>>::Balance>`
   |
   = help: the trait `StorageInfoTrait` is implemented for `frame_support::pallet_prelude::StorageMap<Prefix, Hasher, Key, Value, QueryKind, OnEmpty, MaxValues>`
   = note: required because of the requirements on the impl of `frame_support::traits::Get<Contract<<T as frame_system::Config>::AccountId, <T as frame_system::Config>::AccountId, <<T as pallet::Config>::Currency as Currency<<T as frame_system::Config>::AccountId>>::Balance>>` for `GetDefault`
   = note: required because of the requirements on the impl of `QueryKindTrait<Contract<<T as frame_system::Config>::AccountId, <T as frame_system::Config>::AccountId, <<T as pallet::Config>::Currency as Currency<<T as frame_system::Config>::AccountId>>::Balance>, GetDefault>` for `frame_support::pallet_prelude::ValueQuery`
   = note: required because of the requirements on the impl of `StorageInfoTrait` for `frame_support::pallet_prelude::StorageMap<_GeneratedPrefixForStorageContractSender<T>, frame_support::Blake2_128Concat, <T as frame_system::Config>::AccountId, Contract<<T as frame_system::Config>::AccountId, <T as frame_system::Config>::AccountId, <<T as pallet::Config>::Currency as Currency<<T as frame_system::Config>::AccountId>>::Balance>, frame_support::pallet_prelude::ValueQuery>`

error[E0277]: the trait bound `Contract<<T as frame_system::Config>::AccountId, <T as frame_system::Config>::AccountId, <<T as pallet::Config>::Currency as Currency<<T as frame_system::Config>::AccountId>>::Balance>: std::default::Default` is not satisfied
  --> pallets/escrow/src/lib.rs:66:12
   |
66 |     #[pallet::storage]
   |               ^^^^^^^ the trait `std::default::Default` is not implemented for `Contract<<T as frame_system::Config>::AccountId, <T as frame_system::Config>::AccountId, <<T as pallet::Config>::Currency as Currency<<T as frame_system::Config>::AccountId>>::Balance>`

I do not understand what's wrong :/ Any idea?

0

2 Answers 2

1

Yes, as previously mentioned, the ValueQuery forces Contract to default to some kind of default Contract with default AccountId, which doesn't exist, and OptionQuery allows it to just be None. Broke my head the first time I saw this error! :)

1

I wold like to store a struct using AccountId as key.

This is not the problem. It's totally fine.

The problem is the Contract struct. Because the StorageMap value require Default. It contains an AccountId and the AccountId doesn't implement Default.

You could change this map's query type to OptionQuery.


Check the original PR for more information.

https://github.com/paritytech/substrate/pull/10403

3
  • 2
    Wouldn't using OptionQuery instead of ValueQuery solve the problem without the need to change the value type? Commented Sep 8, 2022 at 9:35
  • Sorry, I mean to change the type to OptionQuery. That's right! Because I don't have a computer nearby when I answer this question. I forgot the detail. I just want to tell you that you should use the option type here.
    – AurevoirXavier
    Commented Sep 8, 2022 at 9:44
  • OK, so I'd suggest to edit the answer to avoid confusion. Commented Sep 8, 2022 at 11:53

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