Bird
Raised Fist0
Blockchain / Solidityprogramming~10 mins

Timelock pattern in Blockchain / Solidity - Step-by-Step Execution

Choose your learning style10 modes available

Start learning this pattern below

Jump into concepts and practice - no test required

or
Recommended
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Concept Flow - Timelock pattern
Start
Request Action
Set Timelock Expiry
Wait Until Expiry
Check Current Time >= Expiry?
NoWait
Yes
Execute Action
End
The Timelock pattern delays execution of an action until a set time has passed, ensuring a waiting period before the action runs.
Execution Sample
Blockchain / Solidity
uint public unlockTime;

function requestAction() public {
  unlockTime = block.timestamp + 1 days;
}

function executeAction() public {
  require(block.timestamp >= unlockTime, "Action is locked");
  // action code
}
This code sets a future unlock time when an action is requested, then only allows execution after that time.
Execution Table
StepActionblock.timestampunlockTimeConditionResult
1Call requestAction()10000001000000 + 86400 = 1086400N/AunlockTime set to 1086400
2Call executeAction() at time 1005000100500010864001005000 >= 1086400?False - revert, cannot execute
3Call executeAction() at time 1086400108640010864001086400 >= 1086400?True - action executes
4Call executeAction() at time 1086500108650010864001086500 >= 1086400?True - action executes
💡 Execution stops if current time is less than unlockTime; action only runs after unlockTime.
Variable Tracker
VariableStartAfter Step 1After Step 2After Step 3Final
unlockTime01086400108640010864001086400
block.timestampN/A1000000100500010864001086500
Key Moments - 3 Insights
Why can't executeAction run immediately after requestAction?
Because unlockTime is set to a future timestamp (current time + 1 day). The execution_table row 2 shows the condition fails when current time is less than unlockTime.
What happens if executeAction is called exactly at unlockTime?
The condition block.timestamp >= unlockTime is true, so the action executes successfully as shown in execution_table row 3.
Does the unlockTime change after it is set?
No, unlockTime stays the same until requestAction is called again. The variable_tracker shows unlockTime remains constant after step 1.
Visual Quiz - 3 Questions
Test your understanding
Look at the execution_table, what is the value of unlockTime after calling requestAction()?
A1000000
B1086400
C0
D1005000
💡 Hint
Check execution_table row 1 under unlockTime column.
At which step does the condition block.timestamp >= unlockTime become true for the first time?
AStep 1
BStep 2
CStep 3
DStep 4
💡 Hint
See execution_table Condition and Result columns for each step.
If the unlockTime was set to current time + 2 days instead of 1 day, how would step 2 change?
ACondition would still be false at step 2
BunlockTime would be less than block.timestamp
CCondition would be true at step 2
DexecuteAction would execute immediately
💡 Hint
Compare unlockTime and block.timestamp values in execution_table row 2.
Concept Snapshot
Timelock pattern delays actions until a set future time.
Set unlockTime = current time + delay.
Only allow execution if current time >= unlockTime.
Prevents immediate execution, adds security delay.
Common in blockchain governance and contracts.
Full Transcript
The Timelock pattern is a way to delay an action in a blockchain contract until a certain time has passed. First, when an action is requested, the contract sets a future unlockTime by adding a delay (like 1 day) to the current block timestamp. Then, when trying to execute the action, the contract checks if the current time is at or past the unlockTime. If not, the action is blocked. This ensures a waiting period before the action runs, adding security and transparency. The example code sets unlockTime in requestAction and requires the current time to be greater or equal in executeAction. The execution table shows that calling executeAction too early fails, but succeeds once the unlockTime is reached or passed. Variables like unlockTime stay fixed until reset. This pattern is useful to prevent sudden changes or actions in blockchain systems.

Practice

(1/5)
1.

What is the main purpose of the Timelock pattern in blockchain smart contracts?

easy
A. To delay certain actions until a specific time has passed
B. To speed up transaction processing
C. To encrypt user data
D. To reduce gas fees

Solution

  1. Step 1: Understand the Timelock pattern concept

    The Timelock pattern is designed to delay actions in smart contracts until a set time has passed.
  2. Step 2: Identify the purpose of the delay

    This delay helps protect users by preventing instant changes that could be harmful or unexpected.
  3. Final Answer:

    To delay certain actions until a specific time has passed -> Option A
  4. Quick Check:

    Timelock pattern = delay actions [OK]
