2024-05-07 22:05:58 +00:00
# Obligato web3 liquidity demo
This demo shows end-to-end integration with Obligato for web3 liquidity (i.e. a native ERC20 token).
2024-05-11 02:55:38 +00:00
This demo is expected to run on a single machine that has SGX.
It depends on `wasmd` (version v0.44.0). Follow the instructions [here ](https://docs.cosmwasm.com/docs/getting-started/installation/#wasmd ) to install, but checkout version `v0.44.0` .
2024-05-07 22:05:58 +00:00
## Create obligations and tenders on Obligato
Make sure tenders have backing funds.
## Start blockchain
```
# cd bisenzone-cw-mvp
./scripts/keygen.sh
./scripts/init-node.sh
./scripts/run-node.sh
```
## Build contract
```
./scripts/build-contract.sh
```
## Listen to events (for debugging)
```
websocat ws://127.0.0.1:26657/websocket
{ "jsonrpc": "2.0", "method": "subscribe", "params": ["tm.event='Tx'"], "id": 1 }
```
## Init enclave
### Setup and build
2024-05-11 02:55:38 +00:00
Generate the private key and build the binary that will run in the enclave:
2024-05-07 22:05:58 +00:00
```
# cd tee-mtcs/enclaves/quartz
gramine-sgx-gen-private-key
CARGO_TARGET_DIR=./target cargo build --release
```
2024-05-11 02:55:38 +00:00
The built binary is a grpc server that hosts the (currently built-in) mtcs application.
2024-05-07 22:05:58 +00:00
### Update enclave trusted hash
2024-05-11 02:55:38 +00:00
Now we need to get the trusted hash to initialize the enclave. Running tm-prover with wrong trusted-hash should print the correct one.
2024-05-07 22:05:58 +00:00
```
# cd tee-mtcs/utils/tm-prover
rm light-client-proof.json
cargo run -- --chain-id testing \
--primary "http://127.0.0.1:26657" \
--witnesses "http://127.0.0.1:26657" \
--trusted-height 1 \
--trusted-hash "5237772462A41C0296ED688A0327B8A60DF310F08997AD760EB74A70D0176C27" \
--contract-address "wasm14hj2tavq8fpesdwxxcu44rty3hh90vhujrvcmstl4zr3txmfvw9s0phg4d" \
--storage-key "quartz_session" \
2024-05-11 02:55:38 +00:00
--trace-file light-client-proof.json & > output
cat output | grep found | head -1 | awk '{print $NF}' | sed 's/\x1b\[[0-9;]*m//g' > trusted.hash
export TRUSTED_HASH=$(cat trusted.hash)
2024-05-07 22:05:58 +00:00
```
2024-05-11 02:55:38 +00:00
Note we dump the output of the command into the `output` file, which we then parse to get the trusted hash,
strip of any extra chars, and finally save into the `trusted.hash` file (we'll use this again laster). We also save it to an env var.
2024-05-07 22:05:58 +00:00
### Start enclave
2024-05-11 02:55:38 +00:00
Update the `quartz-manifest.template` with the correct ("found") hash from the previous command:
```
# cd tee-mtcs/enclaves/quartz
sed -i -r "s/(\"--trusted-hash\", \")[A-Z0-9]+(\"])/\1$TRUSTED_HASH\2/" quartz.manifest.template
```
That will overwrite the template file in place, inserting the new hash in place of the old one.
Now we can start the enclave:
2024-05-07 22:05:58 +00:00
```
# cd tee-mtcs/enclaves/quartz
gramine-manifest \
-Dlog_level="error" \
-Dhome=${HOME} \
-Darch_libdir="/lib/$(gcc -dumpmachine)" \
-Dra_type="epid" \
-Dra_client_spid="51CAF5A48B450D624AEFE3286D314894" \
-Dra_client_linkable=1 \
-Dquartz_dir="$(pwd)" \
quartz.manifest.template quartz.manifest
gramine-sgx-sign --manifest quartz.manifest --output quartz.manifest.sgx
gramine-sgx ./quartz
```
## Send initiate request
2024-05-11 02:55:38 +00:00
Now with the binary running in the enclave, we can run commands in another window.
First, let's instantiate:
2024-05-07 22:05:58 +00:00
```
# cd tee-mtcs/utils/quartz-relayer
2024-05-11 02:55:38 +00:00
export INSTANTIATE_MSG=$(./scripts/relay.sh Instantiate)
2024-05-07 22:05:58 +00:00
```
2024-05-11 02:55:38 +00:00
Note we save the output into an env variable.
2024-05-07 22:05:58 +00:00
## Deploy contract
2024-05-11 02:55:38 +00:00
We can now deploy the contract. The deploy script will read from $INSTANTIATE_MSG and use the attestation to create the contract.
2024-05-07 22:05:58 +00:00
```
# cd bisenzone-cw-mvp
2024-05-11 02:55:38 +00:00
./scripts/deploy-contract.sh artifacts/cw_tee_mtcs.wasm & > output
2024-05-07 22:05:58 +00:00
2024-05-11 02:55:38 +00:00
export CONTRACT=$(cat output | grep Address | awk '{print $NF}' | sed 's/\x1b\[[0-9;]*m//g')
2024-05-07 22:05:58 +00:00
```
2024-05-11 02:55:38 +00:00
Note again we save the output to a file, and then parse the file to get the contract address, which we save in an env var.
2024-05-07 22:05:58 +00:00
## Create session
2024-05-11 02:55:38 +00:00
Now we can initialize a session on the enclave, which will generate a nonce to use:
2024-05-07 22:05:58 +00:00
```
2024-05-11 02:55:38 +00:00
# cd tee-mtcs/utils/quartz-relayer
2024-05-07 22:05:58 +00:00
2024-05-11 02:55:38 +00:00
export EXECUTE=$(./scripts/relay.sh SessionCreate)
2024-05-07 22:05:58 +00:00
```
2024-05-11 02:55:38 +00:00
And we can execute the session creation on the contract:
2024-05-07 22:05:58 +00:00
2024-05-11 02:55:38 +00:00
```
2024-05-07 22:05:58 +00:00
wasmd tx wasm execute "$CONTRACT" "$EXECUTE" --from alice --chain-id testing -y
```
## Set session pk
2024-05-11 02:55:38 +00:00
Now let's generate a light client proof that the contract has created the session:
2024-05-07 22:05:58 +00:00
```
# cd tee-mtcs/utils/tm-prover
rm light-client-proof.json
2024-05-11 02:55:38 +00:00
export TRUSTED_HASH=$(cat trusted.hash)
2024-05-07 22:05:58 +00:00
cargo run -- --chain-id testing \
--primary "http://127.0.0.1:26657" \
--witnesses "http://127.0.0.1:26657" \
--trusted-height 1 \
2024-05-11 02:55:38 +00:00
--trusted-hash $TRUSTED_HASH \
--contract-address $CONTRACT \
2024-05-07 22:05:58 +00:00
--storage-key "quartz_session" \
--trace-file light-client-proof.json
```
2024-05-11 02:55:38 +00:00
And store the proof in an env var:
2024-05-07 22:05:58 +00:00
2024-05-11 02:55:38 +00:00
```
export POP=$(cat light-client-proof.json)
2024-05-07 22:05:58 +00:00
export POP_MSG=$(jq -nc --arg message "$POP" '$ARGS.named')
2024-05-11 02:55:38 +00:00
```
Now we can relay this proof to the enclave, so it can attest to the pubkey:
2024-05-07 22:05:58 +00:00
```
2024-05-11 02:55:38 +00:00
# cd tee-mtcs/utils/quartz-relayer
2024-05-07 22:05:58 +00:00
2024-05-11 02:55:38 +00:00
export EXECUTE=$(./scripts/relay.sh SessionSetPubKey "$POP_MSG")
2024-05-07 22:05:58 +00:00
```
2024-05-11 02:55:38 +00:00
And send the attestation back to the contract:
2024-05-07 22:05:58 +00:00
2024-05-11 02:55:38 +00:00
```
2024-05-07 22:05:58 +00:00
wasmd tx wasm execute "$CONTRACT" "$EXECUTE" --from alice --chain-id testing -y
```
## Check for session success
2024-05-11 02:55:38 +00:00
Wait a few seconds for the tx to commit, and then fetch the nonce and pubkey data:
2024-05-07 22:05:58 +00:00
```
2024-05-11 02:55:38 +00:00
export NONCE_AND_KEY=$(wasmd query wasm contract-state raw "$CONTRACT" $(printf '%s' "quartz_session" | hexdump -ve '/1 "%02X"') -o json | jq -r .data | base64 -d)
echo $NONCE_AND_KEY
# Note if you see an empty pubkey, wait a few seconds and rerun the above wasmd query command
2024-05-07 22:05:58 +00:00
# {"nonce":"d3283ed5d646298c27f5ef1726c42bf4853ed7f3d30c905fd3607ecc56903db4","pub_key":"02e4d8bc80d032ad610e4643c3da4235076b4d24335cc4c77592562bdcd62ce1d0"}
2024-05-11 02:55:38 +00:00
export PUBKEY=$(echo $NONCE_AND_KEY | jq -r .pub_key)
2024-05-07 22:05:58 +00:00
```
## Sync obligations
2024-05-11 02:55:38 +00:00
Now with the pubkey in hand, we can fetch the obligations from Obligato and encrypt them:
2024-05-07 22:05:58 +00:00
```
# cd tee-mtcs/utils/cycles-sync
cargo run -- --keys-file keys.json \
--obligation-user-map-file o_map.json \
--user "alice" \
2024-05-11 02:55:38 +00:00
--contract $CONTRACT \
2024-05-07 22:05:58 +00:00
sync-obligations \
2024-05-11 02:55:38 +00:00
--epoch-pk $PUBKEY
2024-05-07 22:05:58 +00:00
2024-05-11 02:55:38 +00:00
export OBLIGATIONS=$(wasmd query wasm contract-state raw "$CONTRACT" $(printf '%s' "1/obligations" | hexdump -ve '/1 "%02X"') -o json | jq -r .data | base64 -d)
2024-05-07 22:05:58 +00:00
```
## Init clearing
Create a clearing cycle on Obligato (required to be able to upload setoffs to Obligato) and initiate clearing on the
blockchain.
```
2024-05-11 02:55:38 +00:00
wasmd tx wasm execute $CONTRACT '"init_clearing"' --from alice --chain-id testing -y
2024-05-07 22:05:58 +00:00
```
## Run clearing on enclave
2024-05-11 02:55:38 +00:00
With the encrypted obligations in hand, and clearing run initiated on chain, we can run clearing on the enclave:
2024-05-07 22:05:58 +00:00
```
# cd tee-mtcs/enclaves/quartz
export REQUEST_MSG=$(jq -nc --arg message "$OBLIGATIONS" '$ARGS.named')
2024-05-11 02:55:38 +00:00
export SETOFFS=$(grpcurl -plaintext -import-path ../../enclaves/quartz/proto/ -proto mtcs.proto -d "$REQUEST_MSG" '127.0.0.1:11090' mtcs.Clearing/Run | jq -c '.message | fromjson')
2024-05-07 22:05:58 +00:00
```
## Submit setoffs
```
export EXECUTE=$(jq -nc --argjson submit_setoffs "$SETOFFS" '$ARGS.named')
wasmd tx wasm execute "$CONTRACT" "$EXECUTE" --from alice --chain-id testing -y --gas 2000000
wasmd query wasm contract-state raw "$CONTRACT" $(printf '%s' "1/setoffs" | hexdump -ve '/1 "%02X"') -o json | jq -r .data | base64 -d
```
## Verify CW20 balances
2024-05-11 02:55:38 +00:00
TODO: replace addresses
2024-05-07 22:05:58 +00:00
```
wasmd query wasm contract-state smart "$CONTRACT" '{"balance": {"address": "wasm1gjg72awjl7jvtmq4kjqp3al9p6crstpar8wgn5"}}'
wasmd query wasm contract-state smart "$CONTRACT" '{"balance": {"address": "wasm1tawlwmllmnwm950a7uttqlyne3k4774rsnuw6e"}}'
```
## Sync setoffs
```
# cd tee-mtcs/utils/cycles-sync
cargo run -- --keys-file keys.json \
--obligation-user-map-file o_map.json \
--user "alice" \
2024-05-11 02:55:38 +00:00
--contract $CONTRACT \
2024-05-07 22:05:58 +00:00
sync-set-offs
```