shield-halvedShielded Calls

Encrypted writes and signed reads using seismic-alloy

Privacy-preserving contract interactions where calldata (and optionally return data) is encrypted using the TEE's public key.

Overview

Shielded calls use the Seismic transaction type (0x4A) to encrypt calldata before it reaches the network. The SDK's filler pipeline handles encryption automatically -- you mark a transaction as seismic with .seismic(), and the provider encrypts it before broadcast.

There are two shielded operations:

  • Shielded Write -- Encrypted send_transaction that modifies on-chain state

  • Signed Read -- Encrypted eth_call that reads state without modification

Both require a SeismicSignedProvider because they need a private key for ECDH key derivation and transaction signing.

Defining a Contract Interface

Use Alloy's sol! macro to define your contract interface:

use alloy::sol;

sol! {
    interface ISeismicCounter {
        event setNumberEmit();
        event incrementEmit();

        function setNumber(suint256 newNumber) public;
        function increment() public;
        function isOdd() public view returns (bool);
    }
}

This generates Rust types for each function:

  • ISeismicCounter::setNumberCall { newNumber: U256 }

  • ISeismicCounter::incrementCall {}

  • ISeismicCounter::isOddCall {}

Shielded Write

A shielded write sends an encrypted transaction that modifies on-chain state. The calldata is encrypted with AES-GCM using a shared secret derived from the TEE's public key.

Building the Transaction

Sending the Transaction

Complete Example

Signed Read

A signed read executes an encrypted eth_call that proves the caller's identity to the TEE. This is required for reading private state that is access-controlled by msg.sender.

Building the Read Request

Executing the Read

Complete Example

How Encryption Works

The filler pipeline handles encryption transparently:

circle-info

You never need to call encryption functions manually. The provider's filler pipeline handles all cryptographic operations when you use .seismic().

Shielded Write vs. Signed Read

Aspect
Shielded Write
Signed Read

Method

send_transaction()

seismic_call()

State changes

Yes

No

Calldata encrypted

Yes

Yes

Response encrypted

N/A (returns receipt)

Yes (auto-decrypted)

Gas cost

Yes

No (simulated)

signed_read flag

false

true

Important Notes

  • Create transactions cannot be seismic. Contract deployment must use standard (non-seismic) transactions. Deploy first, then interact with shielded calls. See Transparent Calls for deployment patterns.

  • Signed provider required. Both shielded writes and signed reads need a SeismicSignedProvider. An unsigned provider cannot perform shielded operations.

  • Automatic response decryption. When using seismic_call(), the provider automatically decrypts the TEE's encrypted response.

  • Shielded types in ABI. The sol! macro handles shielded Solidity types (suint256, sbool, saddress) -- they map to their standard ABI counterparts for encoding.

See Also

Last updated