Smart Contracts on Soroban: A Backend Engineer's Perspective

2024-06-20
10 min read
Smart Contracts on Soroban: A Backend Engineer's Perspective
SorobanStellarWeb3Rust

Introduction

Coming from a traditional C# and .NET background, diving into smart contract development on Soroban was both exciting and challenging. Here are the key lessons I learned building non-custodial financial flows on Stellar.

Why Soroban?

Soroban is Stellar's smart contract platform built with Rust. Unlike Solidity on Ethereum, Soroban contracts benefit from Stellar's fast finality and low transaction costs, making it practical for real-world financial applications.

Key Differences from Traditional Backend

1. State is Expensive

On-chain storage costs money. Every byte stored in a contract has an associated cost. This forces you to think carefully about data structures and what truly needs to be on-chain vs off-chain.

#[contractimpl]
impl SavingsContract {
    pub fn deposit(env: Env, user: Address, amount: i128) -> Result<(), Error> {
        user.require_auth();
        let mut balance: i128 = env.storage().persistent()
            .get(&user)
            .unwrap_or(0);
        balance += amount;
        env.storage().persistent().set(&user, &balance);
        Ok(())
    }
}

2. Deterministic Execution

Smart contracts must be deterministic. No random numbers, no external API calls, no system time. Everything must be derived from the blockchain state and transaction parameters.

3. Account Abstraction

One of the most powerful patterns we implemented at Juby was account abstraction with email-based onboarding. This reduced the friction of wallet setup from several minutes to under 2 minutes, making Web3 accessible to non-crypto-native users.

The On-chain/Off-chain Bridge

Building an integration layer between traditional backend services and smart contracts is crucial. We synchronize financial simulations off-chain with actual smart contract execution on-chain, ensuring consistency while keeping the user experience smooth.

Takeaways

  • Think of smart contracts as a database with execution logic, not as a traditional server
  • Design your on-chain/off-chain boundary carefully
  • Account abstraction is the key to mainstream Web3 adoption
  • Rust's type system catches many bugs at compile time that would be runtime errors in other languages

Share this post