How can I save string value on Substrate

Viewed 1161
  1. I want to save "String" Value on Substrate
  2. At First, I use "Vec" But It's not recognized by Polkadot JS
  3. I use "Bytes",So I get the below error
  4. How can I solve this problem?

Please help me.

  • Is it correct to use "Bytes" as a way to store strings?
  • If correct, how can I fix the error below?
  • If not, what is correct to use?
  • Please let me know if you have sample code
#[cfg(test)]
mod mock;

#[cfg(test)]
mod tests;

#[derive(Clone, Eq, PartialEq, Default, Encode, Decode, Hash)]
#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))]
pub struct TestData<BlockNumber,Bytes> {
    pub name: Bytes,                                                                                                                                                                    
    pub address: Bytes,
}
pub type TestDataOf<T> = TestData<primitives::Bytes>;
--snip--
// This pallet's storage items.
decl_storage! {
    // It is important to update your storage name so that your pallet's
    // storage items are isolated from other pallets.
    // ---------------------------------vvvvvvvvvvvvvv
    trait Store for Module<T: Trait> as TemplateModule {
        pub TestDatas: map hasher(blake2_128_concat) T::AccountId => Option<TestDataOf<T>>;
    }
}
--snip--
decl_module! {
    /// The module declaration.
    pub struct Module<T: Trait> for enum Call where origin: T::Origin {
        // Initializing errors
        // this includes information about your errors in the node's metadata.
        // it is needed only if you are using errors in your pallet
        type Error = Error<T>;

        // Initializing events
        // this is needed only if you are using events in your pallet
        fn deposit_event() = default;


        /// regist public data
        #[weight = 10_000]
        pub fn register_test_data(origin, name:Bytes, address:Bytes) -> dispatch::DispatchResult {
            let registerer = ensure_signed(origin)?;
            let test_data = TestDataOf::<T> {
                name,
                address,
            };
            <TestDatas<T>>::insert(&registerer, test_data);
            Ok(())
        }
    }
}
--snip--

Error is...

the trait `_::_parity_scale_codec::Encode` is not implemented for `TestData<substrate_primitives::Bytes>`
the trait `_::_parity_scale_codec::Decode` is not implemented for `TestData<substrate_primitives::Bytes>`
the trait `_::_parity_scale_codec::WrapperTypeEncode` is not implemented for `substrate_primitives::Bytes`
1 Answers

You should use a Vec<u8> to store arbitrary bytes in runtime storage like a string.

When accessing a Vec<u8> that is a string in Polkadot JS, you should use the type Text, which automatically handles parsing and converting this type to regular UTF-8 text.

Example:

Rust:

pub struct TestData {
    pub name: Vec<u8>,                                                                                                                                                                    
    pub address: Vec<u8>,
}

Polkadot JS Type Definition:

TestData: {
    name: 'Text',
    address: 'Text'
}

Let me know if this helps or if you have further issues.

Related