Skip to main content
On most EVM chains like Ethereum, smart contracts cannot “wake up” on their own—every function call must be triggered by an externally owned account (EOA) or an off-chain bot. This means implementing time-based automation (like cron jobs) requires external infrastructure. Hedera changes this fundamentally. With the Hedera Schedule Service (HSS) via HIP-755 and HIP-1215, smart contracts on Hedera can schedule future calls to themselves or other contracts. The Hedera network itself stores and executes these scheduled transactions when the time comes—no off-chain bots required. This unlocks powerful new patterns:
  • On-chain cron jobs for DeFi rebalancing and automation
  • Time-based vesting and token releases
  • Recurring payments and subscriptions
  • DAO governance with time-delayed execution
In this tutorial, you’ll build a simple AlarmClock contract that demonstrates this unique capability by scheduling one-shot and recurring alarms entirely on-chain.
You can take a look at the complete code in the hss-schedule-sc-calls demo repository.

Prerequisites

  • ECDSA account from the Hedera Portal.
  • Basic understanding of Solidity.

Table of Contents

  1. Setup Project
  2. Step 1: Configure Hardhat
  3. Step 2: Create the AlarmClock Smart Contract
  4. Step 3: Deploy the Contract
  5. Step 4: Set a One-Shot Alarm
  6. Step 5: Set a Recurring Alarm
  7. Step 6: Monitor Alarm Triggers
  8. Step 7: Run Tests (Optional)
  9. Conclusion
  10. Additional Resources

Setup Project

Set up your project by initializing the hardhat project.
Make sure to select “Hardhat 3 -> Typescript Hardhat Project using Mocha and Ethers.js” and accept the default values. Hardhat will configure your project correctly and install the required dependencies.
Key differences in Hardhat 3:
  • compile → build
    npx hardhat compile is now npx hardhat build. This is the big one. The v3 migration guide explicitly shows using the build task.
  • project init switch
    v2 commonly used npx hardhat or npx hardhat init to bootstrap. In v3 it’s npx hardhat --init.
  • keystore helper commands are new
    v3’s recommended flow includes a keystore plugin with commands like npx hardhat keystore set HEDERA_RPC_URL and npx hardhat keystore set HEDERA_PRIVATE_KEY. These weren’t standard in v2.
  • Foundry-compatible Solidity tests
    In addition to offering Javascript/Typescript integration tests, Hardhat v3 also integrates Foundry-compatible Solidity tests that allows developers to write unit tests directly in Solidity
  • Enhanced Network Management
    v3 allows tasks to create and manage multiple network connections simultaneously which is a significant improvement over the single, fixed connection available in version 2. This provides greater flexibility for scripts and tests that interact with multiple networks.
📚 Learn more from the official Hardhat documentation.
Before we make any changes to our Hardhat configuration file, let’s set some configuration variables we will be referring to within the file later.
For HEDERA_RPC_URL, we’ll have https://testnet.hashio.io/api
For HEDERA_PRIVATE_KEY, enter the HEX Encoded Private Key for your ECDSA account from the Hedera Portal. We won’t need any additional dependencies for this tutorial since we’ll be interacting directly with the Schedule Service system contract. Now let’s remove the default contracts and scripts that come with the Hardhat project:

Install Dependencies

Next, install the required dependencies:
Note that we are installing the latest code from the main branch when we install @hiero-ledger/hiero-contracts. This also gets installed at @hashgraph/smart-contracts so we can easily call these contracts from our own contract.

Step 1: Configure Hardhat

Update your hardhat.config.tsfile in the root directory of your project. This file contains the network settings so Hardhat knows how to interact with the Hedera Testnet.
hardhat.config.ts

Step 2: Create the AlarmClock Smart Contract

