Sending Encrypted Transactions with Programmable Privacy
This comprehensive tutorial walks you through building a complete encrypted transaction system using SKALE’s Programmable Privacy. You’ll learn how to create private transfers that remain encrypted until consensus finality, preventing MEV attacks while maintaining blockchain transparency.This tutorial requires access to a privacy-enabled SKALE chain. Check Programmable Privacy for current feature availability.
What You’ll Build
A full-featured encrypted transfer application that:- Encrypts transaction data (recipient, amount) before blockchain submission
- Shows real-time pending encrypted transactions
- Displays decrypted results after consensus finality
- Handles committee rotations seamlessly
- Provides pre-execution privacy for sensitive transfers — data is hidden until consensus finality
Prerequisites
- Node.js 16+ and npm/yarn
- MetaMask browser extension
- Access to a privacy-enabled SKALE chain
- Basic knowledge of JavaScript and smart contracts
Step 1: Smart Contract Setup
First, let’s create a simple smart contract for our encrypted transfers.Create the Transfer Contract
Create a new filecontracts/SimpleTransferDemo.sol:
- Simple ERC20-like interface for easy testing
- Initial funding of 1,000,000 tokens to deployer
- Allocate function for funding test accounts
- Transfer event for tracking encrypted operations
Deploy the Contract
Use Foundry or Hardhat to deploy the contract to your privacy-enabled SKALE chain. See ERC20 Deployment Guide for detailed deployment instructions.
Step 2: Project Setup
Let’s set up our frontend application structure.Initialize the Project
Configure Environment
Create.env file with your configuration:
VITE_EXPLORER_URL: Block explorer for transaction linksVITE_SCHAIN_ENDPOINT: Privacy-enabled SKALE chain RPCVITE_TRANSFER_CONTRACT: Address of deployed transfer contract
Update package.json
Step 3: Core Implementation
Let’s build the main application logic.Initialize the Privacy SDK
Createsrc/main.js:
Transaction Data Encoding
Wallet Connection
Encrypted Transaction Submission
Transaction Finality Monitoring
Step 4: User Interface
Let’s create a user-friendly interface for our encrypted transfers.HTML Structure
Createindex.html:
CSS Styling
Createsrc/style.css:
UI Management Functions
Add these functions tosrc/main.js:
Step 5: Testing and Running
Run the Application
Test the Flow
- Connect Wallet: Click “Connect Wallet” and approve in MetaMask
- Enter Transfer Details: Input recipient address and amount
- Send Transfer: Click “Encrypt & Send Transfer”
- Monitor: Watch the transaction go through stages:
- Pending: Transaction submitted and encrypted
- Finality: Transaction confirmed by consensus
- Decryption: Original data revealed and executed
- View Results: Check completed transfers section
Step 6: Advanced Features
Committee Rotation Monitoring
Add this to monitor committee changes:Real-Time Pending Transaction Updates
Security Best Practices
Input Validation
Error Handling
Troubleshooting
Common Issues
”Transaction not decrypting”
Solutions:- Wait longer for consensus finality
- Check if committee rotation is in progress
- Verify transaction was sent via threshold encryption
”Gas limit too low”
Solutions:- Increase gas limit to 300,000 or higher
- Always set gasLimit manually for encrypted transactions
”Connection failed”
Solutions:- Verify SKALE chain endpoint URL is correct
- Check network connectivity
- Ensure chain supports Programmable Privacy
”Balance not updating”
Solutions:- Wait for transaction decryption (3-5 seconds after finality)
- Refresh wallet connection
- Check if transfer actually succeeded
Debug Mode
Add this tomain.js for debugging:
