How to create a time-based upkeep directly from my contract rather than use the GUI?

104 views Asked by At

I want to create a time-based upkeep directly from my contract. I was able to register and fund the upkeep but for some reason the function is not getting executed automatically. Here's the code `

// 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 is the function in my contract that I want to be executed at regular intervals.
cronFactory is the cron factory contract.
cronUpkeep is the cronUpkeep.sol contract from the chainlink github repo.

To create these functions, I created a time-based upkeep manually and used the transaction logs to find what all function are being called and implemented the same here.

But, Once I execute both these functions nothing happens, however, I am able to find the upkeep registered on chainlink's website . And also it shows the trigger as custom trigger on upkeep page on chainlink:

chanlink upkeep

Please let me know how I can solve this? Any help would be appreciated. Thanks in advance

1

There are 1 answers

0
Andrew Novikoff On

Contracts cannot execute themselves. Function needs to be called. While contract (function) is not called, contract is sleeping, because every time it makes operations, they should be payed (aka gas), so there is no way to throw an allways-active-timer inside of the contract (infinite gas). It means that you have to make calls manually or use automation services like ChainLink, Openzepplin Defender etc.

You can make a requirement by time-passed with

uint256 private lastTimeStamp;
uint256 private interval;

constructor() {
    lastTimeStamp = block.timestamp;
    interval = 7 days;
}

function isTimePassed() public view returns (bool timePassed) {
    timePassed = ((block.timestamp - lastTimeStamp) > /*7 days */ interval);
    return timePassed;
}

function smth() public {
    (bool timePassed) = isTimePassed();
    ...
}

Something like this.