首页 > 解决方案 > Substrate RPC 中的返回结构

问题描述

我们试图在 RPC 中返回结构,但据我了解它应该是可序列化的:

    error[E0277]: the trait bound `pallet_spaces::Space<T>: serde::de::Deserialize<'_>` is not satisfied
  --> pallets/spaces/rpc/src/lib.rs:15:1
   |
15 | #[rpc]
   | ^^^^^^ the trait `serde::de::Deserialize<'_>` is not implemented for `pallet_spaces::Space<T>`
   |
   = note: required because of the requirements on the impl of `for<'de> serde::de::Deserialize<'de>` for `std::vec::Vec<pallet_spaces::Space<T>>`
   = note: required because of the requirements on the impl of `serde::de::DeserializeOwned` for `std::vec::Vec<pallet_spaces::Space<T>>`
   = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)

问题是我们使用T::Momentfrompallet_timestamp并且它不可序列化,所以我们停留在这一点:

    error[E0277]: the trait bound `<T as pallet_timestamp::Trait>::Moment: _::_serde::Serialize` is not satisfied
  --> pallets/spaces/src/lib.rs:25:5
   |
25 |     pub created: WhoAndWhen<T>,
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `_::_serde::Serialize` is not implemented for `<T as pallet_timestamp::Trait>::Moment`
   |
   = note: required because of the requirements on the impl of `_::_serde::Serialize` for `pallet_utils::WhoAndWhen<T>`
   = note: required by `_::_serde::ser::SerializeStruct::serialize_field`

你有什么建议可以轻松返回这样的结构?

#[derive(Encode, Decode, Clone, Eq, PartialEq, RuntimeDebug, Serialize, Deserialize)]
pub struct Space<T: Trait> {
    pub id: SpaceId,
    pub created: WhoAndWhen<T>,
    pub updated: Option<WhoAndWhen<T>>,

    pub owner: T::AccountId,

    // Can be updated by the owner:
    pub parent_id: Option<SpaceId>,
    pub handle: Option<Vec<u8>>,
    pub content: Content,
    pub hidden: bool,

    pub posts_count: u32,
    pub hidden_posts_count: u32,
    pub followers_count: u32,

    pub score: i32,

    /// Allows to override the default permissions for this space.
    pub permissions: Option<SpacePermissions>,
}
#[derive(Encode, Decode, Clone, Eq, PartialEq, RuntimeDebug, Serialize, Deserialize)]
pub struct WhoAndWhen<T: Trait> {
    pub account: T::AccountId,
    pub block: T::BlockNumber,
    pub time: T::Moment,
}

标签: rustsubstrate

解决方案


std你的主要问题是你在no-std这里混音。Substrate 仅取决于serdeinstd模式,因为您可以在项目中的任何Cargo.toml文件中了解相关信息。

首先解决这个问题:只有serde::*std模式下才能派生。

#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
#[derive(Encode, Decode, Clone, Eq, PartialEq, RuntimeDebug)]
pub struct Space<T: Trait> {
  // snip.. 
} 

推荐阅读