Sui.

Post

Share your knowledge.

Benjamin XDV.
Jul 14, 2025
Expert Q&A

Understanding the Sui Clock Module and Timestamp Usage

I'm building time-sensitive logic in Sui Move (e.g., token vesting, auction deadlines) but struggling with reliable timestamp handling. Key questions:

  1. Clock Object: Why does Sui need a shared Clock instead of block timestamps?
  2. Accuracy: How precise are these timestamps compared to block times?
  3. Usage Patterns: Best practices for time-locks, deadlines, and scheduling?
  4. Testing: How to mock time in unit tests?

Current Issues:

  • Basic sui::clock usage works but feels restrictive
  • Unsure how to handle time across different shards/validators
  • Testing time-dependent logic is flaky
  • Sui
0
2
Share
Comments
.

Answers

2
Arnold.
Jul 14 2025, 14:47

1. Sui Clock Fundamentals

Why a Shared Clock?
Sui’s parallel execution model means:

  • No guaranteed block order → can’t use block numbers/timestamps
  • Clock is a shared object providing consensus-backed time

Core Structure:

module sui::clock {  
    struct Clock has key {  
        id: UID,  
        timestamp_ms: u64,  
    }  
}  

Key Properties:

  • Updated every 2 seconds (configurable by validators)
  • Milliseconds precision (vs. Ethereum’s ~12s blocks)
  • Immutable – can’t be modified by contracts

2. Practical Usage Patterns

Basic Time Check
use sui::clock;  

public entry fn execute_if_ready(  
    clock: &Clock,  
    lock: &mut LockedAsset  
) {  
    assert!(clock.timestamp_ms >= lock.unlock_time, ELocked);  
    // Release assets  
}  
Deadline Enforcement
struct Auction has key {  
    id: UID,  
    end_time: u64, // Stored as Clock timestamp  
    highest_bid: u64  
}  

public entry fn bid(  
    auction: &mut Auction,  
    clock: &Clock,  
    bid_amount: u64  
) {  
    assert!(clock.timestamp_ms < auction.end_time, EAuctionEnded);  
    // Process bid  
}  
Time-Locked Actions
struct VestingSchedule has key {  
    id: UID,  
    start_time: u64,  
    cliff_duration: u64 // In milliseconds  
}  

public fun claimable_amount(  
    vesting: &VestingSchedule,  
    clock: &Clock  
): u64 {  
    let elapsed = clock.timestamp_ms - vesting.start_time;  
    // Linear vesting math  
}  

3. Advanced Considerations

Shard Consistency
  • All shards see the same Clock timestamp within a transaction
  • For cross-shard ops, pass &Clock as a shared object reference
Gas Optimization
  • Store relative times (e.g., duration_ms: u64) instead of absolute where possible
  • Reuse the same Clock reference across functions
Error Handling
const MAX_CLOCK_DRIFT_MS: u64 = 3000; // 3s tolerance  

public fun validate_clock(clock: &Clock) {  
    assert!(tx_context::epoch(ctx) == clock.epoch(), EStaleClock);  
    assert!(clock.timestamp_ms <= tx_context::now_ms(ctx) + MAX_CLOCK_DRIFT_MS, EInvalidTime);  
}  

4. Testing Strategies

Mocking Clock in Tests
#[test_only]  
fun mock_clock(timestamp_ms: u64): Clock {  
    Clock { id: test_scenario::new_object(ctx), timestamp_ms }  
}  

#[test]  
fun test_vesting() {  
    let clock = mock_clock(1000);  
    let vesting = VestingSchedule { start_time: 0, ... };  
    // Test claimable amount at t=1000  
}  
Epoch Transition Tests
#[test]  
fun test_clock_epoch_change() {  
    let mut scenario = test_scenario::begin(...);  
    // Advance epoch  
    test_scenario::next_epoch(&mut scenario);  
    let clock = test_scenario::take_shared<Clock>(scenario);  
    assert!(clock.epoch() == 1, EEpochError);  
}  
0
Comments
.
24p30p.
Jul 14 2025, 13:53

If you’re working on time-sensitive logic like auctions or vesting schedules in Sui Move, the sui::clock module is your go-to way of tracking time. Sui doesn’t rely on block timestamps like Ethereum or Solana because it aims for deterministic execution and parallelism. That’s why it uses a shared Clock object, which updates once per checkpoint and gives you a canonical source of time.

You interact with time by reading from this shared Clock object (usually passed into entry functions) using clock.timestamp. This value is updated roughly every second and gives you the current UNIX timestamp in seconds. While it’s not tied to every block like in EVM, it’s precise enough for practical use cases like token unlocks or bid expiries — just not microsecond-level precision.

When building time-based logic, always pass in the Clock object explicitly so that your Move function can read it and compare timestamps against your stored deadlines. To avoid rigid behavior, use grace periods or leeway in your comparisons (if current_time > unlock_time + buffer), and avoid relying on exact seconds.

For testing, Sui allows you to mock the Clock in unit tests by creating your own instance of the shared object with a custom timestamp. That way, you can simulate future conditions without needing real time to pass. Just construct the Clock manually with a set value in your #[test] functions.

If you feel restricted, it’s likely due to how Sui protects the Clock from mutation outside checkpoints. You’ll need to design your modules to expect timestamps as input and read them from the official shared object. Avoid creating your own time source, as it breaks determinism.

🔗 Learn more on Sui Clock module

-1
Comments
.

Do you know the answer?

Please log in and share it.

Sui is a Layer 1 protocol blockchain designed as the first internet-scale programmable blockchain platform.

420Posts611Answers
Sui.X.Peera.

Earn Your Share of 1000 Sui

Gain Reputation Points & Get Rewards for Helping the Sui Community Grow.

Reward CampaignJuly