How safe is it to use block.timestamp as contract expiration time? If a miner provides an incorrect timestamp in a block header, how much can it be off before it is rejected by other nodes? Is there a strategy to make a contract more robust to this?

up vote 28 down vote accepted

Not especially, but it depends on what the use case is.

Block times are subject to the following constraints:

  • If you stamp your block with a time too far in the future, no one else will build on it (miners will not build on a block timestamped "from the future").
  • Your block time cannot be stamped with an earlier time than its parent.
  • Difficulty is kept lowest (best deal for miners) by not stamping blocks as earlier than they actually occur.

Taken together, these factors suggest that most blocks produced by small hashrate miners who are not trying to manipulate anything will be pretty close to accurate. However, it is trivial for a more powerful miner to manipulate timestamps over short periods, especially if there is something to be gained by doing this.

Ultimate, there is no cryptographic way to verify the timestamp itself--only the ordering of certain cryptographic structures. Therefore block.timestamp needs to be supplemented with some other strategy in the case of high-value/risk applications.

First, a basic: using strict equality == block.timestamp would not be safe, since a block with that exact timestamp may never get mined. So use >= block.timestamp

Now it depends on what happens when the contract "expiration time" is reached. For reasons similar to the safe use of BLOCKHASH, block.timestamp should only be safely used if the total amount of value resting on what the contract does at "expiration time", is lower than what a miner earns by mining a single block. If the outcome of a lottery worth millions depends on block.timestamp, the timestamp will probably be manipulated.

The Yellow Paper does not have any answer to "how much can it be off before it is rejected by other nodes". If block.timestamp is used, the only guarantee (equation 43) is that block.timestamp is greater than that of its parent. But there are game theoretic reasons why block.timestamp won't be significantly wrong.

From the Solidity docs another thing to watch for is: You publish a transaction at a time X, this transaction contains some code that calls block.timestamp and is included in a block whose timestamp is Y and this block is included into the canonical chain (published) at a time Z. The value of block.timestamp will be identical to Y, and X <= Y <= Z

  • Maybe I should elaborate more in my answer: there are ways for larger miners to manipulate timestamps while incurring lower costs than the value of a single block reward. So the use of block.timestamp cannot be made strictly safe by only using low values the way BLOCKHASH randomness can be. – Jeff Coleman Jan 23 '16 at 0:19
  • I can edit or strikethrough my answer and refer to the ways larger miners can manipulate timestamps with low costs... what should I refer to? – eth Jan 23 '16 at 0:50

Your Answer

 

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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