coinsSRC20

Privacy-preserving ERC20 tokens with shielded balances

SRC20 is Seismic's privacy-preserving ERC20 standard. Balances and transfer amounts use shielded types (suint256), so they are hidden from external observers. The protocol ensures that only authorized parties -- the token holder or those with a viewing key -- can read balances and decode transfer events.

What Makes SRC20 Different from ERC20

Feature
ERC20
SRC20

Balances

Public (anyone can read)

Shielded (suint256) -- only the owner can read via signed read

Transfer amounts

Public in transaction data

Encrypted calldata via shielded writes

Events

Public (Transfer, Approval)

Encrypted -- require viewing key to decrypt

Allowances

Public

Shielded (suint256)

Token metadata

Public (name, symbol, decimals)

Public (not shielded)

circle-info

SRC20 contracts are deployed like any other contract on Seismic. The shielding is handled at the EVM level -- the contract uses suint256 for sensitive fields, and the Seismic node's TEE ensures values are encrypted in storage and transit.

Contract Interface

Define the SRC20 interface using Alloy's sol! macro:

use alloy::sol;

sol! {
    interface ISRC20 {
        function name() public view returns (string);
        function symbol() public view returns (string);
        function decimals() public view returns (uint8);
        function totalSupply() public view returns (uint256);

        function balanceOf(address account) public view returns (suint256);
        function transfer(address to, suint256 amount) public returns (bool);
        function approve(address spender, suint256 amount) public returns (bool);
        function allowance(address owner, address spender) public view returns (suint256);
        function transferFrom(address from, address to, suint256 amount) public returns (bool);

        event Transfer(address indexed from, address indexed to, suint256 value);
        event Approval(address indexed owner, address indexed spender, suint256 value);
    }
}

Architecture

Quick Start

Page
Description

Reading and writing SRC20 balances, signed reads, shielded writes

Shielded transfer patterns, approvals, and multi-step workflows

Decrypting encrypted Transfer and Approval events

Key Concepts

Signed Reads for Balances

Unlike ERC20 where balanceOf() is a simple public read, SRC20's balanceOf() uses msg.sender to authenticate the caller. This means you must use seismic_call() (a signed read) rather than a plain eth_call. A plain eth_call zeros out the from field, so the contract sees the zero address as the sender and returns its balance -- which is almost certainly zero.

Shielded Writes

Transfers and approvals use .seismic() to mark the transaction for calldata encryption. The SeismicSignedProvider filler pipeline automatically handles the encryption before the transaction reaches the node.

Encrypted Events

SRC20 Transfer and Approval events contain encrypted suint256 values. To decode the actual transfer amounts, you need a viewing key registered with the Directory contract.

See Also

Last updated