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

从合约创建Chainlink时间型Upkeep后无法自动执行的解决方法

问题:Chainlink时间型Upkeep注册后无法自动执行sendSalary函数

已完成Chainlink Upkeep的注册与充值,但目标函数sendSalary始终无法自动触发执行。相关合约代码如下:

// Goerli network
address public cronFactoryAddress = 0x1af3cE8de065774B0EC08942FC5779930d1A9622;
address public keeperRegistrar = 0x57A4a13b35d25EE78e084168aBaC5ad360252467;

constructor(){
        cronFactory = ICronFactory(cronFactoryAddress);
    }

function createUpkeep(string memory _cronString) public{
        address _target = address(this);    
        bytes memory functionToCall = bytes(abi.encodeWithSignature("sendSalary(string)", _cronString));
        
        bytes memory job = cronFactory.encodeCronJob(_target, functionToCall,  _cronString);
        uint256 maxJobs = cronFactory.s_maxJobs();
        address delegateAddress = cronFactory.cronDelegateAddress();
        address newCronUpkeep = address(new CronUpkeep(msg.sender, delegateAddress, maxJobs, job));
        allUpkeeps.push(newCronUpkeep);
    }

function fundUpkeep(uint256 _linkAmount, address _upkeepAddress) public{
        bytes4 reg = bytes4(keccak256("register(string,bytes,address,uint32,address,bytes,bytes,uint96,address)"));
        bytes memory _data = abi.encode(
            "TestV2",
            "",
            _upkeepAddress,
            uint32(500000),
            address(this),
            "",
            "",
            _linkAmount,
            address(this)
        );
        bytes memory combinedData = abi.encodePacked(reg, _data);
        LinkContract.transferAndCall(keeperRegistrar, _linkAmount, combinedData);
    }

注:sendSalary为需定时执行的合约函数,cronFactory是Chainlink Cron工厂合约,CronUpkeep代码来自Chainlink官方仓库。手动创建时间型Upkeep的交易日志逻辑与上述代码一致,但注册后官网显示Upkeep为「自定义触发」,无自动执行动作。


排查与解决步骤

  • 修正Upkeep触发类型配置
    注册时显示「自定义触发」,说明未正确传入时间触发的配置参数。fundUpkeep函数中register调用的第二个参数(triggerConfig)为空字符串,这是错误的——时间型Upkeep需要传入Cron表达式的编码值。

  • 修改fundUpkeep函数的triggerConfig参数
    使用CronFactory的encodeConfig方法生成合法的时间触发配置,替换原有的空字符串:

    function fundUpkeep(uint256 _linkAmount, address _upkeepAddress, string memory _cronString) public{
        bytes4 reg = bytes4(keccak256("register(string,bytes,address,uint32,address,bytes,bytes,uint96,address)"));
        // 生成Cron表达式对应的触发配置
        bytes memory triggerConfig = cronFactory.encodeConfig(_cronString);
        bytes memory _data = abi.encode(
            "TestV2",
            triggerConfig, // 替换原空字符串
            _upkeepAddress,
            uint32(500000),
            address(this),
            "",
            "",
            _linkAmount,
            address(this)
        );
        bytes memory combinedData = abi.encodePacked(reg, _data);
        LinkContract.transferAndCall(keeperRegistrar, _linkAmount, combinedData);
    }
    
  • 验证CronUpkeep合约的checkUpkeep逻辑
    Chainlink Keeper通过调用CronUpkeep的checkUpkeep方法判断是否触发执行,需确保该方法能正确返回true(满足Cron时间条件时)。

  • 确认权限与资源配置

    1. 检查sendSalary函数是否有访问限制,确保CronUpkeep合约地址有权调用;
    2. 确认Upkeep账户的LINK余额充足,能覆盖执行费用;
    3. 检查uint32(500000)的Gas限额是否足够完成sendSalary的执行,避免因Gas不足导致执行失败。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 04:02:58