Create Time State Machines with Realtime Block Timestamp Comparisons
This React component displays new status badges when a timestamp threshold is met. Useful for time-based games.
Getting Started
Follow the Project Setup instructions to start the project in your local machine and try the recipes yourself. You can also clone or navigate the repo to get just what you need.
A few things to remember:
NEAR native block timestamps accuracy is in nanoseconds, that's 18 0's, 1000000000000000000
But Javascript dates only handle up to the microseconds, that's 12 0's, 1000000000000
NEAR native block timestamps are in UTC, or GMT-0
While your app Date libraries may print the date in the user's local time
NEAR native block timestamps return an
u64
typeWhile the
chrono
Rust crate returnsi64
values
Knowing this will make your life easier when handling dates in smart-contracts. Let's begin.
Fetching dates from a React hook
Let's examine where does Prompt Wars use dates from the on-chain storage, see fetchMarketContractValues
:
These values are then used in this component to render a Counter
:
Setting the on-chain Timestamp storage
For example, for the Counter
component to render a countdown 5 minutes from the future, it uses ends_at
. Note that Timestamp
has an i64
(signed integer) as a type. While env::block_timestamp
returns an u64
(unsigned integer). The reason for this is that you want to prevent Rust overflow errors when doing time operations. A Rust overflow error happens when an unsigned integer breaks the -0 limit.
Comparing dates to determine time periods
Prompt Wars consists of 3 main time periods:
The game is active when
env::block_timestamp
is betweenstarts_at
andends_at
By this time, users may submit prompts
The game is in the REVEALING status when
env::block_timestamp
is greater thanends_at
and less thanresolution.window
By this time, the game is comparing all prompts with the source image and setting the result of each player in its own
OutcomeToken
The game is in the RESOLUTION status when
env::block_timestamp
is between theresolution.window
By this time, the game will set a winner by getting the result that's closest to 0
This time comparisons happen on-chain to prevent malicious manipulation and can be found here:
Automatic status checks
Lastly, in order for the UI to switch between statuses, a client-side interval checks for these flags in the UI side, but also a server-side cronjob will trigger smart-contract actions to reveal and resolve each game:
Client-side interval status checks
A simple useEffect
will fetch and detect changes on the contract time flags and update the status accordingly:
Last updated