A Stellar (Soroban) smart contract implementation for Reclaim Protocol that enables on-chain verification of cryptographic proofs using witness-based epochs.
This contract provides a decentralized verification system for Reclaim Protocol proofs on the Stellar network. It manages epochs with configurable witnesses and verifies cryptographic signatures using secp256k1 recovery.
- Epoch Management: Create and manage epochs with configurable witnesses
- Proof Verification: Verify cryptographic proofs using secp256k1 signature recovery
- Owner Controls: Admin-only functions for epoch management
- Witness System: Support for multiple witnesses with minimum witness requirements
Before you begin, ensure you have the following installed:
- Rust (latest stable version)
- Stellar CLI
- A Stellar account with testnet access (for deployment)
- Clone the repository:
git clone https://github.com/reclaimprotocol/stellar-sdk-onchain-integration.git
cd stellar-sdk-onchain-integration- Build the contract:
stellar contract buildThis will compile the contract and generate the WASM file at target/wasm32-unknown-unknown/release/reclaim.wasm.
- Deploy the contract to Stellar testnet:
stellar contract deploy \
--wasm target/wasm32-unknown-unknown/release/reclaim.wasm \
--source reclaim \
--network testnet- Save the contract address from the output:
export CONTRACT=<paste-contract-address-here>- Set your account address:
export ACCOUNT=<paste-your-public-address-here>- Initialize the contract:
stellar contract invoke \
--id $CONTRACT \
--source reclaim \
--network testnet \
-- instantiate \
--user $ACCOUNTNote: On Mainnet (Public), you might need to set some suitable transaction fee (--fee 600000).
Mainnet:
- Contract Address:
CD4M2KHW3ESOV3RUT7KCTC6BX37PIL2Z3BEK47IA74KIMFIFUI3JJDMO - Explorer: View on Stellar Expert
Testnet:
- Contract Address:
CBWG6TV76FMWKJX3THMMEMK66JVU7Z43JGX74XMB3IKBAZQL66AXP4D7 - Explorer: View on Stellar Expert
Initializes the contract with the specified owner address. This function:
- Sets the contract owner
- Initializes the first epoch (epoch 0) with default witness
- Can only be called once
Parameters:
user: The address that will become the contract owner
Adds a new epoch with the specified witnesses. Only the contract owner can call this function.
Parameters:
witnesses: A vector ofWitnessstructs containing address and host informationminimum_witness: The minimum number of witnesses required for verification
Witness Structure:
pub struct Witness {
pub address: BytesN<20>, // 20-byte witness address
pub host: String, // Host identifier
}Verifies a cryptographic proof by:
- Recovering the public key from the signature using secp256k1
- Deriving the Ethereum-style address from the public key
- Checking if the address matches any of the current epoch's witnesses
Parameters:
message_digest: 32-byte hash of the messagesignature: 64-byte secp256k1 signaturerecovery_id: Recovery ID for signature recovery (0-3)
Returns:
Ok(())if verification succeedsErr(ReclaimError::SignatureMismatch)if the recovered address doesn't match any witness
The contract defines the following error types:
OnlyOwner(1): Function can only be called by the contract ownerAlreadyInitialized(2): Contract has already been initializedHashMismatch(3): Hash verification failedLengthMismatch(4): Length validation failedSignatureMismatch(5): Signature verification failed
Run the test suite:
cd contracts/reclaim
cargo testThe test suite includes:
- Contract initialization tests
- Epoch addition tests
- Proof verification tests
stellar-sdk-onchain-integration/
├── contracts/
│ └── reclaim/
│ ├── src/
│ │ ├── lib.rs # Main contract implementation
│ │ └── test.rs # Test suite
│ ├── Cargo.toml # Contract dependencies
│ └── test_snapshots/ # Test snapshots
├── Cargo.toml # Workspace configuration
└── README.md # This file
The contract is configured with optimized release settings:
- Optimization level:
z(size optimization) - Overflow checks: enabled
- LTO: enabled
- Codegen units: 1
Config:
pub struct Config {
pub owner: Address,
pub current_epoch: u128,
pub exists: bool,
}Epoch:
pub struct Epoch {
pub id: u128,
pub timestamp_start: u64,
pub timestamp_end: u64,
pub minimum_witness: u32,
pub witnesses: Vec<Witness>,
}