Skip to content

Commit 64f5bf8

Browse files
writersblockchaingitbook-bot
authored andcommitted
GITBOOK-902: ibc toolkit - sealed bid auctions
1 parent 958dddd commit 64f5bf8

File tree

3 files changed

+565
-25
lines changed

3 files changed

+565
-25
lines changed
108 KB
Loading

confidential-computing-layer/ibc/usecases/confidential-voting.md

+145-24
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,17 @@ description: >-
88

99
## Overview <a href="#overview" id="overview"></a>
1010

11-
This tutorial explains how to upload a confidential voting contract on Secret Network, which you can execute and query for private voting on any IBC-connected chain. 🚀 In this example, **you will learn how to deploy a confidential voting contract on Secret Network which you will execute from Osmosis mainnet**.&#x20;
11+
This tutorial explains how to upload a confidential voting contract on Secret Network, which you can execute and query for private voting on any IBC-connected chain. 🚀&#x20;
12+
13+
{% hint style="info" %}
14+
In this example, **you will learn how to deploy a confidential voting contract on Secret Network which you will execute from Osmosis mainnet**.&#x20;
15+
{% endhint %}
16+
17+
**The SDK abstracts IBC interactions with the Secret Network for applications that use Cosmos wallets**. It introduces a secure method for generating confidential messages and reliably authenticating users at the same time using the `chacha20poly1305` algorithm.
18+
19+
{% hint style="info" %}
20+
View the typescript SDK [here](https://github.com/writersblockchain/cosmos-ccl-encrypted-payloads-demo/tree/main/next-frontend/src/ccl-sdk), which we will learn how to implement shortly :tada:
21+
{% endhint %}
1222

1323
In this tutorial you will learn:&#x20;
1424

@@ -158,7 +168,7 @@ The `Extension` variant in`ExecuteMsg` leverages the functionality of `handle_en
158168

159169
Now that you understand how the encryption SDK functions, let's look how it's connected to the frontend. The Next.js encryption logic can be found in [Gateway.ts](https://github.com/writersblockchain/cosmos-ccl-encrypted-payloads-demo/blob/main/next-frontend/src/functions/Gateway.ts):
160170

161-
[Create Proposal](confidential-voting.md#overview):&#x20;
171+
[**Create Proposal**](confidential-voting.md#overview)**:**&#x20;
162172

163173
```rust
164174
const create_proposal = async (name: string, description: string, end_time: string = "60") => {
@@ -168,7 +178,7 @@ Now that you understand how the encryption SDK functions, let's look how it's co
168178
}
169179
```
170180

171-
[Vote on Proposal](https://github.com/writersblockchain/cosmos-ccl-encrypted-payloads-demo/blob/1aa91625546547960fd9556e17f14f31d99d726f/next-frontend/src/functions/Gateway.ts#L71):&#x20;
181+
[**Vote on Proposal**](https://github.com/writersblockchain/cosmos-ccl-encrypted-payloads-demo/blob/1aa91625546547960fd9556e17f14f31d99d726f/next-frontend/src/functions/Gateway.ts#L71)**:**&#x20;
172182

173183
```rust
174184
const vote_proposal = async (proposal_id: string, vote: string) => {
@@ -178,7 +188,7 @@ Now that you understand how the encryption SDK functions, let's look how it's co
178188
}
179189
```
180190

181-
Both of these functions access a confidential voting `contract` we have previously deployed on Secret Network contract.&#x20;
191+
Both of these functions access a confidential voting `contract` already deployed on Secret Network (at the end of this tutorial, you will learn how to deploy your own).&#x20;
182192

183193
Then, we call the `execute_gateway_contract` function, which is where all of the cross-chain SDK logic is implemented using IBC hooks:&#x20;
184194

@@ -209,7 +219,27 @@ You can further examine `sendIBCToken` and `gatewayChachaHookMemo` in the CCL-SD
209219

210220
### **Query Messages**
211221

212-
To query encrypted votes using the CCL SDK, use the `enum` called [`InnerQueries`](https://github.com/writersblockchain/cosmos-ccl-encrypted-payloads-demo/blob/1aa91625546547960fd9556e17f14f31d99d726f/deploy-scripts/contracts/secret-voting/src/msg.rs#L35), which wraps the possible queries in the voting smart contract, namely, `MyVote`, with the CCL SDK encryption logic:
222+
There are two types of queries using the CCL SDK:&#x20;
223+
224+
1. **Unauthenticated queries** ie `Extension`, which are queries that don’t require sensitive or protected data. Example: Retrieving a list of proposals or votes, which is public.
225+
2. **Authenticated queries** ie `Inner Queries` (`WithPermit`, `WithAuthData`), which are queries that require `auth_data` from the caller for permission validation. Example: `MyVote { proposal_id }` retrieves a user-specific vote.
226+
227+
| | **Extended Queries** | **Inner Queries** |
228+
| - | -------------------- | ----------------- |
229+
230+
| **Data Access Level** | Public or general data | Private or user-specific data |
231+
| --------------------- | ---------------------- | ----------------------------- |
232+
233+
| **Authorization** | No extra authentication required | Requires `auth_data` or `permit` |
234+
| ----------------- | -------------------------------- | -------------------------------- |
235+
236+
| **Processing Function** | `query::query_extended` | `query::query_with_auth_data` |
237+
| ----------------------- | ----------------------- | ----------------------------- |
238+
239+
| **Use Cases** | Public info like proposals, votes | Personal data like a user’s vote |
240+
| ------------- | --------------------------------- | -------------------------------- |
241+
242+
To query encrypted votes using the CCL SDK, use the `enum` [`InnerQueries`](https://github.com/writersblockchain/cosmos-ccl-encrypted-payloads-demo/blob/1aa91625546547960fd9556e17f14f31d99d726f/deploy-scripts/contracts/secret-voting/src/msg.rs#L35), which wraps the possible queries in the voting smart contract, namely, `MyVote`, with the CCL SDK encryption logic:
213243

214244
```rust
215245
#[cw_serde]
@@ -227,30 +257,112 @@ pub enum InnerQueries {
227257
pub type QueryMsg = GatewayQueryMsg<InnerQueries, sdk::CosmosAuthData, ExtendedQueries>;
228258
```
229259

230-
`InnerMethods` leverage the SDK by using the [`GatewayQueryMsg`](https://github.com/writersblockchain/cosmos-ccl-encrypted-payloads-demo/blob/1aa91625546547960fd9556e17f14f31d99d726f/deploy-scripts/packages/sdk/src/gateway.rs#L33) types to structure to query encrypted query cross-chain votes:
260+
`InnerMethods` leverages the SDK by using the [`GatewayQueryMsg`](https://github.com/writersblockchain/cosmos-ccl-encrypted-payloads-demo/blob/1aa91625546547960fd9556e17f14f31d99d726f/deploy-scripts/packages/sdk/src/gateway.rs#L33) types to query encrypted cross-chain votes. You have the choice of using two different types of encrypted queries: `query_with_auth_data` and `query_with_permit.` In this tutorial, you we will learn how to implement `query_with_permit`.&#x20;
261+
262+
1. [WithAuthData](https://github.com/writersblockchain/cosmos-ccl-encrypted-payloads-demo/blob/1429ba2e713f8156f4a82a782827dd1830628865/deploy-scripts/contracts/secret-voting/src/query.rs#L31):
231263

232264
```rust
233-
#[cw_serde]
234-
pub enum QueryMsg {
235-
EncryptionKey {},
265+
pub fn query_with_auth_data(
266+
deps : Deps,
267+
env : Env,
268+
auth_data : CosmosAuthData,
269+
query : InnerQueries
270+
) -> StdResult<Binary> {
271+
auth_data.verify(deps.api)?;
272+
auth_data.check_data(deps.storage, &env)?;
273+
let address = auth_data.primary_address()?;
274+
query_inner(deps, env,address, query)
275+
}
276+
```
236277

237-
WithAuthData {
238-
auth_data : sdk::CosmosAuthData,
239-
query : { MyVote { proposal_id: u64 } }
240-
},
278+
2. [WithPermit](https://github.com/writersblockchain/cosmos-ccl-encrypted-payloads-demo/blob/1429ba2e713f8156f4a82a782827dd1830628865/deploy-scripts/contracts/secret-voting/src/query.rs#L12):
241279

242-
WithPermit {
243-
permit : secret_toolkit::permit::Permit,
244-
hrp : Option<String>,
245-
query : { MyVote { proposal_id: u64 } }
246-
},
280+
```rust
281+
pub fn query_with_permit(
282+
deps : Deps,
283+
env : Env,
284+
permit : Permit,
285+
hrp : Option<String>,
286+
query : InnerQueries
287+
) -> StdResult<Binary> {
288+
let address = secret_toolkit::permit::validate(
289+
deps,
290+
PERMIT_PREFIX,
291+
&permit,
292+
env.contract.address.to_string(),
293+
hrp.as_deref()
294+
)?;
295+
query_inner(deps, env, address, query)
296+
}
297+
```
247298

248-
Extension {
249-
query : { Proposals {} / Proposal { proposal_id: u64 } / AllVotes { proposal_id: u64 } }
299+
Now let's take a look at the frontend code to see how query\_with\_permit is implemente&#x64;**.** :smile:
300+
301+
### **Frontend Query Logic**&#x20;
302+
303+
The Next.js query decryption logic can be found in [Gateway.ts](https://github.com/writersblockchain/cosmos-ccl-encrypted-payloads-demo/blob/main/next-frontend/src/functions/Gateway.ts):
304+
305+
[Query proposals](https://github.com/writersblockchain/cosmos-ccl-encrypted-payloads-demo/blob/1aa91625546547960fd9556e17f14f31d99d726f/next-frontend/src/functions/Gateway.ts#L163):&#x20;
306+
307+
```rust
308+
const query_proposals = (): Promise<[number, Proposal][]> => {
309+
return query_contract_public(contractConfig.votes, { extension: { query: { proposals: { } } } });
310+
}
311+
```
312+
313+
[Query votes](https://github.com/writersblockchain/cosmos-ccl-encrypted-payloads-demo/blob/1aa91625546547960fd9556e17f14f31d99d726f/next-frontend/src/functions/Gateway.ts#L151C3-L153C4):
314+
315+
```rust
316+
const query_my_vote = (proposal_id: number, message?: string) => {
317+
return query_contract_auth(contractConfig.votes, { my_vote: { proposal_id } }, message);
318+
}
319+
```
320+
321+
Because votes are encrypted, we must decrypt them in order to query a wallet's votes. The frontend function [`query_contract_auth`](https://github.com/writersblockchain/cosmos-ccl-encrypted-payloads-demo/blob/1aa91625546547960fd9556e17f14f31d99d726f/next-frontend/src/functions/Gateway.ts#L116) securely queries the Secret smart contract using **query permits**, ensuring that only authorized users can access sensitive data. Query permits are cryptographic credentials that:
322+
323+
* Prove the user’s ownership of a wallet.
324+
* Allow contracts to verify the user’s identity.
325+
* Avoid exposing the private key.
326+
327+
```rust
328+
const query_contract_auth = async (
329+
contract: Contract,
330+
query: object,
331+
data: string = "Query Permit"
332+
): Promise<any> => {
333+
334+
const storageKey = `${keplrAddress}:${contract.address}:queryPermit}`;
335+
const queryPermitStored = localStorage.getItem(storageKey);
336+
337+
let credential: CosmosCredential;
338+
339+
if (queryPermitStored) {
340+
credential = JSON.parse(queryPermitStored) as CosmosCredential;
341+
} else {
342+
const toSign: DataToSign = {
343+
chain_id: "secret-4",
344+
contract_address: contract.address,
345+
nonce: toBase64(Random.getBytes(32)),
346+
data: btoa(data)
347+
}
348+
const message = toUtf8(JSON.stringify(toSign));
349+
const signRes = await (window as any).keplr.signArbitrary(chainId, keplrAddress!, JSON.stringify(toSign))
350+
credential = {
351+
message: toBase64(message),
352+
signature: signRes.signature,
353+
pubkey: signRes.pub_key.value,
354+
hrp: keplrAddress!.split("1")[0]
355+
}
356+
localStorage.setItem(storageKey, JSON.stringify(credential));
250357
}
251-
}
358+
const res = await queryGatewayAuth(contract, query, [credential]);
359+
console.log("query:", query, " res:", res);
360+
return res;
361+
}
252362
```
253363

364+
You now should have all the tools you need to use the IBC CCL toolkit! Lastly, let's learn how to deploy your own voting contract on Secret Network :clap:
365+
254366
## How to upload a voting contract to Secret Network
255367

256368
`cd` into `deploy-scripts` and install the dependencies:&#x20;
@@ -291,8 +403,17 @@ In your terminal, a `codeID`, `codeHash`, and `contractAddress` will be returned
291403
"address": "secret1q0mycclu927u5m0tn50zgl5af4utrlkzz706lm"
292404
```
293405

406+
Finally, update [config.ts](https://github.com/writersblockchain/cosmos-ccl-encrypted-payloads-demo/blob/1429ba2e713f8156f4a82a782827dd1830628865/next-frontend/src/ccl-sdk/config.ts#L68) with your contract's code\_hash and address:
407+
408+
```typescript
409+
const contractMultiConfig: ContractMultiConfig = {
410+
votes: {
411+
address: "secret1jtc7f8cj5hhc2mg9v5uknd84knvythvsjhd66a",
412+
hash: "ff8443878e8a339637c45c13abc4385c4f0c5668b992afc912e5f59e5d098654"
413+
},
414+
};
415+
```
416+
294417
## Conclusion
295418

296-
{% hint style="danger" %}
297-
_**In progress 12.6.24**_
298-
{% endhint %}
419+
Congratulations on completing this on using Secret Network's IBC SDK to encrypt votes cross-chain using Secret smart contracts! 🎉 You've explored the intricacies of encrypted messaging, cross-chain IBC interactions, and secure smart contract execution using the Secret Network CCL SDK. By building and running the fullstack application, you’ve gained hands-on experience in contract deployment, frontend integration, and secure querying with query permits. 🚀

0 commit comments

Comments
 (0)