Computation has come a long way, and blockchain technology has made critical contribution to this evolution. Ethereum’s Virtual Machine (EVM), which is the base on which decentralized applications (dApps) and decentralized internet (web3) are built, needed to revolutionize computation and storage, and they did. But the missing piece of the puzzle? Privacy.
So, what if we could encrypt data and store it privately? Immediate next question would be - can the nodes compute in a distributed environment? Short answer: Yes, with Trusted Execution Environment (TEEs).
This kicked off the journey from a transparent EVM to a confidential EVM system. The benefits become immediately apparent:
- private compute
- private storage
- randomness
- end-to-end encryption
In this series, we will cover Sapphire 101 as a technical workshop.
Architecture
Before deep diving into Sapphire, notably the first and only production-ready confidential EVM, here's a quick overview of Oasis architecture.
Taking a modular approach, unlike most traditional blockchain technology architecture, which is monolithic, Oasis has distinctly separated the consensus and the compute layers. With execution possible in multiple parallel runtimes (paratimes), Sapphire, the confidential compute paratime, is our focus here.
Now, let's take a look how Sapphire's architecture works.
A full list of Sapphire public endpoints.
Mainnet
- RPC HTTP endpoint
- RPC WebSockets endpoint
- Chain ID: Hex: 0x5afe Decimal: 23294
- Block explorer
Testnet
- RPC HTTP endpoint
- RPC WebSockets endpoint
- Chain ID: Hex: 0x5aff Decimal: 23295
- Block explorer
Let's now get started!
#1: Confidential Transactions
Step 1: Clone this demo starter
Step 2: You'll need to generate an Ethereum-compatible wallet, eg Metamask, Brave, etc.
Step 3: Let's use the testnet and you will need some Sapphire TEST tokens to work with. Use the faucet to add the tokens to your wallet.
Step 4: Time to deploy your contract on Sapphire testnet.
cd backend; pnpm install; pnpm build
PRIVATE_KEY=0x… npx hardhat deploy --network sapphire-testnet
Step 5: Browse Oasis explorer to find your contract. Notice the transaction status: encrypted vs unencrypted.
Now, encrypted transactions work like this.
Step 6: To enable encryption, you need to wrap the ethers signer.
If you are working with Hardhat hardhat.config.ts, add this at the top:
import '@oasisprotocol/sapphire-hardhat';
const signer = ethers.provider.getSigner(); // signer is automatically wrapped
In other client, like a browser, it would be:
import * as sapphire from '@oasisprotocol/sapphire-paratime';
const signer = sapphire.wrap(ethers.provider.getSigner());
Step 7: Demo starter project already imports the wrapper. Check out how the setMessage and message Hardhat tasks store and retrieve the message with encrypted transaction and encrypted call.
PRIVATE_KEY=0x… npx hardhat setMessage <CONTRACT_ADDRESS> <YOUR_MESSAGE> --network
sapphire-testnet
PRIVATE_KEY=0x… npx hardhat message <CONTRACT_ADDRESS> --network sapphire-testnet
Did encryption work? Somewhat. Because public parameters for both plain and encrypted transactions are similar.
- From & To
- Gas Price, Gas Used
- Encrypted Calldata size
Step 8: Finally, try to extend setMessage to support unencrypted transactions as well. Use the explorer to check the transmitted transaction. Take note how deploy task was implemented.
In the next part of the series, we will continue with signed view call, frontend, precompiles.
Top comments (5)
This is super helpful, I’ve been curious about how confidential smart contracts actually work in practice.
Love how Sapphire wraps around the EVM instead of forcing you to learn something completely new. Definitely going to try out the demo and play with encrypted transactions on testnet.
Looking forward to the next part of the series!
Some comments may only be visible to logged-in visitors. Sign in to view all comments.