The Solidity keyword now
does return the underlying node's system time,
but this could be manipulated by that particular node (e.g. to do miner frontrunning).
One possibility is you could have a smart contract that participants can
regularly submit a time for the current block, which would be correct plus or minus a few blocks (called a FUDGE_FACTOR_IN_BLOCKS below).
On Ethereum, each block is found after roughly 15 seconds, so you could write a smart contract that looks roughly like (this might not compile but gives the idea)
contract TimeServer {
uint256 FUDGE_FACTOR_IN_BLOCKS = 2;
uint256 public lastBlockNumber;
uint256 public lastBlockTime;
constructor(uint256 firstBlockNumber) {
require(abs(firstBlockNumber - block.number) < FUDGE_FACTOR_IN_BLOCKS));
lastBlockNumber = block.number;
lastBlockTime = now;
}
function submitNewTime(uint256 newBlockNumber, uint256 newBlockTime) public {
uint blockDiff = newBlockNumber - lastBlockNumber;
require(blockDiff > 0, `New block number must be later than last block')'
uint timeDiff = newBlockTime - lastBlockTime;
require(abs(timeDiff / 15) - blockDiff) < FUDGE_FACTOR_IN_BLOCKS,
'Submitted block time is off by more than +/- fudge factor.') )
lastBlockNumber = newBlockNumber;
lastBlockTime = newBlockTime;
}
}
I'm not sure if now
is in milliseconds or seconds, so check first.
As long as the contract is constructed correctly (given within two blocks of the actual block number, on an honest node), then every other call to submitNewTime
will also be within two blocks of the correct time and block number.
Participants could call this submitNewTime
periodically as a public service (since it costs gas), perhaps every few blocks to adjust for drift. Consumers can access the lastBlockTime
and lastBlockNumber
members as a lower bound on time (it's as stale as the last time anyone called submitNewTime
)
now
keyword to get the current block timestamp in a Dapp. – Carlos Fuentes Aug 8 at 20:38