Solidity合约调用含string参数函数报invalid data错误的解决方法
解决Solidity合约submitSurvey函数调用的"invalid data; odd-length - 0x0"错误
可能的原因及解决方案
1. 修复数值参数的类型转换问题
JavaScript中的科学计数法(如21e6)在编码为Solidity的uint类型时可能触发解析异常,导致整个调用的数据格式错误。
修改测试代码中的数值参数,避免使用科学计数法,改用整数字面量或显式转换为BigInt:
// 方案1:直接使用整数字面量 await mygov.connect(user_account2).submitSurvey("abc", 21000000, 3, 2); // 方案2:显式转换为BigInt(更稳妥,避免大数精度问题) await mygov.connect(user_account2).submitSurvey("abc", BigInt(21e6), 3, 2);
2. 检查Remix测试环境的合约加载状态
- 确保修改合约后重新编译,测试脚本使用的是最新编译生成的ABI。旧ABI会导致参数编码不匹配,触发数据格式错误。
- 尝试刷新Remix页面、清除缓存后重新编译部署合约,再执行测试。
3. 验证函数参数的顺序和类型匹配
确认测试代码的参数顺序与Solidity函数的参数顺序完全一致:
Solidity函数参数顺序:string memory ipfshash, uint surveydeadline, uint numchoices, uint atmostchoice
测试代码参数顺序符合要求,但需确保所有数值参数都在uint的取值范围内且无负数。
额外优化:合约内的逻辑问题(非当前错误原因,但建议修复)
你的合约中surveyid的赋值存在逻辑漏洞:
surveyid = surveys.length - 1 ; mysurvey.SurveyId = surveyid;
由于mysurvey是memory变量,已通过surveys.push(mysurvey)存入storage,后续修改mysurvey.SurveyId不会影响storage中的数据。正确写法应为:
surveyid = surveys.length; // 提前用当前长度作为新Survey的ID Survey memory mysurvey = Survey({ Ipfshash : ipfshash, Owner: msg.sender, Deadline: surveydeadline, SurveyId: surveyid, AtmostChoice: atmostchoice, NumChoices: numchoices, NumTaken : 0, Results : results }); surveys.push(mysurvey);
内容的提问来源于stack exchange,提问作者demet47
相关产品推荐
相关产品推荐

