EigenCloud Deployment
This guide covers deploying L{CORE} infrastructure to EigenCloud's Trusted Execution Environment (TEE). EigenCloud provides hardware-isolated compute that protects sensitive operations like decryption.
Overview
A complete L{CORE} deployment consists of two main components:
| Component | Purpose | Runs In |
|---|---|---|
| Cartesi Node | Processes attestations, stores data, handles queries | TEE |
| Attestor | Receives device data, encrypts, submits to chain | TEE or standard cloud |
Both components can run on EigenCloud for maximum security.
Prerequisites
Before deploying, ensure you have:
- Docker Desktop installed
- Cartesi CLI installed:
npm install -g @cartesi/cli - EigenCloud CLI (
ecloud) installed and configured - Access to a container registry (Docker Hub, GitHub Container Registry, etc.)
- Funded wallet for contract deployment
- Encryption keys generated (see Encryption Key Configuration)
Platform Requirements
EigenCloud runs on AMD64 (x86_64) architecture. If you're developing on Apple Silicon (M1/M2/M3), you must build images with --platform linux/amd64.
Without this flag, containers will fail with exec format error.
Configure Docker for cross-platform builds:
# Enable buildx for multi-platform builds
docker buildx create --name multiplatform --use
# Verify setup
docker buildx inspect --bootstrap
The Template Hash Rule
Any change to the Cartesi machine creates a new template hash. New template hash = new contract deployment required.
The template hash is a cryptographic fingerprint of your Cartesi machine image. Smart contracts use this hash to verify inputs come from the expected machine.
| Change Type | Template Hash Changes? | Action Required |
|---|---|---|
Application code (.ts, .js, .py) | Yes | Deploy new contracts |
Dockerfile ENV changes | Yes | Deploy new contracts |
| Dependency updates | Yes | Deploy new contracts |
External .env file changes | No | Just redeploy container |
| Attestor code changes | No | Just redeploy Attestor |
Always check your template hash after building:
npx cartesi hash
Deployment Workflow
Step 1: Configure Encryption Keys
Before building, ensure your encryption keys are configured:
-
Generate keypairs if you haven't already (see Encryption Key Configuration)
-
Add private key to Cartesi Dockerfile:
ENV LCORE_INPUT_PRIVATE_KEY=your-base64-encoded-private-key -
Add public key to Attestor
.env:LCORE_INPUT_PUBLIC_KEY=matching-base64-encoded-public-key
Step 2: Build the Cartesi Machine
The Cartesi machine is a RISC-V Linux image that runs your application logic.
cd cartesi
# Build the RISC-V machine image
npx cartesi build
This compiles your application for the Cartesi Machine RISC-V architecture. The build process:
- Creates a Linux root filesystem
- Installs your application and dependencies
- Configures the entry point
- Generates the machine image and template hash
After building, note your template hash:
npx cartesi hash
# Example output: 0x9311f8dfa5426f0764dfdf631f23334d408b57902bcc04c44a32997a34ecef9f
Step 3: Deploy Smart Contracts (If Needed)
If this is a new deployment or the template hash changed, deploy new contracts:
npx cartesi deploy --hosting self-hosted
This opens a web interface to deploy contracts. Select your target network (e.g., Arbitrum Sepolia for testnet).
See Cartesi Deployment documentation for detailed options.
After deployment, save:
- Contract address (Application/DApp address)
- InputBox address
- Network information
Step 4: Build the Node Docker Image
Build the Docker image that wraps the Cartesi node for cloud deployment:
# IMPORTANT: Specify platform for Apple Silicon compatibility
docker build --platform linux/amd64 \
-f node.dockerfile \
-t your-registry/lcore-cartesi-node:latest \
.
Push to your container registry:
docker push your-registry/lcore-cartesi-node:latest
Step 5: Build the Attestor Docker Image
cd attestor
# Build for AMD64
docker buildx build --platform linux/amd64 \
-f attestor.dockerfile \
-t your-registry/lcore-attestor:latest \
--push \
.
Step 6: Prepare Environment Files
Create .env.eigencloud files for each component:
Cartesi Node (cartesi/.env.eigencloud):
# Network configuration
CARTESI_BLOCKCHAIN_HTTP_ENDPOINT=https://your-rpc-endpoint
CARTESI_BLOCKCHAIN_WS_ENDPOINT=wss://your-ws-endpoint
CARTESI_BLOCKCHAIN_ID=421614 # Chain ID (e.g., Arbitrum Sepolia)
# Contract addresses (from Step 3)
CARTESI_CONTRACTS_APPLICATION_ADDRESS=0x...
CARTESI_CONTRACTS_INPUT_BOX_ADDRESS=0x...
# Database
CARTESI_POSTGRES_ENDPOINT=postgresql://user:pass@host:5432/dbname
# Wallet (for state commitments)
MNEMONIC=your-wallet-mnemonic
Attestor (attestor/.env.eigencloud):
# Encryption keys
LCORE_INPUT_PUBLIC_KEY=your-base64-public-key
LCORE_OUTPUT_PRIVATE_KEY=your-base64-private-key
# Cartesi node endpoint
CARTESI_NODE_URL=http://cartesi-node:10000
# Blockchain
RPC_ENDPOINT=https://your-rpc-endpoint
INPUT_BOX_ADDRESS=0x...
# Wallet (for submitting inputs)
MNEMONIC=your-attestor-wallet-mnemonic
Step 7: Deploy to EigenCloud
Deploy the Cartesi node:
ecloud compute app deploy \
--image-ref your-registry/lcore-cartesi-node:latest \
--env-file cartesi/.env.eigencloud \
--name lcore-cartesi-node
Deploy the Attestor:
ecloud compute app deploy \
--image-ref your-registry/lcore-attestor:latest \
--env-file attestor/.env.eigencloud \
--name lcore-attestor
Step 8: Verify Deployment
Check that both services are running:
# List deployed apps
ecloud compute app list
# Check logs
ecloud compute app logs --name lcore-cartesi-node
ecloud compute app logs --name lcore-attestor
Test the endpoints:
# Test Cartesi node
curl http://<cartesi-node-ip>:10000/health
# Test Attestor
curl http://<attestor-ip>:8001/health
# Test encryption status
curl http://<cartesi-node-ip>:10000/inspect/encryption_status
Updating Deployments
Code Changes (Template Hash Changes)
When you modify application code:
-
Rebuild the Cartesi machine:
npx cartesi build -
Check if template hash changed:
npx cartesi hash -
If hash changed, deploy new contracts:
npx cartesi deploy --hosting self-hosted -
Update
.env.eigencloudwith new contract addresses -
Rebuild and push Docker image:
docker build --platform linux/amd64 -f node.dockerfile -t your-image .
docker push your-image -
Deploy as a new app (to avoid caching issues):
ecloud compute app deploy \
--image-ref your-image \
--env-file .env.eigencloud \
--name lcore-node-v2
Configuration Changes Only
For changes that don't affect the template hash (external .env changes):
-
Update your
.env.eigencloudfile -
Redeploy the existing app:
ecloud compute app upgrade \
--name lcore-cartesi-node \
--env-file .env.eigencloud
Database Setup
The Cartesi node requires PostgreSQL. Options:
Supabase
Use Supabase for managed PostgreSQL:
- Create a new project at supabase.com
- Use the Session pooler connection (port 5432), not Transaction pooler (port 6543)
- The Diesel ORM requires prepared statement support
# Correct (Session pooler)
CARTESI_POSTGRES_ENDPOINT=postgresql://user:pass@host:5432/postgres
# Incorrect (Transaction pooler - will fail)
CARTESI_POSTGRES_ENDPOINT=postgresql://user:pass@host:6543/postgres
Self-Hosted PostgreSQL
Deploy PostgreSQL alongside your services or use any PostgreSQL-compatible database.
Monitoring
Logs
# Stream logs
ecloud compute app logs --name lcore-cartesi-node --follow
# Recent logs
ecloud compute app logs --name lcore-cartesi-node --tail 100
Health Checks
Set up monitoring for:
/healthendpoints on both services- Input processing rate (GraphQL
inputs.totalCount) - Database connectivity
- Wallet balance (for gas)
GraphQL Queries
Query the Cartesi node's GraphQL endpoint:
curl -X POST http://<node-ip>:10000/graphql \
-H "Content-Type: application/json" \
-d '{
"query": "{ inputs { totalCount } notices { totalCount } }"
}'
Security Considerations
Key Management
- Never commit encryption keys or mnemonics to public repositories
- Use separate keys for development/staging/production
- Store production keys in secure secret management systems
- Rotate keys periodically (see Key Rotation)
Network Security
- Restrict access to management endpoints
- Use TLS for all external communications
- Configure firewalls to limit inbound connections
Wallet Security
- Use dedicated wallets for each service
- Fund wallets with only necessary amounts
- Monitor wallet balances and transactions
Troubleshooting
See the Troubleshooting Guide for common issues:
Next Steps
- Encryption Key Configuration — Set up encryption keys
- Troubleshooting — Common issues and solutions
- Encryption Architecture — Understand the encryption systems