Skip to main content
Available on SKALE Base and SKALE Base Sepolia — Conditional Transactions are available on mainnet and testnet. Contact the SKALE team at https://discord.gg/skale for access and feedback.

Why Conditional Transactions?

Encrypted Transactions decrypt everything at finality — useful for single-shot protection, but limited when you need persistent private state. Conditional Transactions (CTX) solve this by letting smart contracts decide when and what to decrypt, based on arbitrary Solidity conditions. Each decryption request queues a callback via an ephemeral wallet in a later block, enabling multi-step autonomous workflows where data is only revealed when conditions are met.

What Are Conditional Transactions?

Conditional Transactions (CTX) let smart contracts conditionally trigger decryption of encrypted data and receive the results in a callback. Unlike Encrypted Transactions (which decrypt automatically at finality), CTX decryption only happens when a contract explicitly requests it — and the decrypted data is delivered as a transaction from an ephemeral wallet in a later block. The flow is:
  1. Condition in Solidity — Your contract evaluates some condition (e.g., “has the deadline passed?”)
  2. submitCTX — If the condition is met, your contract calls submitCTX with encrypted arguments
  3. Validators queue — The network queues a callback transaction via an ephemeral wallet (a unique address generated per call)
  4. Callback in block N+1 — The queued transaction executes, delivering decrypted data to your contract’s onDecrypt function
The “conditional” part is that decryption and callback execution only happen if and when your contract’s Solidity logic calls submitCTX.

Quick Example

How It Works in Detail

submitCTX — The Condition Trigger

Returns the address of the ephemeral wallet that will execute the callback. Each call generates a unique address.

onDecrypt — The Callback

onDecrypt is called by the ephemeral wallet. The validator committee decrypts encryptedArgs during execution and passes them as decryptedArgs.

⚠️ Security: Protect onDecrypt

Because onDecrypt is a public callback, anyone could call it directly if you don’t restrict access. Each submitCTX call generates a new, unique ephemeral wallet — so you must track which addresses are authorized:
Without this check, an attacker could call onDecrypt with arbitrary arguments or replay old callbacks.

Complete Example

The following contract lets an owner store an encrypted value and grant viewers access via re-encryption. Each viewer gets a unique CTX callback:

CTX Chaining

onDecrypt can call submitCTX again, creating chains of conditional decryption across multiple blocks — each step uses a new ephemeral wallet:
Each step is a separate block. Each submitCTX generates a unique ephemeral wallet. The chain terminates when a callback doesn’t call submitCTX.

Chaining Example

Use Cases

Confidential Auctions

Bidders submit encrypted bids. A condition checks whether the deadline has passed before triggering decryption:
Losing bids stay undisclosed only if the onDecrypt callback does not persist, emit, or return losing bid plaintext. Your contract logic must explicitly handle only the winning result to maintain confidentiality.

Private Voting with Cascading Outcomes

Votes stay encrypted until tally time. The tally outcome determines whether another CTX fires:

Getting Started