Substrate pallet存储用BTreeMap未实现Encode trait报错如何解决?
错误原因
- 你使用了
std::collections::BTreeMap,Substrate Runtime 默认以无标准库(no_std)的WASM环境编译,std版本的BTreeMap没有实现Runtime要求的Scale编解码trait。 - 结构体
SortitionSumTree的泛型参数AccountId没有加必要的编解码约束,无法满足存储序列化的要求。 - 存储定义中传入的泛型参数错误,你直接把pallet的Config类型
T传给了需要AccountId泛型的结构体,类型不匹配。
解决步骤
- 第一步:替换BTreeMap的导入
把use std::collections::BTreeMap;替换为Substrate官方提供的no_std兼容版本:
use sp_std::collections::btree_map::BTreeMap;
- 第二步:给结构体泛型加约束
修改结构体定义,给泛型AccountId增加编解码相关的约束,避免后续编译的约束缺失问题:
#[derive(PartialEq, Eq, PartialOrd, Ord, Default, Clone, Encode, Decode, TypeInfo)] #[codec(encode_bound(AccountId: Encode))] #[codec(decode_bound(AccountId: Decode))] #[scale_info(bound(AccountId: TypeInfo))] #[cfg_attr(feature = "std", derive(Debug))] pub struct SortitionSumTree<AccountId> { pub k: u128, pub stack: Vec<u128>, pub nodes: Vec<u128>, pub ids_to_tree_indexes: BTreeMap<AccountId, u128>, pub node_indexes_to_ids: BTreeMap<u128, AccountId>, }
- 第三步:修正存储定义的泛型参数
存储定义中要传入pallet Config中定义的关联类型AccountId作为结构体的泛型参数:
#[pallet::storage] #[pallet::getter(fn sortition_sum_trees)] pub type SortitionSumTrees<T: Config> = StorageMap<_, Blake2_128Concat, Vec<u8>, SortitionSumTree<T::AccountId>>;
如果你已经在pallet的Config trait中继承了frame_system::Config,那么T::AccountId默认已经满足所有需要的约束,无需额外加其他配置。
内容的提问来源于stack exchange,提问作者Amiya Behera
相关产品推荐
相关产品推荐

