4

I hope this question is not bad one, but this has been something I have been having trouble understanding. How does time in the blockchain work, and how can I utilize variables like block.timestamp and the like? I am creating a faucet where the user can withdraw a set amount of ether, then they have to wait one hour before they can withdraw more.

Edit for duplication: I have looked at other explanations here on StackExchange, but it did not answer my question. I would like to know how time is passed on the blockchain, and with this knowledge utilize block.timestamp. I apologize if I was unclear. I am a beginner with creating Dapps, and want to learn! :)

  • @RichardHorrocks I am creating a faucet where the user can withdraw a set amount of ether, then they have to wait one hour before they can withdraw more. This is not calling the contract at a later time, but making the withdraw function unavailable to the address for one hour. – ACluelessProgramer Jul 21 '17 at 19:07
  • Okay - reading the description again, and your comment, I was perhaps a bit hasty. I've retracted my suggested dupe :-) – Richard Horrocks Jul 21 '17 at 19:09
  • @RichardHorrocks Now worries! I think I was a bit unclear in asking. Thank you! – ACluelessProgramer Jul 21 '17 at 19:09
5

The block.timestamp should indicate approximately when the block was mined. But it is only an approximation, it depends on the precision of the clock of the machines working on it, also a miner can modify it. So it is not a very secure measure of the time but for your use case should be good.

From solidity documentation

block.timestamp (uint): current block timestamp as seconds since unix epoch.

You can do something like this:

mapping(address => uint) startTime;

function start() {
    startTime[msg.sender] = now;
}

function hasElapsed() constant return (bool) {
    if (now >= startTime[msg.sender] + 60 minutes) {
        // 60 minutes has elapsed from startTime[msg.sender]
        return true;
    }
    return false;
}
  • This is what I have been trying to do! Let me make sure I have this right: you are mapping the msg.sender to the current block (a uint), then checking to see if the current block is more than or equal to the msg.sender's time of transaction + 60 minutes, and finally doing whatever you need to do in the if function. – ACluelessProgramer Jul 22 '17 at 11:34
  • Actually, wouldn't be if (now <= startTime[msg.sender] + 60 minutes) with an less than equal to operator? So we can check as long as now is less or equal to now + 60 minutes? – ACluelessProgramer Jul 22 '17 at 11:44
  • In my example startTime[msg.sender] is the time where the watch has started, ie the user first request to the contract. Then startTime[msg.sender] + 60 minutes is 1 hour after the first request. In that case if now <= startTime[msg.sender] + 60 minutes is true, it implies that less than an hour has elapsed. – Ismael Jul 22 '17 at 20:50
0

Of course, per User will be difficult to enforce, as Ethereum only has Accounts, not Users. What's to prevent me from opening a dozen accounts and calling your Faucet at once?

Per Account, the answer above should work. My only concern would be the startTime mapping table, as being stateful, if the faucet is popular, how much gas would it consume on the mainnet?

  • I see your point, but this will the deployed for test ether (for now). I guess it will consume same gas on the testnet as well. – ACluelessProgramer Jul 22 '17 at 11:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.