Substrate中decl_storage!宏内原生类型与结构体映射报错解决
解决Substrate存储中结构体的EncodeLike实现错误
嘿,这个问题我之前刚碰到过!你遇到的错误本质是你的Post结构体没有实现Substrate存储系统要求的SCALE codec相关 trait——具体来说是Encode和Decode(EncodeLike会自动由这两个派生出来)。Substrate的存储依赖SCALE来序列化/反序列化数据,所以任何要存入存储的类型都必须实现这两个trait。
下面是具体的修复步骤,附带完整代码示例:
1. 给Post结构体添加必要的派生宏
首先,你需要为Post结构体派生Encode、Decode以及一些存储操作常用的trait。这些宏都在frame_support crate里,所以要确保已经导入。
修改你的结构体定义:
// 导入必要的宏和trait(确保你的pallet已经引入了frame_support) use frame_support::codec::{Encode, Decode}; use frame_support::RuntimeDebug; // 派生所需的trait,同时给泛型A添加约束 #[derive(Encode, Decode, Clone, PartialEq, RuntimeDebug)] pub struct Post<A> where A: Encode + Decode + Clone + PartialEq, { id: u8, content: String, tip_amount: u8, // 建议改成snake_case符合Rust代码规范,可选但推荐 author: A, } // 可选:给结构体添加构造函数,方便创建实例 impl<A> Post<A> where A: Encode + Decode + Clone + PartialEq, { pub fn new(id: u8, content: String, tip_amount: u8, author: A) -> Self { Self { id, content, tip_amount, author, } } }
这里的trait约束是为了确保泛型A(也就是你的AccountId)也满足编码要求——而Substrate默认的AccountId类型(比如AccountId32)已经实现了这些trait,所以不用担心。
2. 确保decl_storage!中的定义正确
现在你的Post<T::AccountId>已经具备了存储所需的所有trait,直接沿用你原来的存储映射定义就可以了:
decl_storage! { trait Store for Module<T: Trait> as PostModule { Posts: map hasher(blake2_256) u8 => Post<T::AccountId>; } }
为什么需要这些trait?
Encode/Decode:Substrate存储用SCALE codec处理数据的序列化和反序列化,没有这两个trait,数据无法写入或读取存储。Clone:存储操作中经常需要克隆数据(比如读取后返回给外部调用),所以这个trait是必要的。PartialEq:方便在业务逻辑中比较两个Post实例是否相等。RuntimeDebug:调试时可以打印结构体的内容,非常实用。
这样修改后,你之前遇到的EncodeLike未实现的错误应该就消失了。如果还有问题,可以检查一下你的pallet是否正确引入了frame_support依赖,以及T::AccountId是否确实实现了所需的trait。
内容的提问来源于stack exchange,提问作者hemant kumar
相关产品推荐
相关产品推荐

