Search code examples
ethereumsoliditysmartcontracts

How to handle timestamp in Solidity


I have written a smart contract which gets the block.timestamp and limits the caller to call the contract until the 2 hours passed as following:

mapping(address => uint256) public coffeKitchenLatestAqcuiredBalances;

function requestStarCoinFromCoffeeKitchenFaucet() public {
    address callerAddress = msg.sender;
    uint256 userLastRetrieveTime = coffeKitchenLatestAqcuiredBalances[callerAddress];
    if (userLastRetrieveTime != 0){
        uint256 epochNow = block.timestamp;
        require(userLastRetrieveTime < epochNow - 7200,"You need to wait for 2 hours from your last call");
    }
}

However I did not manage to extract to timestamp to limit the call time should be from 8AM to 6PM.

How can I format the epoch timestamp and check it on the smart contract call?


Solution

  • A great example of retrieving the hour from timestamp is in this library.

    Since you might not want to import the whole library for just one function, here's a minimal implementation:

    pragma solidity ^0.8;
    
    library TimestampHelper {
        uint constant SECONDS_PER_DAY = 24 * 60 * 60;
        uint constant SECONDS_PER_HOUR = 60 * 60;
    
        function getHour(uint timestamp) internal pure returns (uint hour) {
            uint secs = timestamp % SECONDS_PER_DAY;
            hour = secs / SECONDS_PER_HOUR;
        }
    }
    
    contract MyContract {
        function foo() external view {
            uint currentHour = TimestampHelper.getHour(block.timestamp);
            require(
                currentHour >= 8 && currentHour <= 18,
                "We're closed now. Opened from 8 AM to 6 PM UTC."
            );
        }
    }