如何配置Chainlink Keepers的performUpkeep以调用正确的目标函数
你当前的实现里checkUpkeep返回的performData为空,没有携带任何操作标识,所以performUpkeep无法区分触发场景,也就没法调用对应函数,只需要按以下步骤改造即可:
1. 改造checkUpkeep逻辑,传递操作标识
你可以用简单的数字编码代表不同的操作类型,比如1对应调用setTime(),2对应调用提现函数,将编码后的内容作为performData返回:
function checkUpkeep( bytes calldata checkData ) external view override returns ( bool upkeepNeeded, bytes memory performData ) { // 触发setTime的场景 if (getPrice() == roundMoonPrice[coinRound]) { // 编码操作标识,需要传参数的话也可以一起编码 performData = abi.encode(uint8(1)); return (true, performData); } // 触发提现的场景 if (roundWinningIndex[coinRound].length != 0) { performData = abi.encode(uint8(2)); return (true, performData); } // 无满足条件的场景 return (false, ""); }
2. 编写performUpkeep解析标识调度对应函数
Chainlink Keeper会将checkUpkeep返回的performData原封不动传入performUpkeep,你只需要解码出操作标识,匹配对应函数调用即可:
function performUpkeep(bytes calldata performData) external override { // 解码操作标识 uint8 operationType = abi.decode(performData, (uint8)); if (operationType == 1) { // 调用setTime函数 setTime(); } else if (operationType == 2) { // 调用提现函数,有参数的话也可以一起解码出来传入 withdrawal(); } else { // 未知操作类型直接回滚,避免异常执行 revert("invalid operation type"); } }
3. 正确性保障建议
- 可以在
performUpkeep入口增加权限校验,仅允许Chainlink Keeper官方调用地址触发,避免恶意调用 - 如果你要调用的函数需要传参,只需要在
checkUpkeep编码时把参数和操作标识一同写入performData,解码时按编码顺序对应解析即可 - 每个函数内部保留独立的业务校验逻辑,就算标识传错也不会触发异常业务流程
内容的提问来源于stack exchange,提问作者Japarjam
相关产品推荐
相关产品推荐

