You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Substrate pallet调用mutate更新StorageMap成员报EncodeLike未实现错误如何解决

错误原因

该报错和Messages结构体的编解码实现无关,完全是mutate方法的参数传递错误导致:

  • StorageMap的mutate方法第一个参数要求传入存储项对应的key(也就是你定义的Vec<u8>类型的键),但你代码里把取出来的Messages<T>类型的值val当作第一个参数传给了mutate,编译器尝试把Messages<T>当做键编码为Vec<u8>,自然就抛出了trait EncodeLike<Vec<u8>> is not implemented for Messages<T>的错误。

修复方案

你之前先get再匹配的逻辑属于冗余写法,mutate本身就会把对应key的存储值以可变引用的形式传给闭包,还能减少一次存储读取开销,修正后的完整代码如下:

#[pallet::weight(0)]
pub fn update(
    origin: OriginFor<T>,
    key: Vec<u8>,
    header: Vec<u8>,
) -> DispatchResultWithPostInfo {
    let _origin_account = ensure_signed(origin)?;
    
    Payload::<T>::mutate(&key, |payload_opt| {
        match payload_opt {
            Some(val) => {
                println!("{:?}", val.header);
                // 结构体中header字段是Option类型,需要包一层Some
                val.header = Some(header);
            },
            None => println!("Not found")
        }
    });

    // 按函数返回值要求返回结果
    Ok(().into())
}

额外注意事项

  • 如果需要key不存在时自动创建新条目,可以在闭包的None分支赋值:*payload_opt = Some(Messages { meta: None, header: Some(header) })
  • 生产环境不要使用println,链上逻辑建议用log库的宏输出日志,或者直接移除调试代码
  • 不要随意使用#[pallet::weight(0)],实际业务需要根据执行复杂度设置合理的weight,避免链上资源被滥用

内容的提问来源于stack exchange,提问作者Kalanamith

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 00:36:04