Create a new Solidity file (AlarmClockSimple.sol) in your contracts directory:
contracts/AlarmClockSimple. sol
How It Works
  1. Schedule Service System Contract (0x16b): The contract interacts with the Hedera Schedule Service at the fixed address 0x16b, which provides the scheduleCall function.
  2. setAlarm function: When a user calls setAlarm(recurring, intervalSeconds), the contract:
    • Creates an Alarm struct in storage with the user’s address and target time
    • Calls _scheduleAlarm to schedule the future execution
  3. _scheduleAlarm (internal): This function:
    • Encodes the call data for triggerAlarm(alarmId)
    • Calls the Schedule Service at 0x16b with scheduleCall(... )
    • Specifies the target time (expirySecond), gas limit, and encoded call data
    • Emits AlarmScheduled event
  4. Scheduled Execution: When the scheduled time arrives, the Hedera network automatically executes the scheduled transaction, calling triggerAlarm(alarmId) on the contract.
  5. triggerAlarm function: This is called by the network (or can be manually triggered):
    • Increments the trigger counter
    • Emits AlarmTriggered event
    • For recurring alarms, schedules the next occurrence by calling _scheduleAlarm again
  6. HBAR Requirement: The contract must hold HBAR to pay for gas when scheduled transactions execute. Each execution (and re-scheduling for recurring alarms) deducts from the contract’s balance.
Let’s build this contract by running:
This command will generate the smart contract artifacts, including the ABI. We are now ready to deploy the smart contract.

Step 3: Deploy the Contract

Create a deployment script (deploy.ts) in scripts directory:
scripts/deploy.ts
Critical: Why Does the Contract Need HBAR?Every time a scheduled transaction executes (when the network automatically calls triggerAlarm), gas fees must be paid. Since the contract itself is the payer for these scheduled executions, it must hold HBAR.For recurring alarms:
  • Each triggerAlarm execution consumes gas
  • Each triggerAlarm then schedules the next alarm (more gas)
  • If the contract runs out of HBAR, scheduled executions will fail and recurring alarms will stop
Best practice: Fund the contract with enough HBAR based on:
  • Your SCHEDULED_CALL_GAS_LIMIT (set to 2,000,000 in this example)
  • Expected number of alarm executions
  • For recurring alarms, estimate how long you want them to run
You can always add more HBAR by sending a transaction to the contract address.
Deploy your contract by executing the script:
Copy the deployed contract address and set it as an environment variable for the next steps.
Expected output:
Set the contract address as an environment variable:
In order to decode events emitted from the contract, the contract must be verified.
You can then upload the verify-bundles/AlarmClockSimple/metadata.json file to Hashscan to verify this contract.

Step 4: Set a One-Shot Alarm

Create a script (setOneShot.ts) in your scripts directory to set a one-shot alarm.
scripts/setOneShot.ts
How It Works
  1. Connects to your deployed AlarmClockSimple contract
  2. Calls setAlarm(false, 10) to schedule a one-shot alarm in 10 seconds
  3. The contract immediately schedules a transaction with the Schedule Service
  4. After ~10 seconds, the network will automatically execute triggerAlarm(0)
  5. You can view the AlarmScheduled and AlarmTriggered events on HashScan
Important: The alarm will fire automatically—no further action needed from you!
Run the script:
Expected output:

Step 5: Set a Recurring Alarm

Create a script (setRecurring.ts) in your scripts directory to set a recurring alarm.
scripts/setRecurring.ts
How Recurring Alarms Work
  1. You call setAlarm(true, 10) to set a recurring alarm with a 10-second interval
  2. The contract schedules the first triggerAlarm call for 10 seconds from now
  3. When the scheduled time arrives, the network executes triggerAlarm:
    • Increments the trigger counter
    • Emits AlarmTriggered event
    • Automatically schedules the next alarm for 10 seconds later
  4. This creates a self-sustaining on-chain timer!
The alarm will keep firing indefinitely until:
  • The contract runs out of HBAR (scheduled execution fails)
  • You modify the contract logic to stop it
  • A scheduling error occurs
This is perfect for:
  • DeFi rebalancing strategies
  • Periodic token distributions
  • Recurring payment systems
  • Time-based governance actions
Run the script:
Expected output:

Step 6: Monitor Alarm Triggers

After setting your alarms, you can monitor their execution on HashScan, Hedera’s block explorer.

