Sapphire 101: A Technical Workshop For Blockchain Devs Part 2
DC

DC @dc600

About: Blockchain crypto web3 AI enthusiast || Storyteller

Location:
Kolkata India
Joined:
Feb 27, 2025

Sapphire 101: A Technical Workshop For Blockchain Devs Part 2

Publish Date: Jul 29
3 3

Continuing from Part 1 of the series where we introduced Sapphire and explored confidential transactions.

#2: Signed View Calls

This section is about impersonation and view calls. Let's go through this step by step.

  • When executing a transaction, msg.sender contains the address of the caller — the one who signed the transaction or the contract address of the caller function.
  • For view calls, Ethereum supports impersonation. This means you can set the value of msg.sender field to arbitrary value (e.g. some third-party address) and perform read-only queries on behalf of someone else.
  • This is perfectly fine in Ethereum, because the contract state is public anyway and anyone can simulate any execution path.
  • Sapphire contract storage is confidential, it forbids impersonation: For anonymous view call: msg.sender equals address(0x0) For signed view call (aka. signed query): msg.sender equals address(signer)
  • Here you should mitigate memory access pattern attacks by requiring specific msg.sender.
    1. Make the message field in the MessageBox contract private and only allow the author of the message to retrieve it.
    2. Try using the unwrapped signer to check whether the msg.sender is really zeroed, if view call is unsigned.

#3: Frontend

  • The frontend folder contains a simple Vue-based app that imports the MessageBox contract from backend.
  • Let's start with building the backend.
cd backend; pnpm build
Enter fullscreen mode Exit fullscreen mode
  • In the demo starter we have been working with, we use Vite to reflect any changes on-the-fly and for deployment. You can preview the frontend with:
cd frontend; pnpm dev
Enter fullscreen mode Exit fullscreen mode
  • To sign in the frontend with this demo starter, we store the MetaMask instance into local store so that it’s not reloaded each time you open a subpage.
  • useEthereumStore() returns {signer, unwrappedSigner, provider, unwrappedProvider} to access all flavors of the signer or the provider respectively.
  • Contract address, expected chain ID etc. is read from frontend/.env* files.
  • In contracts.ts the wrappers for the contracts are prepared for you:
const messageBox = useMessageBox();
const uwMessageBox = useUnwrappedMessageBox();
Enter fullscreen mode Exit fullscreen mode
  • Calling uwMessageBox.message() will execute Anonymous Unencrypted View Call in the background.
  • Calling messageBox.message() will activate MetaMask for Signed and Encrypted View Call.

  • Signing the same query is cached. (This helps to reduce annoying popups.)

Based on what you've learned so far, try setting the message in the browser with MetaMask.

#4: Precompiles

For EVMs, the coding language in use is Solidity. So, precompiles are built-in functions that extend the EVM.
Be careful here as these are complex operations that are difficult to implement efficiently.

Examples of Ethereum precompiles:

  • SHA256
  • Elliptic Curve & Pairing (ECADD, ECMUL, ECPAIRING) for ZK / BN128 curve
  • EcDSA Signature Verification (ecrecover)

Sapphire precompiles:

pnpm install -D @oasisprotocol/sapphire-contracts
import "@oasisprotocol/sapphire-contracts/contracts/Sapphire.sol";
Enter fullscreen mode Exit fullscreen mode

The list here is not an exhaustive one:

  • Gas padding
  • Random Number Generation (VRF / CSPRNG)
  • Encryption & decryption (X25519), key generation (Ed25519, SEC P256 k1), signing & verification (EdDSA, EcDSA)

Check our docs here.

Sapphire-Localnet

  • It goes without saying that Sapphire precompiles run on Sapphire only.
  • We can use Testnet, but for running the (automated CI) tests each time, this is not viable (slow, gas costs).
  • Inspired by npx hardhat node and geth --dev, the Oasis team provides the sapphire-localnet docker image which spins up an isolated Oasis network locally:
docker run --rm -it -p8545:8545 -p8546:8546 hcr.io/oasisprotocol/sapphire-localnet
Enter fullscreen mode Exit fullscreen mode

Random Number Generator (RNG)

  • Cryptographically secure source of entropy:
bytes memory entropy = Sapphire.randomBytes(32, "");
Enter fullscreen mode Exit fullscreen mode
  • Much simpler and faster than relying on an external VRF, and, it’s also instant!
  • The second parameter seeds the RNG with your own “extra entropy”.

Based on what you've learned so far, try implementing on-chain CAPTCHA (e.g. add two numbers) to prevent spam attacks.

Curious what comes next? We’ll take it up in the concluding part of the series.

In the meantime, you should check these out:
Sapphire docs
Sapphire repository

Have a question or need help? Join our Discord and head over to the #dev-central channel.

Comments 3 total

  • Aditya Singh
    Aditya SinghJul 30, 2025

    nother banger post! 🔥

    Part 2 really ties it all together love how you dove into confidential storage, view functions, and encryption precompiles. These are the kinds of features that set Oasis Sapphire apart from other EVM chains trying to "add privacy" as an afterthought.
    The step-by-step breakdown makes it super approachable even for devs new to TEEs or smart privacy.
    For folks following along, the full Sapphire docs are a must-bookmark:
    📘 docs.oasis.io/sapphire/
    And if you're curious how all this connects to off-chain compute, check out ROFL:
    🧠 oasis.net/blog/rofl-mainnet-launch
    Excited to see what you cover next maybe something on integrating with the Oasis Privacy Layer? 👀

  • sid
    sidJul 31, 2025

    Part 2 really builds on the foundation beautifully, signed view calls and impersonation restrictions are crucial when privacy is the core offering. Loved the practical touches like frontend integration and the clean abstraction with useEthereumStore() and useMessageBox(). Also, the Sapphire precompiles open so many doors for privacy-preserving cryptography, on-chain CAPTCHA with native RNG? Game-changing stuff, and the official Sapphire docs provide great detail!👏

  • Suvrajeet Banerjee
    Suvrajeet BanerjeeAug 13, 2025

    Awesome! 🎉

Add comment