Roughtime as Timestamp Oracle

Sometimes a CKB script (also known as smart contract) requires current time as input. Because the deterministic nature of CKB transactions, a script has no access to timestamp in block header as on Ethereum. Several alternatives have been devised to provide the equivalent function, such as since field, header dep + ckb_load_header_by_field syscall, or more complex schemes.

The idea here is another one and it reuses existing Internet infrastructure, Roughtime. Roughtime is a protocol that aims to achieve rough time synchronisation in a secure way that doesn’t depend on any particular time server. It is proposed by Google and Cloudflare, and already provided by many including Chainpoint and int08h. Roughtime is a interactive authenticated protocol in which a client can submit a request with nonce to the server and the server must sign the nonce together with current timestamp as the response.

Now imagine a design pattern like this, for any operation which can only be performed after timestamp T on CKB:

  1. create an operation cell Cell_{op}, with timestamp T embedded in data or lock args;
  2. the lock of Cell_{op} requires a witness W = W_{op} + W_{t} such that: a) contains the operator’s signature W_{op}, b) an timestamp witness W_{t} from any one or multiple Roughtime servers, and c) $W_{t} must include a timestamp larger or equal than T;
  3. W_t is a Roughtime response to a request which uses the outpoint of Cell_{op} as nonce.

This way the Cell_{op} can be unlocked only after time T.

Roughtime uses EdDSA which can be easily supported on CKB (thanks to the cryptography abstraction). The accuracy of Roughtime is good enough for layer 1 applications. The scheme is permissionless and decentralized in that a script can choose any one or multiple Roughtime servers as oracle. The timestamp witness are auditable. The reputation stake of some Roughtime servers are higher than many decentralized oracles we see today.


It’s more trickier to implement operations that can only performe before T. A simple idea which does NOT work is like this:

  1. unlock Cell_{op} and create an intermediate state Cell'_{op};
  2. use Cell'_{op} as a fresh nonce to get a W'_t from Roughtime server;
  3. If the timestamp in W'_t is smaller than T, Cell'_{op} can be unlocked to perform the actual action.

The problem is the operator could retain a valid W'_t at wish and use it to unlock Cell'_{op} at any time after T.In order to achieve “only perform before T”, we should rely on on-chain time instead of a time oracle. Here’s a pattern that works:

  1. unlock Cell_{op} and create an intermediate state Cell'_{op} in tx1;
  2. create a following transaction tx2 with Cell'_{op} as an input and its including block header as header dep, and operation performed state Cell''_{op} as output.
  3. tx2 is valid only if the timestamp in header dep is smaller than T.

This is indeed nice when it works, tho one question I have is: what would be the incentives for running a roughtime service? For an Internet world, you could say Google gets incentives in the form of fame by running such a server, but in a decentralized world, people naturally want to run away from big monopoly like Google. What we might end up facing, is a dozen of small independent providers, how should we monetize them then?

Initially servers running by Googles and altruists should be good enough for early dapps. If the ecosystem grows larger and the economic value of these timestamp oracles becomes more explicit, for-profit services will emerge to provide better services like more fine-grained timestamp, unlimited API access, timestamp insurance etc. It’s also possible to build a timestamp DAO with its own token economics, incentivize independent providers to provide a high-quality and sustainable service collaboratively.

If the timestamp of W_{t} is less than W_{op} , does it mean that no one could prove the reality of the timestamp from Cell operator ?