near_sdk_sim中view!调用获取struct出现EOF错误如何解决?
报错核心原因
报错本质是调用返回值的解析格式和合约实际输出格式不匹配:
- NEAR 合约的view方法默认会将返回值通过Borsh规则序列化成二进制流,这是链上交互的标准返回格式
- 当前代码使用的
.unwrap_json()方法,是按照JSON文本格式解析返回内容,面对纯二进制的Borsh输出时,解析器识别不到合法的JSON结构,就会抛出「读取到内容结束、未找到可解析值」的错误。
修正方案
方案1:匹配Borsh解析逻辑(符合链上交互规范)
不需要修改合约本身的代码,直接调整测试侧的解析逻辑即可:
- 先调用
.unwrap_result()确认合约执行过程中没有触发panic,再将返回的二进制流通过Borsh规则反序列化为Product结构体:
let product: Product = view!(contract.get_product(1u128.into())) .unwrap_result() .to_borsh() .deserialize() .expect("Borsh反序列化Product失败");
- 注意:因为你的
Product已经提前derive了BorshDeserialize,可以直接完成反序列化,不需要额外修改结构体定义。
方案2:调整合约返回格式为JSON(方便调试时直接解析)
如果希望保留.unwrap_json()的调用方式适配测试场景,可以修改合约的view方法,让返回值序列化为JSON格式输出:
- 保持现有
Product的serde序列化derive(当前代码已经完成) - 修改
get_product方法的返回值类型,将结构体转成JSON Value返回:
pub fn get_product(&self, product_id: U128) -> near_sdk::serde_json::Value { let product_option = self.product_map.get(&product_id); match product_option { Some(product) => near_sdk::serde_json::to_value(product).unwrap(), None => { panic!("No products for the id"); } } }
修改完成后,原来的view!(contract.get_product(1.into())).unwrap_json()就可以正常解析出Product实例。
易踩的排查点
- 先确认
product_map中确实存在对应product_id的键值:如果触发了No products for the id的panic,调用本身没有返回有效内容,无论用哪种解析方式都会报EOF类错误 - 检查参数类型匹配:
1.into()要确保能正确转换为合约方法要求的U128类型,避免参数序列化错位导致的查询失败 - 用Borsh反序列化时,要确保
Product的字段顺序、数据类型和存储时的序列化逻辑完全一致,避免出现反序列化值错位的问题
内容的提问来源于stack exchange,提问作者Amiya Behera
相关产品推荐
相关产品推荐