Hint: Timelock means waiting before action happens [OK]
Common Mistakes:
  • Thinking it speeds up transactions
  • Confusing with encryption
  • Assuming it lowers gas fees
2.

Which of the following Solidity code snippets correctly enforces a timelock using block.timestamp?

function execute() public {
  require(__________, "Too early to execute");
  // action code
}
easy
A. block.timestamp >= unlockTime
B. block.timestamp < unlockTime
C. block.number >= unlockTime
D. block.difficulty > unlockTime

Solution

  1. Step 1: Understand the condition for timelock

    The action should only execute if the current time is equal or after the unlock time.
  2. Step 2: Choose the correct comparison

    Using block.timestamp >= unlockTime ensures the function runs only after the unlock time.
  3. Final Answer:

    block.timestamp >= unlockTime -> Option A
  4. Quick Check:

    Time check uses block.timestamp >= unlockTime [OK]
Hint: Use block.timestamp and >= for timelock checks [OK]
Common Mistakes:
  • Using < instead of >=
  • Using block.number instead of block.timestamp
  • Using unrelated block properties
3.

What will be the output of the following Solidity function call if block.timestamp is 1650000000 and unlockTime is 1650000100?

function canExecute() public view returns (bool) {
  return block.timestamp >= unlockTime;
}
medium
A. true
B. Revert with error
C. Compilation error
D. false

Solution

  1. Step 1: Compare block.timestamp and unlockTime values

    Given block.timestamp = 1650000000 and unlockTime = 1650000100, block.timestamp is less than unlockTime.
  2. Step 2: Evaluate the return statement

    The expression block.timestamp >= unlockTime evaluates to false.
  3. Final Answer:

    false -> Option D
  4. Quick Check:

    1650000000 >= 1650000100 = false [OK]
Hint: Compare timestamps carefully for true/false output [OK]
Common Mistakes:
  • Assuming >= means true when timestamp is smaller
  • Confusing block.timestamp with block.number
  • Expecting errors instead of boolean
4.

Identify the error in this Solidity timelock function and choose the fix:

uint256 public unlockTime;

function execute() public {
  require(block.timestamp > unlockTime, "Too early");
  // perform action
}
medium
A. Use block.number instead of block.timestamp
B. Change block.timestamp > unlockTime to block.timestamp >= unlockTime
C. Remove the require statement
D. Change unlockTime to block.timestamp

Solution

  1. Step 1: Analyze the require condition

    The condition block.timestamp > unlockTime disallows execution exactly at unlockTime.
  2. Step 2: Adjust condition to allow execution at unlockTime

    Changing to block.timestamp >= unlockTime allows execution starting from unlockTime.
  3. Final Answer:

    Change block.timestamp > unlockTime to block.timestamp >= unlockTime -> Option B
  4. Quick Check:

    Use >= to include unlockTime moment [OK]
Hint: Use >= to allow execution at unlock time [OK]
Common Mistakes:
  • Using > excludes unlockTime moment
  • Removing require loses protection
  • Using block.number causes wrong timing
5.

You want to create a timelock contract that allows an admin to schedule a withdrawal only after 1 day from scheduling. Which approach correctly implements this?

contract Timelock {
  address public admin;
  uint256 public unlockTime;

  constructor() {
    admin = msg.sender;
  }

  function scheduleWithdrawal() public {
    require(msg.sender == admin, "Not admin");
    unlockTime = block.timestamp + 86400; // 1 day
  }

  function withdraw() public {
    require(msg.sender == admin, "Not admin");
    require(block.timestamp >= unlockTime, "Too early");
    // withdrawal logic
  }
}
hard
A. Admin cannot schedule withdrawal
B. Withdrawal can happen immediately after scheduling
C. Correctly enforces 1-day delay before withdrawal
D. unlockTime is set incorrectly causing errors

Solution

  1. Step 1: Check scheduling sets unlockTime correctly

    The scheduleWithdrawal function sets unlockTime to current time plus 86400 seconds (1 day).
  2. Step 2: Verify withdraw enforces timelock

    The withdraw function requires current time to be at or after unlockTime, enforcing the delay.
  3. Final Answer:

    Correctly enforces 1-day delay before withdrawal -> Option C
  4. Quick Check:

    UnlockTime = now + 1 day, withdraw requires >= unlockTime [OK]
Hint: Add 86400 seconds and check block.timestamp >= unlockTime [OK]
Common Mistakes:
  • Not adding delay in schedule function
  • Using > instead of >= in withdraw
  • Not restricting functions to admin