diff --git a/cosmwasm/README.md b/cosmwasm/README.md index 590fd28..34029af 100644 --- a/cosmwasm/README.md +++ b/cosmwasm/README.md @@ -1,28 +1,61 @@ -# Bisenzone CosmWasm MVP +# Quartz CosmWasm Packages -CosmWasm smart contracts used in the Bisenzone MVP. +This repository contains a collection of packages designed to facilitate the development of CosmWasm smart contracts for Quartz apps. -## Testing instructions +## Packages -* Deploy the smart contract on a local wasmd instance - (see [Obligation Clearing Mvp: Local setup](https://github.com/informalsystems/obligation-clearing-mvp#local-setup)) - * Should normally be as simple as running the following scripts -> - ```bash - # terminal-1 - ./scripts/keygen.sh - ./scripts/init-node.sh - ./scripts/run-node.sh - ``` - ```bash - # terminal-2 - ./scripts/build-contract.sh - ./scripts/deploy-contract.sh artifacts/cofi_karma_game.wasm - ``` -* Set contract env var (using the output of the `deploy.sh` script) - +### 1. `quartz-cw` -``` -export CONTRACT="wasm13we0myxwzlpx8l5ark8elw5gj5d59dl6cjkzmt80c5q5cv5rt54qhmta7s" -``` +The `quartz-cw` package offers a high-level framework for building attestation-aware smart contracts by wrapping CosmWasm messages in TEE attestations (e.g. DCAP). + +- Defines `Attested` wrapper for a message and its attestation +- Supports a MockAttestation type for development ease +- Implements session management for secure communication between contract and enclave +The `quartz-cw` package handles actual DCAP verification within smart contracts by calling the standalone `quartz-dcap-verifier` and `tcbinfo` contracts. + +### 2. `quartz-dcap-verifier` + +Your personal DCAP detective! This package is a standalone smart contract for verifying DCAP attestations that can be called by other contracts. + +- Thin wrapper for standalone smart contract around the functionality provided in the `quartz-tee-ra` package +- Provides query and execute entry points for attestation checks + +### 3. `quartz-tee-ra` + +This `quartz-tee-ra` handles Intel SGX remote attestation for both EPID and DCAP protocols. + +- Verifies EPID and DCAP attestations +- Provides core types and structures for SGX quotes +- Implements cryptographic verification of attestation reports + +### 4. `tcbinfo` + +The `tcbinfo` package manages and verifies TCB information crucial for maintaining enclave security. + +- Stores and retrieves TCB information +- Verifies TCB signatures and certificates +- Provides a CosmWasm contract for TCB management + +### 5. `wasmd-client` + +The `wasmd-client` package offers a Rust client interface for interacting with Wasmd nodes. + +- Defines traits for querying and executing CosmWasm contracts +- Provides utilities for deploying and interacting with contracts + + +## Examples + +Check out the `integration_tests` modules in each package for usage examples and best practices! + +## Contributing + +We welcome contributions from the community! If you find any issues or have suggestions for improvement, please open an issue or submit a pull request. Make sure to follow the contribution guidelines outlined in the repository. + + +## Contact + +If you have any questions or need further assistance, please reach out to us at [quartz.support@informal.systems](mailto:quartz.support@informal.systems). -For further instructions, refer to the contract specific READMEs -(e.g. [cofi-karma-game README.md](contracts/cofi-karma-game/README.md)) \ No newline at end of file diff --git a/cosmwasm/packages/quartz-cw/README.md b/cosmwasm/packages/quartz-cw/README.md index f4a6bbc..9267c32 100644 --- a/cosmwasm/packages/quartz-cw/README.md +++ b/cosmwasm/packages/quartz-cw/README.md @@ -1 +1,82 @@ -# Quartz CosmWasm spec + +# Quartz CosmWasm (quartz-cw) + +Quartz CosmWasm (quartz-cw) is a high-level framework for building attestation-aware smart contracts on CosmWasm. It provides a robust foundation for developing secure, Intel SGX-based contracts with built-in remote attestation support. + +## Features + +- `Attested` wrapper for secure message handling +- Traits and structures for easy contract development +- State management and message handling utilities +- Support for both DCAP and EPID attestation protocols +- Mock SGX support for testing environments + +## Installation + +Add `quartz-cw` to your `Cargo.toml`: + +```toml +[dependencies] +quartz-cw = { path = "../packages/quartz-cw" } +``` + +## Usage + +Here's a basic example of how to use `quartz-cw` in your CosmWasm contract: + +```rust +use quartz_cw::prelude::*; +use cosmwasm_std::{DepsMut, Env, MessageInfo, Response}; + +pub fn execute( + deps: DepsMut, + env: Env, + info: MessageInfo, + msg: QuartzExecuteMsg, +) -> Result { + match msg { + QuartzExecuteMsg::Attested(attested_msg) => { + // Handle attested message + // Verification of the attestation is done automatically + let result = attested_msg.handle(deps, env, info)?; + Ok(result) + }, + // Other message handlers... + } +} +``` + +## Key Components + +1. `Attested`: A wrapper struct for holding a message and its attestation. +2. `Attestation`: A trait for attestation types (DCAP, EPID, Mock). +3. `HasUserData`: A trait for extracting user data from attestations. +4. `RawHandler`: A trait for handling raw messages. + +## Configuration + +You can enable mock SGX support for testing by adding the `mock-sgx` feature to your `Cargo.toml`: + +```toml +[dependencies] +quartz-cw = { path = "../packages/quartz-cw", features = ["mock-sgx"] } +``` + +## Testing + +To run the tests: + +```sh +cargo test +``` + +## License + +This project is licensed under [LICENSE_NAME]. See the LICENSE file for details. + +## Contributing + +We welcome contributions! Please feel free to submit a Pull Request. + +For more information on the implementation details, check out the following files: + diff --git a/cosmwasm/packages/quartz-cw/SPEC.md b/cosmwasm/packages/quartz-cw/SPEC.md new file mode 100644 index 0000000..364e868 --- /dev/null +++ b/cosmwasm/packages/quartz-cw/SPEC.md @@ -0,0 +1,159 @@ + +# Quartz CosmWasm (quartz-cw) Specification + +## Abstract + +This document specifies the `quartz-cw` package, which provides a high-level framework for building attestation-aware smart contracts on CosmWasm. The package implements secure message handling, state management, and attestation verification for Intel SGX-based contracts. + +## Table of Contents + +- [Introduction](#introduction) +- [Functionality](#functionality) +- [Implementation](#implementation) +- [Properties](#properties) +- [Assumptions](#assumptions) + +## Introduction + +The `quartz-cw` package is designed to facilitate the development of secure, attestation-aware smart contracts on the CosmWasm platform. It provides a set of tools and abstractions that allow developers to easily integrate Intel SGX remote attestation into their smart contracts, ensuring that only authorized enclaves can interact with the contract's sensitive functions. + +### Scope + +This specification covers the core components of the `quartz-cw` package, including: + +1. The `Attested` wrapper for secure message handling +2. Attestation types and verification processes +3. State management utilities +4. Message handling and execution flow + +### Design Goals + +- Provide a secure and easy-to-use framework for attestation-aware smart contracts +- Abstract away the complexities of SGX attestation verification +- Ensure compatibility with both DCAP and EPID attestation protocols (though EPID is deprecated now by Intel) +- Allow for easy testing and mocking of SGX environments + +## Functionality + +The `quartz-cw` package provides the following key functionalities: + +1. Secure message wrapping with `Attested` +2. Attestation verification for DCAP and EPID protocols +3. State management utilities for CosmWasm contracts +4. Execution handlers for attested messages + +### Definitions + +- `Attested`: A wrapper struct that holds a message `M` and its attestation `A`. +- `Attestation`: A trait that defines the common interface for different attestation types. +- `DcapAttestation`: A struct representing a DCAP attestation. +- `EpidAttestation`: A struct representing an EPID attestation. +- `MockAttestation`: A struct for mocking attestations in test environments. + +## Implementation + +The `quartz-cw` package is implemented in Rust and relies on the CosmWasm framework. The main components are: + +### Attested Message Wrapper + +The `Attested` struct is a wrapper for holding a message and its attestation: + +```rust +/// A wrapper struct for holding a message and its attestation. +#[derive(Clone, Debug, PartialEq)] +pub struct Attested { + pub msg: M, + pub attestation: A, +} + +impl Attested { + pub fn new(msg: M, attestation: A) -> Self { + Self { msg, attestation } + } +} +``` + + +### Attestation Trait + +The `Attestation` trait defines the common interface for different attestation types: + +```rust +pub trait Attestation { + fn verify(&self, deps: Deps<'_>, env: &Env) -> Result<(), Error>; +} +``` + + +### Attestation Verification + +The attestation verification process is handled by the `quartz-tee-ra` package, which is a dependency of `quartz-cw`. The verification functions are called within the execution handlers of `quartz-cw`. + +```rust +pub use intel_sgx::{ + dcap::verify as verify_dcap_attestation, + epid::{types::IASReport, verifier::verify as verify_epid_attestation}, + Error, +}; +``` + + +### Execution Handler + +The execution handler is responsible for processing attested messages and verifying their attestations before executing the contained message. + +```rust +pub fn handle_attested( + deps: DepsMut<'_>, + env: Env, + info: MessageInfo, + attested: Attested, +) -> Result +where + M: DeserializeOwned + Serialize, + A: Attestation, + H: Handler, +{ + // Verify the attestation + attested.attestation.verify(deps.as_ref(), &env)?; + + // Extract the message from the attested wrapper + let msg = attested.msg; + + // Dispatch the message to the appropriate handler + H::handle(deps, env, info, msg) +} +``` + + +## Properties + +The `quartz-cw` package ensures the following properties: + +1. **Attestation Integrity**: All messages wrapped with `Attested` must have a valid attestation that can be verified. + +2. **Message Confidentiality**: The contents of attested messages are only accessible after successful attestation verification. + +3. **Enclave Identity Verification**: The package verifies that messages come from authorized enclaves by checking the MRENCLAVE value. + +4. **Protocol Flexibility**: The package supports both DCAP and EPID attestation protocols, allowing for different SGX deployment scenarios. + +5. **Testability**: The mock-sgx feature allows for easy testing of contracts without a real SGX environment. + +## Assumptions + +The `quartz-cw` package operates under the following assumptions: + +1. The underlying SGX hardware and software stack is secure and not compromised. + +2. The attestation verification process provided by the Intel Attestation Service (IAS) or DCAP infrastructure is reliable and secure. + +3. The CosmWasm runtime environment correctly executes the contract code and maintains the integrity of the contract's state. + +4. The communication channel between the enclave and the smart contract is secure and resistant to man-in-the-middle attacks. + +5. The contract developers correctly implement the `quartz-cw` abstractions and follow secure coding practices. + +6. The MRENCLAVE values of authorized enclaves are known and correctly configured in the contract's state. + +By adhering to this specification, developers can create secure, attestation-aware smart contracts that leverage the power of Intel SGX technology within the CosmWasm ecosystem.# Quartz CosmWasm (quartz-cw) Specification diff --git a/cosmwasm/packages/quartz-tee-ra/README.md b/cosmwasm/packages/quartz-tee-ra/README.md new file mode 100644 index 0000000..b49817b --- /dev/null +++ b/cosmwasm/packages/quartz-tee-ra/README.md @@ -0,0 +1,147 @@ +# Quartz TEE Remote Attestation (quartz-tee-ra) + +Quartz TEE Remote Attestation is a Rust library that provides functionality for verifying Intel SGX remote attestations. It supports both EPID and DCAP attestation protocols, making it a versatile tool for secure enclave-based applications. + +## Features + +- EPID attestation verification +- DCAP attestation verification +- Support for Intel SGX quote parsing and validation +- Integration with MobileCoin's attestation verifier + +## Installation + +Add `quartz-tee-ra` to your `Cargo.toml`: + +```toml +[dependencies] +quartz-tee-ra = { path = "../packages/quartz-tee-ra" } +``` + +## Usage + +Here's a basic example of how to use `quartz-tee-ra` for DCAP attestation verification: + +```rust +use quartz_tee_ra::{verify_dcap_attestation, intel_sgx::dcap::{Quote3, Collateral, TrustedIdentity}}; + +fn verify_attestation(quote: Quote3>, collateral: Collateral, identities: &[TrustedIdentity]) { + let verification_output = verify_dcap_attestation(quote, collateral, identities); + + if verification_output.is_success().into() { + println!("Attestation verified successfully!"); + } else { + println!("Attestation verification failed: {:?}", verification_output); + } +} +``` + +For EPID attestation: + +```rust +use quartz_tee_ra::{verify_epid_attestation, IASReport}; + +fn verify_epid_attestation(report: IASReport, mrenclave: Vec, user_data: Vec) { + match verify_epid_attestation(report, mrenclave, user_data) { + Ok(_) => println!("EPID attestation verified successfully!"), + Err(e) => println!("EPID attestation verification failed: {:?}", e), + } +} +``` + +## API Reference + +The main functions exported by this library are: + + +```21:25:cosmwasm/packages/quartz-tee-ra/src/lib.rs +pub use intel_sgx::{ + dcap::verify as verify_dcap_attestation, + epid::{types::IASReport, verifier::verify as verify_epid_attestation}, + Error, +}; +``` + + +## Dependencies + +This package relies on several external crates and MobileCoin libraries. Key dependencies include: + + +```11:36:cosmwasm/packages/quartz-tee-ra/Cargo.toml + +[dependencies] +# external +der.workspace = true +hex-literal.workspace = true +num-bigint.workspace = true +serde.workspace = true +serde_json.workspace = true +sha2.workspace = true +thiserror.workspace = true +x509-cert.workspace = true +x509-parser.workspace = true + +# mobilecoin +mc-attestation-verifier.workspace = true +mc-sgx-dcap-types.workspace = true + +# cosmos +cosmwasm-schema.workspace = true +cosmwasm-std.workspace = true + +[dev-dependencies] +hex = "0.4.3" +mc-sgx-dcap-types.workspace = true +mc-sgx-core-types.workspace = true +mc-sgx-dcap-sys-types.workspace = true +``` + + +## Development + +To run tests: + +```sh +cargo test +``` + +## License + +[LICENSE_NAME] - see the LICENSE file for details. + +## Contributing + +Contributions are welcome! Please feel free to submit a Pull Request. + +## Safety + +This crate uses `#![deny(unsafe_code)]` to ensure everything is implemented in 100% Safe Rust. + + +```1:17:cosmwasm/packages/quartz-tee-ra/src/lib.rs +#![warn( + clippy::checked_conversions, + clippy::panic, + clippy::panic_in_result_fn, + clippy::unwrap_used, + rust_2018_idioms, + unused_lifetimes +)] +#![deny( + trivial_casts, + trivial_numeric_casts, + unused_import_braces, + unused_qualifications, + warnings +)] +// FIXME(hu55a1n1) - uncomment once we have better wrappers for FFI structs and ctors +// #![forbid(unsafe_code)] +``` + + +Note: There's a TODO to uncomment the `#![forbid(unsafe_code)]` once better wrappers for FFI structs and constructors are implemented. + +## Disclaimer + +This software is provided "as is" and without any express or implied warranties, including, without limitation, the implied warranties of merchantability and fitness for a particular purpose. \ No newline at end of file diff --git a/cosmwasm/packages/wasmd-client/README.md b/cosmwasm/packages/wasmd-client/README.md new file mode 100644 index 0000000..c35fe59 --- /dev/null +++ b/cosmwasm/packages/wasmd-client/README.md @@ -0,0 +1,110 @@ +# wasmd-client + +`wasmd-client` is a Rust library that provides a trait and implementation for interacting with CosmWasm-enabled blockchains, specifically designed for use with the `wasmd` daemon. + +## Features + +- Query smart contracts +- Execute transactions on smart contracts +- Deploy new smart contracts +- Query transaction details + +## Installation + +Add this to your `Cargo.toml`: + +```toml +[dependencies] +wasmd-client = { path = "../packages/wasmd-client" } +``` + +## Usage + +The main interface is provided through the `WasmdClient` trait: + + +```9:44:cosmwasm/packages/wasmd-client/src/lib.rs +pub trait WasmdClient { + type Address: AsRef; + type Query: ToString; + type RawQuery: ToHex; + type ChainId: AsRef; + type Error; + + fn query_smart( + &self, + contract: &Self::Address, + query: Self::Query, + ) -> Result; + + fn query_raw( + &self, + contract: &Self::Address, + query: Self::RawQuery, + ) -> Result; + + fn query_tx(&self, txhash: &str) -> Result; + + fn tx_execute( + &self, + contract: &Self::Address, + chain_id: &Id, + gas: u64, + sender: &str, + msg: M, + ) -> Result; + + fn deploy( + &self, + chain_id: &Id, + sender: &str, // what should this type be + wasm_path: M, + ) -> Result; +``` + + +To use the client, implement this trait for your specific needs or use the provided implementation. + +### Querying a Smart Contract + +```rust +let result: MyResponseType = client.query_smart(&contract_address, query_msg)?; +``` + +### Executing a Transaction + +```rust +let tx_hash = client.tx_execute(&contract_address, &chain_id, gas, &sender, execute_msg)?; +``` + +### Deploying a New Contract + +```rust +let contract_address = client.deploy(&chain_id, &sender, wasm_file_path)?; +``` + +### Querying a Transaction + +```rust +let tx_result: MyTxResultType = client.query_tx(&tx_hash)?; +``` + +## Error Handling + +The `WasmdClient` trait uses an associated `Error` type, allowing for flexible error handling depending on the specific implementation. + +## Development + +To run tests: + +```sh +cargo test +``` + +## Contributing + +Contributions are welcome! Please feel free to submit a Pull Request. + +## License + +This project is licensed under [LICENSE_NAME]. See the LICENSE file for details. \ No newline at end of file diff --git a/docs/_getting_started.md b/docs/_getting_started.md new file mode 100644 index 0000000..aa9b1e1 --- /dev/null +++ b/docs/_getting_started.md @@ -0,0 +1,619 @@ +# Getting Started + +Here you'll get quickly up and running with an example Quartz application. + +You can run this locally using a "mock" enclave (i.e. without real privacy or +attestations), or you can get access to a machine with Intel SGX enabled to run it securely. + +TODO sections: + +- Transfer Application - describe basic application +- Local Mock SGX - describe getting up and running locally with mock sgx (old demo instructions, updated with new quartz CLI) -done +- Real SGX - describe how to get setup quickly with SGX e.g. on Azure, and how to run the same example there - done needs review +- Public Testnet - describe how to deploy on Neutron testnet - TODO + +## Transfer Application Template + +The Transfer Application is a simple template / demo app designed to showcase very basic use of the Quartz framework. It allows users to deposit funds into a contract, transfer them privately within the contract's encrypted state, and ultimately withdraw whatever balance they have left or have accumulated. + +#### Key Features + +1. **Deposit Funds**: Users can deposit funds into a smart contract. +2. **Private Transfers**: Users can transfer funds privately within the contract + +3. **Withdraw Funds**: Users can withdraw their funds from the contract based on their balance in the encrypted state. + +#### Application Structure + +The application is divided into: + +1. **Frontend**: The user interface built with Next.js, cosmjs / graz. +2. **Contracts**: The backend application as a CosmWasm smart contract +3. **Enclave**: Code that executes off-chain and privately in an enclave + +#### Setting Up the Application + +To get started with the Transfer Application, follow these steps: + +**Prerequisites** +Ensure you have the following installed: +Go: Required for building wasmd. +Make: Typically pre-installed on Linux systems. +Git: For cloning the repository. +Websocat: To listen to the events. + + +### Install Dependencies +Install the necessary dependencies for both the frontend and backend. + +```bash + # Install Rust + curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh + rustup target add wasm32-unknown-unknown + + # Install Go tools + export PATH="${PATH}:${HOME}/go/bin" + source ~/.bashrc + go install github.com/fullstorydev/grpcurl/cmd/grpcurl@latest + + # Install grpcurl + go install github.com/fullstorydev/grpcurl/cmd/grpcurl@latest + + # Install websocat + cargo install websocat + +``` + +### Clone the Repository +First, clone the repository to your local machine. + +```bash + git clone ssh://git@github.com/informalsystems/cycles-quartz + cd cycles-quartz +``` + + + +### Install a local daemon (local neutrond/wasmd) +Install a local daemon to be able to easily interact with a local or remote chain. + +a. Neutron +```bash + git clone -b main https://github.com/neutron-org/neutron.git + cd neutron + make install +``` + +After the installation, to verify everything is working run: + +```bash + neutrond version +``` + +b. Wasmd + +```bash + git clone https://github.com/cosmwasm/wasmd/ + cd wasmd + git checkout v0.44.0 / 0.52.0 + go install ./cmd/wasmd +``` + +After the installation, to verify everything is working run: + +```bash + wasmd version +``` + + +### Run a local chain from docker + +Follow the instructions on [the docker folder]() +a. Neutron +```bash + cd docker/neutron + make start-docker-container +``` + +After the installation, you should see a `neutrond` container if you run + +``` + docker ps +``` + +b. Wasmd +```bash + cd docker/wasmd + make run +``` + +After the installation, you should see a `wasmd` container if you run + +``` + docker ps +``` + + + +### Installing the Quartz CLI +To install the Quartz CLI, run the following command from the `cycles-quartz` folder: + +```bash + cargo install --path cli/ +``` + + +### Quickstart on the basic using `dev` +To quickly get up and running, you can run the following `dev` command from the `cycles-quartz` folder: + + +```bash +quartz --mock-sgx --app-dir "apps/transfers/" dev --unsafe-trust-latest --contract-manifest "apps/transfers/contracts/Cargo.toml" --init-msg '{"denom":"ucosm"}' +``` + +This command will build contract and enclave binaries, deploy, instantiate the contract, handshake and listen to the contract. + +To stop the enclave: +```bash + pkill -f quartz-app-tran +``` + +To restart: +```bash +rm -rf apps/transfers/.cache && quartz --mock-sgx --app-dir "apps/transfers/" dev --unsafe-trust-latest --contract-manifest "apps/transfers/contracts/Cargo.toml" --init-msg '{"denom":"ucosm"}' +``` + +From here you can jump to the section on the [front-end](#### Building the front-end Application). + + + +### Create a new quartz app template + +To create a new Quartz app, use the `init` command: + +```bash +quartz init --name --path /path/to/your/project +``` + +This command will create a new directory structure for your Quartz app: +``` +new_app_name/ +├── contracts/ +├── enclave/ +├── frontend/ +└── README.md +``` + + + +### Build the Binaries +To build both the contract and enclave binaries, use the build command: + +```bash +quartz --mock-sgx --app-dir "apps/transfers/" contract build --contract-manifest "apps/transfers/contracts/Cargo.toml" +``` + +This command will compile the smart contract to WebAssembly and build the enclave binary. + +### Configuring and Running the Enclave + +To configure and run the enclave, use the following commands: + +```bash + # Configure the enclave +quartz --mock-sgx --app-dir "apps/transfers/" enclave build +``` + +```bash + # Start the enclave +quartz --mock-sgx --app-dir "apps/transfers/" enclave start +``` + +The enclave will start running and wait for commands. + +### Deploying the Contract + +With the enclave running, open a new terminal window to deploy the contract: + +```bash +quartz --mock-sgx --app-dir "apps/transfers/" contract deploy --contract-manifest "apps/transfers/contracts/Cargo.toml" --init-msg '{"denom":"ucosm"}' + +``` + +Make note of the deployed contract address, as you'll need it for the next step. + +```bash +2024-09-24T11:11:51.233106Z INFO 📌 Contract Address: wasm1suhgf5svhu4usrurvxzlgn54ksxmn8gljarjtxqnapv8kjnp4nrss5maay +``` + +### Performing the Handshake + activating listener + +To establish communication between the contract and the enclave, perform the handshake: + +```bash +quartz --mock-sgx --app-dir "apps/transfers/" handshake --contract +``` + +Replace `` with the address you received when deploying the contract. + +Make note of the handshake generate public key, as you'll need it for the `.env.local` files on the front-end. + +```bash +2024-09-24T11:12:16.961641Z INFO Handshake complete: 02360955ff74750f6ea0b539f41cce89451f591e4c835d0a5406e6effa96dd169d +``` + +Events coming from the contract will be logged following the handshake as they are retrieved by the listener. + +```bash +2024-09-24T11:12:25.156779Z INFO Enclave is listening for requests... +``` + +#### Building the front-end Application + +Once the application is set up, you can interact with it through the frontend. Make sure you have the Keplr extension installed in your browser. You can then deposit, transfer, and withdraw funds using different Keplr accounts. + + +```bash + # Go to the front-end folder + cd frontend + # Do a fresh install + npm ci + # Copy .env.example + cp .env.example .env.local + # Edit .env.local by adding `` and `` + nano .env.local +``` + +##### Example of app required variables + +``` +NEXT_PUBLIC_TARGET_CHAIN=localWasm +NEXT_PUBLIC_ENCLAVE_PUBLIC_KEY=02360955ff74750f6ea0b539f41cce89451f591e4c835d0a5406e6effa96dd169d +NEXT_PUBLIC_TRANSFERS_CONTRACT_ADDRESS=wasm1jfgr0vgunezkhfmdy7krrupu6yjhx224nxtjptll2ylkkqhyzeshrspu9 +``` + +Once the enviroment variables are set, the front-end application can be started with the following command: + +```bash + npm run dev +``` + + +For more detailed instructions on setting up and using the application, refer to the [README](apps/transfers/README.md) file. + + + +## Interacting with the Application + +Once you have the frontend running and connected to your local blockchain (or testnet), you can interact with the Transfer Application: + +1. Ensure you have the Keplr wallet extension installed in your browser. +2. Use one of the provided accounts [wasmd_docker](docker/wasmd/accounts/) / [neutrond_docker](docker/neutrond/accounts/) ) by importing it into your Keplr wallet or create a new one and fund it using the CLI with your `admin` / `val1` account. +3. Use the frontend to deposit funds into the contract. +4. Transfer funds privately between different accounts within the contract. +5. Withdraw funds from the contract back to your Keplr wallet. + +All transactions will be processed automatically by the enclave, ensuring the privacy and confidentiality of your transfers. + +This completes the basic setup and usage guide for the Transfer Application. In the next sections, we'll cover how to run this application with local Mock SGX, real SGX on Azure, and how to deploy it on the Neutron testnet. + + + + + +## Local daemon and wallet + +For all **testing** purposes, you can use the wallets we provide in the `docker/wasmd/accounts` folder. + +Once your `wasmd` is running, you can easily copy the wallets from docker to your local daemon `~/.config` folder: + +Here's how you can copy the user wallets from the Docker instance to your local wasmd configuration: + +1. First, ensure that your local wasmd instance is not running. If it is, stop it. + +2. Locate the directory where the Docker instance stores the wallet data. Based on the provided `Dockerfile`, it appears to be `/root` inside the container. + +3. Copy the wallet data from the Docker container to a temporary directory on your local machine: + +```bash +docker cp -r wasmd:/root/.wasmd/keyring-test temp-keyring +``` + +This command copies the `keyring-test` directory from the Docker container to a `temp-keyring` directory in your current local directory. + +4. Copy the wallet data from the temporary directory to your local wasmd configuration directory: + +```bash +cp -r ~/.temp-keyring/* ~/.wasmd/keyring-test/ +``` + +This command copies the contents of the `temp-keyring` directory to your local `~/.wasmd/keyring-test/` directory. + +5. Clean up the temporary directory: + +```bash +rm -rf ./temp-keyring +``` + +6. Verify that the wallets have been copied successfully by running the following command: + +```bash +wasmd keys list --keyring-backend=test +``` + +This should display the list of wallets that were present in the Docker container. + +### Alternative method with docker running +Now, let's add the admin key. We'll use the mnemonic from the admin.txt file in your Docker setup. First, let's view the contents of that file: + +```bash +docker exec wasmd cat /tmp/accounts/admin.txt +``` + +You should see a mnemonic phrase (a series of words) at the end of this output. + +Now, use this mnemonic to add the admin key to your local wasmd installation: +```bash +wasmd keys add admin --recover --keyring-backend=test +``` + +After completing these steps, your local wasmd instance should have the same `admin` wallets as the Docker instance. You can repeat the process for `alice`, `bob` and `charlie`. + + You can now start your local wasmd instance, and it will use the copied wallets. + +Note: Make sure to replace `wasmd` in the `docker cp` command with the actual name of your running Docker container if it differs. + + + + + +## Working with an Azure Sgx + + +Login via `ssh` into your Azure Sgx enabled machine. + +```bash + ssh username@21.6.21.71 +``` + +### Quickstart +Once logged in, install the `cli` with the following command: + +```bash + cargo install --path cli/ +``` + +We now need to build the binaries. + + +### Build the Binaries +To build both the contract binaries, use the build command: + +```bash +quartz --app-dir "apps/transfers/" contract build --contract-manifest "apps/transfers/contracts/Cargo.toml" +``` + + +This command will compile the smart contract to WebAssembly and build the contract binary. + + +### Configuring and Running the Enclave + +The following configuration assumes that the `wasmd` node will be running in the same Azure instance as the enclave. +If you wish to use another enclave provider you have to make sure that `QUARTZ_NODE_URL` is set to the enclave address and port as an argument as in: + +``` +QUARTZ_NODE_URL=87.23.1.3:11090 && quartz --app-dir "apps/transfers/" contract deploy --contract-manifest "apps/transfers/contracts/Cargo.toml" --init-msg '{"denom":"ucosm"}' + +``` + +If you wish to use another blockchain you have to make sure that `--node-url` is set to the chain address and port as an option in the `cli` as in: + +``` +QUARTZ_NODE_URL=127.0.0.1:11090 && quartz --app-dir "apps/transfers/" --node-url "https://92.43.1.4:26657" contract deploy --contract-manifest "apps/transfers/contracts/Cargo.toml" --init-msg '{"denom":"ucosm"}' + +``` + + + +To configure and run the enclave, use the following commands: + +```bash + # Configure the enclave +quartz --app-dir "apps/transfers/" enclave build +``` + + +Before starting the enclave, you have to make sure that all relevant contracts (tcbinfo, dcap-verifier) have been instantiated as described below +```bash + # Start the enclave +QUARTZ_NODE_URL=127.0.0.1:11090 && quartz --app-dir "apps/transfers/" enclave start --fmspc "00606A000000" --tcbinfo-contract "wasm1pk6xe9hr5wgvl5lcd6wp62236t5p600v9g7nfcsjkf6guvta2s5s7353wa" --dcap-verifier-contract "wasm107cq7x4qmm7mepkuxarcazas23037g4q9u72urzyqu7r4saq3l6srcykw2" +``` + +The enclave will start running and wait for commands. + +### Deploying the Contract + +With the enclave running, open a new terminal window to deploy the contract: + +```bash +QUARTZ_NODE_URL=127.0.0.1:11090 && quartz --app-dir "apps/transfers/" contract deploy --contract-manifest "apps/transfers/contracts/Cargo.toml" --init-msg '{"denom":"ucosm"}' +``` + +Make note of the deployed contract address, as you'll need it for the next step. + + +``` +2024-09-26T15:21:39.036639Z INFO 🆔 Code ID: 66 +2024-09-26T15:21:39.036640Z INFO 📌 Contract Address: wasm1z0az3d9j9s3rjmaukxc58t8hdydu8v0d59wy9p6slce66mwnzjusy76vdq +{"ContractDeploy":{"code_id":66,"contract_addr":"wasm1z0az3d9j9s3rjmaukxc58t8hdydu8v0d59wy9p6slce66mwnzjusy76vdq"}} + +``` + +### Performing the Handshake + activating listener + +To establish communication between the contract and the enclave, perform the handshake: + +```bash +quartz --app-dir "apps/transfers/" handshake --contract +``` + +Replace `` with the address you received when deploying the contract. + +Make note of the handshake generate public key, as you'll need it for the `.env.local` files on the front-end. + +```bash +2024-09-24T11:12:16.961641Z INFO Handshake complete: 02360955ff74750f6ea0b539f41cce89451f591e4c835d0a5406e6effa96dd169d +``` + +Events coming from the contract will be logged following the handshake as they are retrieved by the listener. + +```bash +2024-09-24T11:12:25.156779Z INFO Enclave is listening for requests... +``` + + +## Quartz cosmwasm packages +### Get the FMSPC of the host machine +``` +export QUOTE="/* quote generated during the handshake should work */" +cd utils/print-fmspc/ +cargo run > /dev/null +``` + + + +### Deploying the `tcbinfo` contract +1. Build and store the contract on-chain +``` +cargo run -- contract build --contract-manifest "../cosmwasm/packages/tcbinfo/Cargo.toml" +RES=$(wasmd tx wasm store ./target/wasm32-unknown-unknown/release/tcbinfo.wasm --from alice -y --output json --chain-id "testing" --gas-prices 0.0025ucosm --gas auto --gas-adjustment 1.3) +TX_HASH=$(echo $RES | jq -r '.["txhash"]') +``` +2. Instantiate the contract using Intel's root CA cert. +``` +CERT=$(sed ':a;N;$!ba;s/\n/\\n/g' ../cosmwasm/packages/quartz-tee-ra/data/root_ca.pem) +RES=$(wasmd query tx "$TX_HASH" --output json) +CODE_ID=$(echo $RES | jq -r '.logs[0].events[1].attributes[1].value') +wasmd tx wasm instantiate "$CODE_ID" "{\"root_cert\": \"$CERT\"}" --from "alice" --label "tcbinfo" --chain-id "testing" --gas-prices 0.0025ucosm --gas auto --gas-adjustment 1.3 -y --no-admin --output json +TCB_CONTRACT=$(wasmd query wasm list-contract-by-code "$CODE_ID" --output json | jq -r '.contracts[0]') +``` +3. Get the Tcbinfo for the given FMSPC. +``` +HEADERS=$(wget -q -S -O - https://api.trustedservices.intel.com/sgx/certification/v4/tcb?fmspc=00606A000000 2>&1 >/dev/null) +TCB_INFO=$(wget -q -O - https://api.trustedservices.intel.com/sgx/certification/v4/tcb?fmspc=00606A000000) +export TCB_ISSUER_CERT=$(echo "$HEADERS" | + grep 'TCB-Info-Issuer-Chain:' | + sed 's/.*TCB-Info-Issuer-Chain: //' | + sed 's/%0A/\n/g' | + sed 's/%20/ /g' | + sed 's/-----BEGIN%20CERTIFICATE-----/-----BEGIN CERTIFICATE-----/' | + sed 's/-----END%20CERTIFICATE-----/-----END CERTIFICATE-----/' | + perl -MURI::Escape -ne 'print uri_unescape($_)' | + awk '/-----BEGIN CERTIFICATE-----/{flag=1; print; next} /-----END CERTIFICATE-----/{print; flag=0; exit} flag') + +TCB_ISSUER_CERT=$(echo "$TCB_ISSUER_CERT" | sed ':a;N;$!ba;s/\n/\\n/g') +echo "TCB_INFO:" +echo "$TCB_INFO" +echo +echo "TCB_ISSUER_CERT:" +echo "$TCB_ISSUER_CERT" +``` +4. Add the Tcbinfo for the given FMSPC to the contract (and test it with a query) +``` +wasmd tx wasm execute "$TCB_CONTRACT" "{\"tcb_info\": $(echo "$TCB_INFO" | jq -Rs .), \"certificate\": \"$TCB_ISSUER_CERT\"}" --from admin --chain-id testing --gas auto --gas-adjustment 1.2 -y +wasmd query wasm contract-state smart "$TCB_CONTRACT" '{"get_tcb_info": {"fmspc": "00606A000000"}}' +``` + +### Deploying the `quartz-dcap-verifier` contract +1. Build the contract +``` +cargo run -- contract build --contract-manifest "../cosmwasm/packages/quartz-dcap-verifier/Cargo.toml" +``` +2. Optimize the contract +In order to optimized the contract, you need to install `wasm-opt` v.119 see HOWTO below +``` +wasm-opt -Oz ./target/wasm32-unknown-unknown/release/quartz_dcap_verifier.wasm -o ./target/wasm32-unknown-unknown/release/quartz_dcap_verifier.optimized.wasm +``` +3. Store the optimized contract on-chain +``` +RES=$(wasmd tx wasm store ./target/wasm32-unknown-unknown/release/quartz_dcap_verifier.optimized.wasm --from admin -y --output json --chain-id "testing" --gas-prices 0.0025ucosm --gas auto --gas-adjustment 1.3) +TX_HASH=$(echo $RES | jq -r '.["txhash"]') +RES=$(wasmd query tx "$TX_HASH" --output json) +CODE_ID=$(echo $RES | jq -r '.logs[0].events[1].attributes[1].value') +``` +4. Instantiate the `quartz-dcap-verifier` contract. +``` +wasmd tx wasm instantiate "$CODE_ID" null --from "admin" --label "dcap-verifier" --chain-id "testing" --gas-prices 0.0025ucosm --gas auto --gas-adjustment 1.3 -y --no-admin --output json +DCAP_CONTRACT=$(wasmd query wasm list-contract-by-code "$CODE_ID" --output json | jq -r '.contracts[0]') +``` + +### Quartz setup +``` +quartz --app-dir "../apps/transfers/" + --contract-manifest "../apps/transfers/contracts/Cargo.toml" \ + --unsafe-trust-latest \ + --init-msg '{"denom":"ucosm"}' \ + dev \ + --fmspc "00606A000000" \ + --tcbinfo-contract "$TCB_CONTRACT" \ + --dcap-verifier-contract "$DCAP_CONTRACT" +``` + + + + +#### HOWTO Install `wasm-opt` + +To install `wasm-opt` version 119 on an Azure SGX machine running Ubuntu, follow these steps: + +### 1. **Update and install dependencies:** + +Before installing `wasm-opt`, make sure your system is up-to-date and has the necessary build tools: + +```bash +sudo apt update +sudo apt install -y build-essential cmake git +``` + +### 2. **Download and build `wasm-opt` version 119:** + +The `wasm-opt` tool is part of the [Binaryen](https://github.com/WebAssembly/binaryen) project. To get version 119, you’ll need to clone the specific tag from the Binaryen GitHub repository. + +```bash +git clone https://github.com/WebAssembly/binaryen.git +cd binaryen +git checkout version_119 +``` + +### 3. **Build the project:** + +Next, you'll build Binaryen and the `wasm-opt` tool: + +```bash +cmake . && make +``` + +### 4. **Install `wasm-opt`:** + +Once the build is complete, you can install `wasm-opt` globally on your system: + +```bash +sudo make install +``` + +### 5. **Verify the installation:** + +Finally, confirm that `wasm-opt` version 119 is installed correctly by running: + +```bash +wasm-opt --version +``` + +This should return something like: + +``` +wasm-opt version_119 +``` + +Now, `wasm-opt` version 119 should be properly installed on your Azure SGX machine running Ubuntu. diff --git a/docs/getting_started.md b/docs/getting_started.md index 5eeec5e..7b279d6 100644 --- a/docs/getting_started.md +++ b/docs/getting_started.md @@ -1,14 +1,534 @@ -# Getting Started +# Quartz: Getting Started Guide -Here you'll get quickly up and running with an example Quartz application. +## Table of Contents -You can run this locally using a "mock" enclave (i.e. without real privacy or -attestations), or you can get access to a machine with Intel SGX enabled to run it securely. +- [Introduction](#introduction) +- [Quick Start](#quick-start) +- [Simple Example](#simple-example) +- [Installation](#installation) +- [Local Testnet without SGX](#local-testnet-without-sgx) +- [Real Testnet with SGX](#real-testnet-with-sgx) +- [Other Testnets with SGX](#other-testnets-with-sgx) +- [Troubleshooting and FAQ](#troubleshooting-and-faq) +- [Glossary](#glossary) -TODO sections: +## Introduction -- Transfer Application - describe basic application -- Local Mock SGX - describe getting up and running locally with mock sgx (old demo instructions, updated with new quartz CLI) -- Real SGX - describe how to get setup quickly with SGX e.g. on Azure, and how to run the same example there -- Public Testnet - describe how to deploy on Neutron testnet +This guide will help you get up and running with an example Quartz application. You can run this locally using a "mock" enclave (without real privacy or attestations), or you can use a machine with Intel SGX enabled for secure execution. +> **Note**: This guide assumes familiarity with blockchain concepts and basic smart contract development. + +## Quick Start + +For those who want to get started quickly: + +1. Install dependencies (Rust, wasmd or neutrond) +2. Clone the repository: `git clone ssh://git@github.com/informalsystems/cycles-quartz` +3. Install Quartz CLI: `cargo install --path cli/` +4. Run the development environment: + ```bash + quartz --mock-sgx --app-dir "apps/transfers/" dev \ + --unsafe-trust-latest \ + --contract-manifest "apps/transfers/contracts/Cargo.toml" \ + --init-msg '{"denom":"ucosm"}' + ``` +5. Set up the frontend (see [Building the front-end Application](#building-the-front-end-application)) + +For more detailed instructions, continue reading the following sections. + +## Simple Example + +The Transfer Application is a simple template / demo app designed to showcase very basic use of the Quartz framework. It allows users to deposit funds into a contract, transfer them privately within the contract's encrypted state, and ultimately withdraw whatever balance they have left or have accumulated. + +### Key Features +- Deposit funds into a smart contract +- Transfer funds privately within the contract via encrypted transactions that are handled by Quartz (ie. processed by the enclave and remote attested to). +- Withdraw funds from the contract based on balances in the encrypted state. + +### Application Structure + +1. **Frontend**: The user interface built with Next.js, cosmjs / graz. +2. **Contracts**: The backend application as a CosmWasm smart contract +3. **Enclave**: Code that executes off-chain and privately in an enclave + +## Installation + +Quartz is built in Rust and requires an up-to-date version with the +wasm32 target to be installed. It also expects the system to have a +CosmWasm-compatible Cosmos-SDK blockchain client installed, for instance `wasmd` +or `neutrond`. CosmWasm binaries can be built with `Go` or downloaded from their +developers. Finally, you'll need `npm` to build the frontend. + +### Install Quartz + +Install rust: + + ```bash + curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh + ``` +and add the wasm32 target: + + ```bash + rustup target add wasm32-unknown-unknown + ``` + +Now clone and build the repo: + + ```bash + git clone ssh://git@github.com/informalsystems/cycles-quartz + cd cycles-quartz + cargo install --path cli/ + ``` + +And check that it worked: + + ```bash + quartz --help + ``` + +### Install a CosmWasm Client + +For the local testnet, its simplest to use `wasmd`. + +For the real testnet, `neutrond` is required (the guide is for Neutron's +testnet). + +In either case, you can build from source in Go or use a docker container. + +The docker containers come with preconfigured keys and balances. If you use the +Go binaries you'll have to set up keys and balances yourself. + +To build from source, first make sure you have Go installed. + +Then for `wasmd`: + + ```bash + git clone https://github.com/cosmwasm/wasmd/ + cd wasmd + git checkout v0.44.0 + go install ./cmd/wasmd + ``` + +Or for `neutrond`: + + ```bash + git clone -b main https://github.com/neutron-org/neutron.git + cd neutron + make install + ``` + +To use the docker images, install and set up docker. + +Then for wasmd`: + + ```bash + cd docker/wasmd + make run + ``` + +Or for `neutrond`: + + ```bash + cd docker/neutron + make start-docker-container + ``` + +If using docker it will pre-configure a few keys and allocate funds to them. + + +## Local Testnet Without SGX + +From the root of the `cycles-quartz` repo, we can now deploy our example +transfers app. Deployment involves three components: + +- the enclave +- the smart contract +- the front end + +First we build and run the enclave code. +Quartz provides a `--mock-sgx` flag so we can deploy locally for testing and +development purposes without needing access to an SGX core. +We use `--app-dir` to specify where the app code is located. + +### Enclave + + +1. Build the enclave binary: + ```bash + quartz --mock-sgx --app-dir "apps/transfers/" enclave build + ``` + +2. Start the enclave: + ```bash + quartz --mock-sgx --app-dir "apps/transfers/" enclave start + ``` + +The enclave is a long running process. You'll have to open another window to +continue. + +### Contract + +1. Build the contract binary: + ```bash + quartz --mock-sgx --app-dir "apps/transfers/" contract build --contract-manifest "apps/transfers/contracts/Cargo.toml" + ``` + +2. Deploy the contract: + ```bash + quartz --mock-sgx --app-dir "apps/transfers/" contract deploy \ + --contract-manifest "apps/transfers/contracts/Cargo.toml" \ + --init-msg '{"denom":"ucosm"}' + ``` + +Note our contract takes initialization data in the `--init-msg` which for +the transfers app specifies the asset denom that can be used in this deployment. The +transfers app is currently single asset only. + +If successful, it will print the resulting contract address. Save it to an +environment variable: + +``` +export CONTRACT_ADDRESS= +``` + +3. Perform the handshake: + ```bash + quartz --mock-sgx --app-dir "apps/transfers/" handshake --contract $CONTRACT_ADDRESS + ``` + +This will setup a secure connection between the contract and the enclave. + +If successful, it should output a pubkey value. We'll need both the contract +address and this pubkey value to configure the frontend. Save this to an +environment variable: + +``` +export PUBKEY= +``` + +Now the contract is ready to start processing requests to the enclave. + +### Frontend + +1. Navigate to the frontend folder: + ```bash + cd apps/transfers/frontend + ``` + +2. Install dependencies: + ```bash + npm ci + ``` + +3. Set up environment variables: + ```bash + cp .env.example .env.local + ``` + +Now open `.env.local` and edit the values of +NEXT_PUBLIC_TRANSFERS_CONTRACT_ADDRESS +and +NEXT_PUBLIC_ENCLAVE_PUBLIC_KEY +to be the contract address and pubkey from the previous step (deploying the +contract and doing the handshake). + +4. Finally, start the frontend: + ```bash + npm run dev + ``` + +### Use the App + +Open your browser to `localhost:3000` to see the app. + +You'll need to have the Keplr wallet extension installed and unlocked. + +Configure the chain visibility settings in Keplr so you can see your local chain +(search for the chain id, should be `testing`). + +Create a new address in Keplr for testing purpose. You'll need to send this +address some funds from the `admin` account setup with your local node. For +instance, send 10M ucosm with: + +``` +wasmd tx bank send admin 10000000ucosm --chain-id testing +``` + +You should now see the funds on your local testnet on Keplr. + +Now you can interact with the app by depositing funds, privately transfering +them to other addresses, and finally withdrawing them. + +## Real Testnet with SGX + +Now that we've tried the example app on a local tesnet with a mocked SGX, it's +time to use a real testnet and a real SGX core. This guide will walk through how +to get setup with SGX on Azure, and how to deploy quartz contracts to the +Neutron testnet using real remote attestions from SGX cores on Azure. + +Real verification of SGX on a CosmWasm network requires two additional global contracts +to be deployed: dcap-verify and tcbinfo. The +dcap-verify contract provides the core verification of the SGX attestation +(called DCAP). The tcbinfo contract contains global information about secure +versions of SGX processors. Together they allow contracts built with quartz to +securely verify remote attestations from SGX enclaves. + +We have already predeployed the dcap-verify and tcbinfo contracts on the Neutron +testnet at TODO. To deploy these on your own testnet, see [below][#other-testnets-with-sgx]. + +To begin, you'll need to deploy an SGX-enabled Azure instance and log in via ssh. + +Once logged in, clone and install Quartz like before (see +[installation][#installation] + +### Build and Deploy the Contracts + +TODO: make this about deploying to neutron. + +To build both the contract binaries, use the build command: + +```bash +quartz --app-dir "apps/transfers/" contract build --contract-manifest "apps/transfers/contracts/Cargo.toml" +``` +This command will compile the smart contract to WebAssembly and build the contract binary. + +The following configuration assumes that the `wasmd` node will be running in the same Azure instance as the enclave. +If you wish to use another enclave provider you have to make sure that `QUARTZ_NODE_URL` is set to the enclave address and port as an argument as in: + +```bash +QUARTZ_NODE_URL=87.23.1.3:11090 && quartz --app-dir "apps/transfers/" contract deploy --contract-manifest "apps/transfers/contracts/Cargo.toml" --init-msg '{"denom":"ucosm"}' +``` + +If you wish to use another blockchain you have to make sure that `--node-url` is set to the chain address and port as an option in the `cli` as in: + +```bash +QUARTZ_NODE_URL=127.0.0.1:11090 && quartz --app-dir "apps/transfers/" --node-url "https://92.43.1.4:26657" contract deploy --contract-manifest "apps/transfers/contracts/Cargo.toml" --init-msg '{"denom":"ucosm"}' +``` + +### Build and Run the SGX Enclave + +First we build the enclave like before: + +```bash +# Configure the enclave +quartz --app-dir "apps/transfers/" enclave build +``` + +Before starting the enclave, we should check that the relevant contracts +(tcbinfo, dcap-verifier) have been instantiated. + +TODO: how to query to check this? + +TODO: use variables for the contract addresses + + + +```bash +# Start the enclave +QUARTZ_NODE_URL=127.0.0.1:11090 && quartz --app-dir "apps/transfers/" enclave start --fmspc "00606A000000" --tcbinfo-contract "wasm1pk6xe9hr5wgvl5lcd6wp62236t5p600v9g7nfcsjkf6guvta2s5s7353wa" --dcap-verifier-contract "wasm107cq7x4qmm7mepkuxarcazas23037g4q9u72urzyqu7r4saq3l6srcykw2" +``` + +The enclave will start running and wait for commands. + +### Deploying the Contract + +With the enclave running, open a new terminal window to deploy the contract: + +```bash +QUARTZ_NODE_URL=127.0.0.1:11090 && quartz --app-dir "apps/transfers/" contract deploy --contract-manifest "apps/transfers/contracts/Cargo.toml" --init-msg '{"denom":"ucosm"}' +``` + +Make note of the deployed contract address, as you'll need it for the next step. You should see output similar to: + +``` +2024-09-26T15:21:39.036639Z INFO 🆔 Code ID: 66 +2024-09-26T15:21:39.036640Z INFO 📌 Contract Address: wasm1z0az3d9j9s3rjmaukxc58t8hdydu8v0d59wy9p6slce66mwnzjusy76vdq +{"ContractDeploy":{"code_id":66,"contract_addr":"wasm1z0az3d9j9s3rjmaukxc58t8hdydu8v0d59wy9p6slce66mwnzjusy76vdq"}} +``` + +### Performing the Handshake + activating listener + +To establish communication between the contract and the enclave, perform the handshake: + +```bash +quartz --app-dir "apps/transfers/" handshake --contract +``` + +Replace `` with the address you received when deploying the contract. + +Make note of the handshake generate public key, as you'll need it for the `.env.local` files on the front-end. You should see output similar to: + +```bash +2024-09-24T11:12:16.961641Z INFO Handshake complete: 02360955ff74750f6ea0b539f41cce89451f591e4c835d0a5406e6effa96dd169d +``` + +Events coming from the contract will be logged following the handshake as they are retrieved by the listener: + +```bash +2024-09-24T11:12:25.156779Z INFO Enclave is listening for requests... +``` + +## Other Testnets With SGX + +To setup on another testnet we need to deploy a tcinfo contract and a +dcap-verifier contract. + +### Get the FMSPC of the host machine + +```bash +export QUOTE="/* quote generated during the handshake should work */" +cd utils/print-fmspc/ +cargo run > /dev/null +``` + +### Deploying the `tcbinfo` contract + +1. Build and store the contract on-chain +```bash +cargo run -- contract build --contract-manifest "../cosmwasm/packages/tcbinfo/Cargo.toml" +RES=$(wasmd tx wasm store ./target/wasm32-unknown-unknown/release/tcbinfo.wasm --from alice -y --output json --chain-id "testing" --gas-prices 0.0025ucosm --gas auto --gas-adjustment 1.3) +TX_HASH=$(echo $RES | jq -r '.["txhash"]') +``` + +2. Instantiate the contract using Intel's root CA cert. +```bash +CERT=$(sed ':a;N;$!ba;s/\n/\\n/g' ../cosmwasm/packages/quartz-tee-ra/data/root_ca.pem) +RES=$(wasmd query tx "$TX_HASH" --output json) +CODE_ID=$(echo $RES | jq -r '.logs[0].events[1].attributes[1].value') +wasmd tx wasm instantiate "$CODE_ID" "{\"root_cert\": \"$CERT\"}" --from "alice" --label "tcbinfo" --chain-id "testing" --gas-prices 0.0025ucosm --gas auto --gas-adjustment 1.3 -y --no-admin --output json +TCB_CONTRACT=$(wasmd query wasm list-contract-by-code "$CODE_ID" --output json | jq -r '.contracts[0]') +``` + +3. Get the Tcbinfo for the given FMSPC. +```bash +HEADERS=$(wget -q -S -O - https://api.trustedservices.intel.com/sgx/certification/v4/tcb?fmspc=00606A000000 2>&1 >/dev/null) +TCB_INFO=$(wget -q -O - https://api.trustedservices.intel.com/sgx/certification/v4/tcb?fmspc=00606A000000) +export TCB_ISSUER_CERT=$(echo "$HEADERS" | + grep 'TCB-Info-Issuer-Chain:' | + sed 's/.*TCB-Info-Issuer-Chain: //' | + sed 's/%0A/\n/g' | + sed 's/%20/ /g' | + sed 's/-----BEGIN%20CERTIFICATE-----/-----BEGIN CERTIFICATE-----/' | + sed 's/-----END%20CERTIFICATE-----/-----END CERTIFICATE-----/' | + perl -MURI::Escape -ne 'print uri_unescape($_)' | + awk '/-----BEGIN CERTIFICATE-----/{flag=1; print; next} /-----END CERTIFICATE-----/{print; flag=0; exit} flag') + +TCB_ISSUER_CERT=$(echo "$TCB_ISSUER_CERT" | sed ':a;N;$!ba;s/\n/\\n/g') +echo "TCB_INFO:" +echo "$TCB_INFO" +echo +echo "TCB_ISSUER_CERT:" +echo "$TCB_ISSUER_CERT" +``` + +4. Add the Tcbinfo for the given FMSPC to the contract (and test it with a query) +```bash +wasmd tx wasm execute "$TCB_CONTRACT" "{\"tcb_info\": $(echo "$TCB_INFO" | jq -Rs .), \"certificate\": \"$TCB_ISSUER_CERT\"}" --from admin --chain-id testing --gas auto --gas-adjustment 1.2 -y +wasmd query wasm contract-state smart "$TCB_CONTRACT" '{"get_tcb_info": {"fmspc": "00606A000000"}}' +``` + +### Deploying the `quartz-dcap-verifier` contract + +1. Build the contract +```bash +cargo run -- contract build --contract-manifest "../cosmwasm/packages/quartz-dcap-verifier/Cargo.toml" +``` + +2. Optimize the contract +In order to optimize the contract, you need to install `wasm-opt` v.119. See the HOWTO section below for installation instructions. +```bash +wasm-opt -Oz ./target/wasm32-unknown-unknown/release/quartz_dcap_verifier.wasm -o ./target/wasm32-unknown-unknown/release/quartz_dcap_verifier.optimized.wasm +``` + +3. Store the optimized contract on-chain +```bash +RES=$(wasmd tx wasm store ./target/wasm32-unknown-unknown/release/quartz_dcap_verifier.optimized.wasm --from admin -y --output json --chain-id "testing" --gas-prices 0.0025ucosm --gas auto --gas-adjustment 1.3) +TX_HASH=$(echo $RES | jq -r '.["txhash"]') +RES=$(wasmd query tx "$TX_HASH" --output json) +CODE_ID=$(echo $RES | jq -r '.logs[0].events[1].attributes[1].value') +``` + +4. Instantiate the `quartz-dcap-verifier` contract. +```bash +wasmd tx wasm instantiate "$CODE_ID" null --from "admin" --label "dcap-verifier" --chain-id "testing" --gas-prices 0.0025ucosm --gas auto --gas-adjustment 1.3 -y --no-admin --output json +DCAP_CONTRACT=$(wasmd query wasm list-contract-by-code "$CODE_ID" --output json | jq -r '.contracts[0]') +``` + +### Quartz setup +```bash +quartz --app-dir "../apps/transfers/" \ + --contract-manifest "../apps/transfers/contracts/Cargo.toml" \ + --unsafe-trust-latest \ + --init-msg '{"denom":"ucosm"}' \ + dev \ + --fmspc "00606A000000" \ + --tcbinfo-contract "$TCB_CONTRACT" \ + --dcap-verifier-contract "$DCAP_CONTRACT" +``` + +#### HOWTO Install `wasm-opt` + +To install `wasm-opt` version 119 on an Azure SGX machine running Ubuntu, follow these steps: + +1. **Update and install dependencies:** + +```bash +sudo apt update +sudo apt install -y build-essential cmake git +``` + +2. **Download and build `wasm-opt` version 119:** + +```bash +git clone https://github.com/WebAssembly/binaryen.git +cd binaryen +git checkout version_119 +``` + +3. **Build the project:** + +```bash +cmake . && make +``` + +4. **Install `wasm-opt`:** + +```bash +sudo make install +``` + +5. **Verify the installation:** + +```bash +wasm-opt --version +``` + +This should return something like: + +``` +wasm-opt version_119 +``` + + +## Troubleshooting and FAQ + +1. **Q: The enclave fails to start. What should I do?** + A: Ensure all dependencies are correctly installed and that you're using the correct version of each tool. + +2. **Q: I'm getting a "contract not found" error during handshake. How do I fix this?** + A: Double-check that you're using the correct contract address from the deployment step. + +3. **Q: The frontend isn't connecting to the blockchain. What's wrong?** + A: Verify that your `.env.local` file has the correct contract address and public key. + +For more issues, please refer to our GitHub issues page or community forums. + +## Glossary + +- **Enclave**: A protected area of execution in memory. +- **SGX (Software Guard Extensions)**: Intel's technology for hardware-based isolation and memory encryption. +- **FMSPC**: Flexible Memory Sharing Protocol Component. +- **TCB**: Trusted Computing Base. +- **DCAP**: Data Center Attestation Primitives. +- **Wasmd**: Go implementation of a Cosmos SDK-based blockchain with WebAssembly smart contracts. +- **Neutron**: A CosmWasm-enabled blockchain built with the Cosmos SDK.