function checkUpkeep(
bytes calldata checkData
) external view override returns (
bool upkeepNeeded, bytes memory performData
) {
if (getPrice() == roundMoonPrice[coinRound]) {
upkeepNeeded = true;
return (true, performData) ; //should perform upkeep for the setTime() function
} if (roundWinningIndex[coinRound].length != 0) {
upkeepNeeded = true;
return (true, performData);//should perform upkep for the a withdrawal function
}
//question: how do I configure the perform upkeep to know which function to call? as elaborated above
}
function performUpkeep(bytes calldata performData) external override {
setTime();
}
1 Answer
There are a number of ways you can have the keepers call the correct function. One way would be to add information in your performData
designating which function to call.
The performUpkeep looks like this:
function performUpkeep(bytes calldata performData) external override {
// conditional to call one function
// conditional to call a different function
}
1. The Better way
When the Chainlink keepers call checkUpkeep
they pass the returned information of performData
to the input of performUpkeep
. You can encode just about anything to pass as inputs to the performUpkeep
function.
For example, you could pass a number to performUpkeep that corresponds with which function to call:
function checkUpkeep(
bytes calldata checkData
) external view override returns (
bool upkeepNeeded, bytes memory performData
) {
if (getPrice() == roundMoonPrice[coinRound]) {
upkeepNeeded = true;
performData = abi.encodePacked(uint256(0); // This is the new line
return (true, performData) ;
} if (roundWinningIndex[coinRound].length != 0) {
upkeepNeeded = true;
performData = abi.encodePacked(uint256(1); // This is the new line
return (true, performData);
}
Then, in your performUpkeep:
function performUpkeep(bytes calldata performData) external override {
uint256 decodedValue = abi.decode(performData, (uint256));
if(decodedValue == 0){
setTime();
}
if(decodedValue == 1){
withdraw();
}
}
We encode and decode our performData
object. In fact, we can use multiple parameters as well using more clever encoding per the solidity docs.
2. The not as good, but easier to understand way
Otherwise, you could do something with storage variables if the encoding is too tricky. This isn't ideal, because multiple calls of performUpkeep will fight for the storage variable.
For example:
uint256 public functionToCall = 0;
function checkUpkeep(
bytes calldata checkData
) external view override returns (
bool upkeepNeeded, bytes memory performData
) {
if (getPrice() == roundMoonPrice[coinRound]) {
upkeepNeeded = true;
functionToCall = 0;
return (true, performData) ;
} if (roundWinningIndex[coinRound].length != 0) {
upkeepNeeded = true;
functionToCall = 1;
return (true, performData);
}
Then:
function performUpkeep(bytes calldata performData) external override {
if(functionToCall == 0){
setTime();
}
if(functionToCall == 1){
withdraw();
}
}