Chainlink Keepers performUpkeep字节数组编码Hardhat执行失败问题咨询
问题根因
- 变量阴影冲突:
checkUpkeep函数入参已命名为checkData,函数内部重新声明了同名内存变量,不同编译器的语法检查规则差异会导致跨环境表现不一致:Remix默认允许变量阴影语法,而Hardhat默认的编译器校验规则会拦截该写法抛出隐性错误。 - Upkeep触发标记错误:Chainlink Automation机制中,
checkUpkeep返回的第一个布尔值为true时才会触发后续performUpkeep调用,当前代码写死该标记为false,如果你的Hardhat用例是模拟完整的Automation调用流程,会直接跳过performUpkeep执行。 - 数组长度冗余:声明了长度为10的
uint256数组,但循环仅为前5个位置赋值,剩余位置默认为0,属于非预期的冗余数据,虽不直接导致报错但会增加不必要的编码开销。
修复后代码
// 入参checkData未使用可以注释避免命名冲突,显式命名返回值提高可读性 function checkUpkeep(bytes calldata /* checkData */) external view override returns (bool upkeepNeeded, bytes memory performData) { uint256 counter = 0; // 数组长度改为实际需要的5,消除冗余 uint256[] memory numbers = new uint256[](5); for (uint256 i = 0; i < 10; i+=2) { numbers[counter++] = i; } performData = abi.encode(numbers); // 满足触发条件时返回true,你可以根据业务逻辑调整判断规则 upkeepNeeded = true; } function performUpkeep(bytes calldata performData) external override { uint256[] memory numbers = abi.decode(performData, (uint256[])); console.log("The first number is:", numbers[0]); }
Hardhat环境验证注意事项
- 单元测试
performUpkeep时,需要先调用checkUpkeep获取返回的编码后字节数据,再将该数据作为入参传入performUpkeep,不要手动构造不符合编码规则的字节参数。 - 确认Hardhat配置的Solidity编译器版本与Remix使用版本一致,建议统一使用0.8.17及以上稳定版本,避免编译器兼容问题。
内容的提问来源于stack exchange,提问作者alphak3y
相关产品推荐
相关产品推荐

