drk: Token mint freezing

This commit is contained in:
parazyd
2023-02-24 14:16:55 +01:00
parent 6c2dc8f9bc
commit e67f133be8
3 changed files with 84 additions and 4 deletions

View File

@@ -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(())
}
},
}
}

View File

@@ -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<Transaction> {
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)
}
}

View File

@@ -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<Nullifier> = vec![];
let mut outputs: Vec<Output> = vec![];
let mut freezes: Vec<TokenId> = 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(())