HTLC explained
Understand how Hash Time-Locked Contracts enable trustless cross-chain asset exchanges. Learn about hashlocks, timelocks, and why the mechanism is cryptographically secure.
Hash Time-Locked Contracts (HTLCs) enable trustless asset exchanges across different blockchains. This page explains how the mechanism works and why it provides strong security guarantees.
The two core components
Hashlock: the cryptographic lock
A hashlock is a cryptographic puzzle created by hashing a secret value:
hashlock = keccak256(secret)Only someone who knows the original secret can "unlock" the hashlock. Think of it like a combination lock where only the secret holder knows the combination.
Key properties of the hashlock:
- No one can figure out the secret from the hashlock alone
- The same secret always produces the same hashlock
Timelock: the deadline
A timelock is a deadline after which the settlement expires. It serves two purposes:
- Protection from stuck assets - If something goes wrong, assets are not locked forever
- Coordination mechanism - Creates a window during which the exchange must complete
How HTLC ensures atomicity
The best way to understand HTLC security is through a concrete example.
Example: Bank sells bonds to an Investor
Setup:
- Investor has 100,000 USDC on Polygon
- Bank has 1,000 BOND tokens on Ethereum
- They want to exchange these assets atomically
Step 1: Bank generates the secret
The Bank generates a random secret and computes the hashlock:
- Secret:
0x7a8b9c...(only the Bank knows this) - Hashlock:
keccak256(secret) = 0xdef456...(shared with the Investor)
Step 2: Bank creates settlement on Ethereum
| Field | Value |
|---|---|
| Flow | Bank → Investor: 1,000 BOND |
| Hashlock | 0xdef456... |
| Timelock | January 15, 2025 at 12:00 PM |
The Bank approves, locking 1,000 BOND into the settlement contract.
Step 3: Investor creates settlement on Polygon
The Bank shares only the hashlock (not the secret) with the Investor.
| Field | Value |
|---|---|
| Flow | Investor → Bank: 100,000 USDC |
| Hashlock | 0xdef456... (same as Ethereum) |
| Timelock | January 14, 2025 at 12:00 PM (24 hours before Ethereum) |
The Investor approves, locking 100,000 USDC into the settlement contract.
Both settlements are now in the Armed state, waiting for the secret.
Step 4: The swap executes
- Bank reveals secret on Polygon (January 13) - Settlement executes, Bank receives 100,000 USDC
- Secret is now public - The Investor can see it on-chain
- Investor reveals secret on Ethereum (January 13) - Settlement executes, Investor receives 1,000 BOND
Both parties received their assets. The exchange was atomic across chains.
Why HTLC is secure
The Investor cannot cheat
The Investor might try to claim the Bank's BOND on Ethereum without providing USDC. To do this, they would need to reveal the secret on Ethereum.
But the Investor only knows the hashlock, not the secret.
The hashlock is created using keccak256, a cryptographic hash function with these properties:
- One-way function - Given the hashlock, it's computationally impossible to reverse-engineer the secret
- Brute force is impractical - The secret is a 256-bit value with 2^256 possibilities. Even trying 1 trillion guesses per second would take longer than the age of the universe
- Collision resistance - No other value produces the same hashlock
The only way the Investor can execute the Ethereum settlement is to wait for the Bank to reveal the secret on Polygon first.
The Bank cannot cheat
After revealing the secret on Polygon, the Bank cannot withdraw their BOND on Ethereum because:
- The Ethereum timelock doesn't expire until January 15
- The Investor has until then to use the (now public) secret
- The Bank's BOND remain locked in the settlement contract
Timelock order is critical
The timelocks must be staggered correctly:
Correct order: Polygon expires January 14, Ethereum expires January 15
The Investor has 24 hours after the secret is revealed on Polygon to use it on Ethereum.
If timelocks were reversed:
| Chain | Reversed Timelocks (UNSAFE) | Correct Timelocks |
|---|---|---|
| Polygon (Investor → Bank: USDC) | January 15, 12:00 PM | January 14, 12:00 PM |
| Ethereum (Bank → Investor: BOND) | January 14, 12:00 PM | January 15, 12:00 PM |
Setup (January 12):
- Bank creates settlement on Ethereum with January 14 timelock (WRONG - too early)
- Investor creates settlement on Polygon with January 15 timelock
- Both settlements are Armed
Bank waits strategically:
- Bank does NOT reveal the secret yet
- Both settlements remain in Armed state
The Exploit begins (January 14 at 12:01 PM):
- Ethereum timelock expires (January 14 deadline passed)
- Bank calls
withdraw()on Ethereum settlement - Bank receives their 1,000 BOND back (settlement expired without executing)
The Exploit completes (January 14 at 12:30 PM):
- Polygon settlement is still valid (doesn't expire until January 15)
- Bank reveals secret on Polygon
- Bank receives 100,000 USDC from Polygon
Final State:
- Bank has: 100,000 USDC (claimed from Polygon) + 1,000 BOND (withdrawn from Ethereum)
- Investor has: Lost 100,000 USDC, received nothing
- Investor cannot claim BOND because Ethereum settlement already expired and was withdrawn
The key rule: When you don't have the secret, make sure the cutoff date of the HTLC that you create is before the cutoff date of the HTLC leg that has the secret. This ensures you have time to use the secret after it's revealed, before your settlement expires.
Timelock rule
The settlement where you receive assets should have an earlier timelock than the settlement where you send assets. This ensures you have time to claim your assets after the secret is revealed.
How XvP implements HTLC
XvP settlements incorporate HTLC with these features:
| Feature | Implementation |
|---|---|
| Secret generation | UI can generate secrets, or you can provide your own |
| Hashlock verification | Contract validates secret matches hashlock |
| Armed state | All local senders must approve before secret can be revealed |
| Auto-execute | When enabled, settlement executes automatically when secret is revealed |
| Cutoff date | Enforces the timelock expiration |
The revealSecret() function:
- Validates the provided secret matches the hashlock
- Confirms all local senders have approved
- If auto-execute is enabled, executes all local flows atomically
- Records the secret on-chain for transparency
Failure scenarios
| Scenario | What happens |
|---|---|
| Bank never reveals secret | Both settlements expire, all parties withdraw their locked assets |
| Investor never approves on Polygon | Bank's BOND remain locked until Ethereum timelock expires |
| Network congestion delays Investor | If Investor can't use secret before Ethereum expires, they lose the trade |
To mitigate network delays, set timelocks with sufficient buffer (24-48 hours between chains is recommended).
Further reading
Overview
HTLC settlements coordinate asset exchanges across different blockchains using hash time-locked contracts. Learn when to use HTLC and how cross-chain coordination works.
Walkthrough
Follow a complete multi-party cross-chain settlement where a Builder sells tokenized real estate to two Buyers, with a Notary receiving fees across Ethereum and Polygon.