Search code examples
blockchainsubstrate

How to map rust primitive with struct inside decl_storage! macro in substrate


pub struct Post<A> {

    id:u8,
    content:String,
    tipAmount:u8,
    author:A,
}

decl_storage! {

    trait Store for Module<T: Trait> as PostModule {

        Posts: map hasher(blake2_256) u8 => Post<T::AccountId>;

    }
}

I'm getting below error

the trait _::_parity_scale_codec::EncodeLike is not implemented for Post<::AccountId>

How we can map primitive data type with struct in decl_storage! Macro


Solution

  • You have two problems. One is rather mild, the other more serious:

    1. All data types that shall be stored on chain need to have two bounds: Encode and Decode from [parity-scale-codec]. Include this in your crate (with the "derive" feature) and simply:
    #[derive(Encode, Decode)]
    pub struct Post<A> {
        id:u8,
        content:String,
        tipAmount:u8,
        author:A,
    }
    

    Look at any other pallet in Parity's Frame library for examples. Note that most often (unless if your value is an Option) your type must also provide a Default, that you can again derive.

    1. You cannot, and probably don't want to store a string on chain. This is most often a (common and fair) mistake that people just beginning to learn blockchains make. A blockchain should not act as a data store to keep potentially long, dynamically allocated strings. Only consensus critical data should be kept on chain. As I infer from your struct, you seem to keep some blog posts on chain. That's absolutely unnecessary. You can just keep the hash of the content on chain (with other small metadata if you desire) and keep the actual post content elsewhere, in IPFS for example. The hash is enough for everyone to be able to very that the content is indeed correct.