> For the complete documentation index, see [llms.txt](https://docs.seismic.systems/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.seismic.systems/clients/alloy/contract-interaction.md).

# Contract Interaction

Patterns for calling and transacting with smart contracts on Seismic using the Rust SDK.

## Overview

seismic-alloy uses Alloy's `sol!` macro with `#[sol(rpc)]` to define contract interfaces and generate type-safe call builders. Functions with shielded parameters (e.g., `suint256`, `saddress`, `sbool`) auto-encrypt via `ShieldedCallBuilder` — you can call `.send()` or `.call()` directly without `.seismic()`. For non-shielded functions that still need encryption, use `.seismic()` to opt in. Omit `.seismic()` entirely for transparent (unencrypted) operations.

### Key Concepts

* **`sol!` macro with `#[sol(rpc)]`** — Define contract interfaces with Solidity syntax, generate call builders and deploy methods
* **Auto-encryption for shielded params** — Functions with shielded types in their arguments return a `ShieldedCallBuilder` automatically; call `.send()` or `.call()` directly
* **`.seismic()` call builder** — For non-shielded functions that need encryption; converts a `SolCallBuilder` into a `ShieldedCallBuilder`
* **Two traits** — `SeismicCallExt` adds `.seismic()` to `SolCallBuilder`; `ShieldedCallExt` adds `.call()`, `.send()`, and builder methods to `ShieldedCallBuilder`
* **SecurityParams** — Per-call overrides for expiration, block hash, and encryption nonce
* **EIP-712** — `.eip712()` on `ShieldedCallBuilder` for browser wallet compatibility

## Shielded vs. Transparent Operations

| Operation             | When                            | Pattern                                     | Provider Required       |
| --------------------- | ------------------------------- | ------------------------------------------- | ----------------------- |
| **Shielded Read**     | Function has shielded params    | `contract.method().call().await?`           | `SeismicSignedProvider` |
| **Shielded Read**     | Function has no shielded params | `contract.method().seismic().call().await?` | `SeismicSignedProvider` |
| **Shielded Write**    | Function has shielded params    | `contract.method().send().await?`           | `SeismicSignedProvider` |
| **Shielded Write**    | Function has no shielded params | `contract.method().seismic().send().await?` | `SeismicSignedProvider` |
| **Transparent Read**  | Any                             | `contract.method().call().await?`           | Any provider            |
| **Transparent Write** | Any                             | `contract.method().send().await?`           | `SeismicSignedProvider` |

{% hint style="info" %}
Contract deployment (Create transactions) **cannot** be seismic. Deploy your contract with a standard transaction, then interact with it using shielded calls.
{% endhint %}

## Defining Contract Interfaces

Use Alloy's `sol!` macro with `#[sol(rpc)]` to define your contract's interface. This generates type-safe call builders with `.call()` and `.send()` methods:

```rust
use seismic_prelude::client::*; // sol! macro is included in the prelude

sol! {
    #[sol(rpc)]
    contract SeismicCounter {
        event setNumberEmit();
        event incrementEmit();

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

To also include deployment, add the `bytecode` attribute:

```rust
sol! {
    #[sol(rpc, bytecode = "0x60806040...")]
    contract SeismicCounter {
        // ...
    }
}
```

## Quick Example

```rust
use seismic_prelude::client::*;
// The prelude re-exports both SeismicCallExt (adds .seismic() to SolCallBuilder)
// and ShieldedCallExt (adds .call(), .send(), .eip712() to ShieldedCallBuilder),
// so you don't need to worry about which trait to import.
use seismic_alloy_network::reth::SeismicReth;

sol! {
    #[sol(rpc)]
    contract SeismicCounter {
        function setNumber(suint256 newNumber) public;
        function isOdd() public view returns (bool);
    }
}

let provider = SeismicProviderBuilder::new()
    .wallet(wallet)
    .connect_http(url)
    .await?;

let contract = SeismicCounter::new(address, &provider);

// Shielded read — isOdd() has no shielded params, so use .seismic()
let is_odd = contract.isOdd().seismic().call().await?;

// Shielded write — setNumber has a shielded param (suint256), auto-encrypts
contract.setNumber(alloy_primitives::aliases::SUInt(U256::from(42)))
    .send()
    .await?
    .get_receipt()
    .await?;

// Transparent read (standard eth_call)
let is_odd = contract.isOdd().call().await?;
```

## Navigation

| Page                                                                          | Description                                                              |
| ----------------------------------------------------------------------------- | ------------------------------------------------------------------------ |
| [Shielded Calls](/clients/alloy/contract-interaction/shielded-calls.md)       | Encrypted writes and signed reads using auto-encryption and `.seismic()` |
| [Transparent Calls](/clients/alloy/contract-interaction/transparent-calls.md) | Standard Ethereum calls without encryption                               |

## See Also

* [SeismicSignedProvider](/clients/alloy/provider/seismic-signed-provider.md) — Required for shielded operations
* [SeismicUnsignedProvider](/clients/alloy/provider/seismic-unsigned-provider.md) — Sufficient for transparent reads
* [Transaction Types](/clients/alloy/transaction-types.md) — Underlying transaction structs
* [Encryption](/clients/alloy/provider/encryption.md) — How calldata encryption works


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.seismic.systems/clients/alloy/contract-interaction.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