Viewing Events

Navigate to your contract’s events page:
You’ll see two types of events: 1. AlarmScheduled Event
This event is emitted when an alarm is scheduled. For recurring alarms, you’ll see this event multiple times—once for each scheduled occurrence. 2. AlarmTriggered Event
This event is emitted when the scheduled time arrives and the alarm fires.

Viewing Scheduled Transactions

You can also view the actual scheduled transaction executions on HashScan: Example Flow:
  1. setAlarm transaction: View on HashScan
    • This is when you call setAlarm()
    • Emits AlarmScheduled event
  2. Scheduled triggerAlarm execution: View on HashScan
    • This is the automatic execution by the network
    • Notice the transaction was triggered by the schedule service, not by an EOA
    • Emits AlarmTriggered event
Understanding the Transaction FlowWhen you look at the scheduled transaction on HashScan on the trace tab, you will notice:
  • The “From” address will be the contract itself (or show as scheduled execution)
  • The “To” address is the contract address
  • The “Function” called is triggerAlarm(alarmId)
  • You’ll see the gas consumed by the execution
  • No external account initiated this call—it was executed by the network’s Schedule Service
This is the key difference from traditional EVM chains!

Step 7: Run Tests (Optional)

You can find both types of tests in the hedera-code-snippets repository. You will find the following files:
  • contracts/AlarmClockSimple.t.sol
  • Initial state: Verifies contract deploys with nextAlarmId starting at 0.
  • Alarm creation: Confirms setAlarm properly creates alarm structs with correct user, time, and interval values.
  • Authorization: Ensures only the alarm owner or the contract itself can trigger alarms (non-owners are rejected).
  • One-shot enforcement: Validates that one-shot alarms can only be triggered once and revert on subsequent attempts.
  • HBAR handling: Verifies the contract can receive HBAR via receive() function for funding scheduled executions.
  • test/AlarmClockSimple.ts
  • Deployment and setup: Deploys the contract with 10 HBAR funding, creates a separate funded user wallet, and validates initial state.
  • One-shot alarms: Sets a one-shot alarm, verifies the AlarmScheduled event is emitted, and confirms alarm details are correctly stored.
  • Recurring alarms: Sets a recurring alarm and validates it’s configured with the recurring flag and proper interval.
  • Manual triggering: Tests that users can manually trigger their own alarms and verifies the AlarmTriggered event is emitted with correct data.
  • Authorization checks: Ensures non-owners cannot trigger someone else’s alarm and that one-shot alarms cannot be triggered twice.
  • Network integration: All tests run against Hedera testnet as the Schedule Service precompile (0x16b) is not available locally.
Copy these files and then run the tests:
You can also run both the solidity and mocha tests altogether:
Which should output something like:

Conclusion

You’ve just built an on-chain alarm clock that demonstrates Hedera Schedule Service’s unique capability—scheduling future smart contract calls without any off-chain infrastructure! In this tutorial, you learned how to:
  • Interact with the Schedule Service system contract
  • Schedule one-shot alarms that fire once at a future time
  • Create recurring alarms that automatically reschedule themselves
  • Monitor scheduled executions on HashScan
  • Understand the HBAR requirements for scheduled transactions

Key Takeaways

  • Hedera’s Schedule Service enables truly autonomous smart contracts. No off-chain bots or keeper networks required
  • Contracts must hold HBAR to pay for scheduled execution gas fees
  • Recurring patterns create self-sustaining on-chain automation. Perfect for DeFi, vesting, payments, and governance
  • This capability doesn’t exist on most EVM chains. It’s a fundamental difference in what’s possible on Hedera
Continue exploring the tutorial about dynamic rebalancing through scheduled execution to see a real-world application of this technology—building a capacity-aware DeFi rebalancer that automatically adjusts its strategy based on network conditions.

HSS x EVM - Dynamic Rebalancing Through Scheduled Execution (Part 2)


Additional Resources

Check out the resources below to learn more about Hedera’s Schedule Service and HIP-1215!

Writer: Kiran Pachhai, Developer Advocate