From e67f133be865bdbcef2bd244d7803e1385ca9a95 Mon Sep 17 00:00:00 2001 From: parazyd Date: Fri, 24 Feb 2023 14:16:55 +0100 Subject: [PATCH] drk: Token mint freezing --- bin/drk/src/main.rs | 17 +++++++++++- bin/drk/src/rpc_token.rs | 54 +++++++++++++++++++++++++++++++++++-- bin/drk/src/wallet_money.rs | 17 +++++++++++- 3 files changed, 84 insertions(+), 4 deletions(-) diff --git a/bin/drk/src/main.rs b/bin/drk/src/main.rs index 08438ff43..243a8ce2b 100644 --- a/bin/drk/src/main.rs +++ b/bin/drk/src/main.rs @@ -1206,7 +1206,22 @@ async fn main() -> Result<()> { Ok(()) } - TokenSubcmd::Freeze { token } => todo!(), + + TokenSubcmd::Freeze { token } => { + let token_id = + TokenId::try_from(token.as_str()).with_context(|| "Invalid token ID")?; + + let drk = Drk::new(args.endpoint).await?; + + let tx = drk + .freeze_token(token_id) + .await + .with_context(|| "Failed to create token freeze transaction")?; + + println!("{}", bs58::encode(&serialize(&tx)).into_string()); + + Ok(()) + } }, } } diff --git a/bin/drk/src/rpc_token.rs b/bin/drk/src/rpc_token.rs index b2e98bc6b..159d5217b 100644 --- a/bin/drk/src/rpc_token.rs +++ b/bin/drk/src/rpc_token.rs @@ -24,7 +24,8 @@ use darkfi::{ zkas::ZkBinary, }; use darkfi_money_contract::{ - client::mint_v1::MintCallBuilder, MoneyFunction, MONEY_CONTRACT_ZKAS_TOKEN_MINT_NS_V1, + client::{freeze_v1::FreezeCallBuilder, mint_v1::MintCallBuilder}, + MoneyFunction, MONEY_CONTRACT_ZKAS_TOKEN_FRZ_NS_V1, MONEY_CONTRACT_ZKAS_TOKEN_MINT_NS_V1, }; use darkfi_sdk::{ crypto::{contract_id::MONEY_CONTRACT_ID, Keypair, PublicKey, TokenId}, @@ -37,7 +38,7 @@ use rand::rngs::OsRng; use super::Drk; impl Drk { - /// Create a payment transaction. Returns the transaction object on success. + /// Create a token mint transaction. Returns the transaction object on success. pub async fn mint_token( &self, amount: &str, @@ -103,4 +104,53 @@ impl Drk { Ok(tx) } + + /// Create a token freeze transaction. Returns the transaction object on success. + pub async fn freeze_token(&self, token_id: TokenId) -> Result { + let mut tokens = self.list_tokens().await?; + tokens.retain(|x| x.0 == token_id); + if tokens.is_empty() { + return Err(anyhow!("Did not find mint authority for token ID {}", token_id)) + } + assert!(tokens.len() == 1); + + let mint_authority = Keypair::new(tokens[0].1); + + if tokens[0].2 { + return Err(anyhow!("This token is already marked as frozen in the wallet")) + } + + let zkas_bins = self.lookup_zkas(&MONEY_CONTRACT_ID).await?; + let zkas_ns = MONEY_CONTRACT_ZKAS_TOKEN_FRZ_NS_V1; + + let Some(token_freeze_zkbin) = zkas_bins.iter().find(|x| x.0 == zkas_ns) else { + return Err(anyhow!("Token freeze circuit not found")) + }; + + let k = 13; + let token_freeze_zkbin = ZkBinary::decode(&token_freeze_zkbin.1)?; + let token_freeze_circuit = + ZkCircuit::new(empty_witnesses(&token_freeze_zkbin), token_freeze_zkbin.clone()); + + eprintln!("Creating token freeze circuit proving keys"); + let freeze_builder = FreezeCallBuilder { + mint_authority, + token_freeze_zkbin, + token_freeze_pk: ProvingKey::build(k, &token_freeze_circuit), + }; + + eprintln!("Building transaction parameters"); + let debris = freeze_builder.build()?; + + // Encode and sign the transaction + let mut data = vec![MoneyFunction::FreezeV1 as u8]; + debris.params.encode(&mut data)?; + let calls = vec![ContractCall { contract_id: *MONEY_CONTRACT_ID, data }]; + let proofs = vec![debris.proofs]; + let mut tx = Transaction { calls, proofs, signatures: vec![] }; + let sigs = tx.create_sigs(&mut OsRng, &[mint_authority.secret])?; + tx.signatures = vec![sigs]; + + Ok(tx) + } } diff --git a/bin/drk/src/wallet_money.rs b/bin/drk/src/wallet_money.rs index 51ddf1d74..53d6fb361 100644 --- a/bin/drk/src/wallet_money.rs +++ b/bin/drk/src/wallet_money.rs @@ -31,7 +31,7 @@ use darkfi_money_contract::{ MONEY_KEYS_COL_IS_DEFAULT, MONEY_KEYS_COL_KEY_ID, MONEY_KEYS_COL_PUBLIC, MONEY_KEYS_COL_SECRET, MONEY_KEYS_TABLE, MONEY_TREE_COL_TREE, MONEY_TREE_TABLE, }, - model::{MoneyMintParamsV1, MoneyTransferParamsV1, Output}, + model::{MoneyFreezeParamsV1, MoneyMintParamsV1, MoneyTransferParamsV1, Output}, MoneyFunction, }; use darkfi_sdk::{ @@ -486,6 +486,7 @@ impl Drk { let mut nullifiers: Vec = vec![]; let mut outputs: Vec = vec![]; + let mut freezes: Vec = vec![]; for (i, call) in tx.calls.iter().enumerate() { if call.contract_id == cid && call.data[0] == MoneyFunction::TransferV1 as u8 { @@ -526,6 +527,16 @@ impl Drk { continue } + + if call.contract_id == cid && call.data[0] == MoneyFunction::FreezeV1 as u8 { + eprintln!("Found Money::FreezeV1 in call {}", i); + let params: MoneyFreezeParamsV1 = deserialize(&call.data[1..])?; + + let (mint_x, mint_y) = params.signature_public.xy(); + let token_id = TokenId::from(poseidon_hash([mint_x, mint_y])); + + freezes.push(token_id); + } } let secrets = self.get_money_secrets().await?; @@ -625,6 +636,10 @@ impl Drk { let _ = self.rpc_client.request(req).await?; } + for token_id in freezes { + // TODO: Update info in wallet if token id is found + } + if !owncoins.is_empty() { if let Err(_) = kaching().await { return Ok(())