From 3fc7ba6e2ca5a1c7bfca0a706443df896b1e04e4 Mon Sep 17 00:00:00 2001 From: zero Date: Fri, 2 Feb 2024 12:12:42 +0100 Subject: [PATCH] fix broken drk compile due to money token call changes --- bin/drk/src/main.rs | 45 ++++++++-------- bin/drk/src/money.rs | 25 +++++---- bin/drk/src/token.rs | 124 ++++++++++++++++++++++++++++++++++++------- 3 files changed, 144 insertions(+), 50 deletions(-) diff --git a/bin/drk/src/main.rs b/bin/drk/src/main.rs index c4d8c21ee..34ae7c2e5 100644 --- a/bin/drk/src/main.rs +++ b/bin/drk/src/main.rs @@ -1485,6 +1485,7 @@ async fn realmain(args: Args, ex: Arc>) -> Result<()> { exit(2); }; + // TODO: see TokenAttributes struct. I'm not sure how to restructure this rn. let token_id = TokenId::derive(mint_authority); eprintln!("Successfully imported mint authority for token ID: {token_id}"); @@ -1533,7 +1534,7 @@ async fn realmain(args: Args, ex: Arc>) -> Result<()> { exit(2); } - let rcpt = match PublicKey::from_str(&recipient) { + let _rcpt = match PublicKey::from_str(&recipient) { Ok(r) => r, Err(e) => { eprintln!("Invalid recipient: {e:?}"); @@ -1541,7 +1542,7 @@ async fn realmain(args: Args, ex: Arc>) -> Result<()> { } }; - let token_id = match drk.get_token(token).await { + let _token_id = match drk.get_token(token).await { Ok(t) => t, Err(e) => { eprintln!("Invalid Token ID: {e:?}"); @@ -1549,22 +1550,23 @@ async fn realmain(args: Args, ex: Arc>) -> Result<()> { } }; - let tx = match drk.mint_token(&amount, rcpt, token_id).await { - Ok(tx) => tx, - Err(e) => { - eprintln!("Failed to create token mint transaction: {e:?}"); - exit(2); - } - }; + panic!("temporarily disabled due to change of API for drk.mint_token() fn"); + //let tx = match drk.mint_token(&amount, rcpt, token_id).await { + // Ok(tx) => tx, + // Err(e) => { + // eprintln!("Failed to create token mint transaction: {e:?}"); + // exit(2); + // } + //}; - eprintln!("{}", bs58::encode(&serialize(&tx)).into_string()); + //eprintln!("{}", bs58::encode(&serialize(&tx)).into_string()); - Ok(()) + //Ok(()) } TokenSubcmd::Freeze { token } => { let drk = Drk::new(args.wallet_path, args.wallet_pass, args.endpoint, ex).await?; - let token_id = match drk.get_token(token).await { + let _token_id = match drk.get_token(token).await { Ok(t) => t, Err(e) => { eprintln!("Invalid Token ID: {e:?}"); @@ -1572,17 +1574,18 @@ async fn realmain(args: Args, ex: Arc>) -> Result<()> { } }; - let tx = match drk.freeze_token(token_id).await { - Ok(tx) => tx, - Err(e) => { - eprintln!("Failed to create token freeze transaction: {e:?}"); - exit(2); - } - }; + panic!("temporarily disabled due to change of API for drk.mint_token() fn"); + //let tx = match drk.freeze_token(token_id).await { + // Ok(tx) => tx, + // Err(e) => { + // eprintln!("Failed to create token freeze transaction: {e:?}"); + // exit(2); + // } + //}; - eprintln!("{}", bs58::encode(&serialize(&tx)).into_string()); + //eprintln!("{}", bs58::encode(&serialize(&tx)).into_string()); - Ok(()) + //Ok(()) } }, } diff --git a/bin/drk/src/money.rs b/bin/drk/src/money.rs index d124d0c4f..b7bc409bb 100644 --- a/bin/drk/src/money.rs +++ b/bin/drk/src/money.rs @@ -26,7 +26,7 @@ use darkfi::{tx::Transaction, zk::halo2::Field, Error, Result}; use darkfi_money_contract::{ client::{MoneyNote, OwnCoin}, model::{ - Coin, MoneyTokenFreezeParamsV1, MoneyTokenMintParamsV1, MoneyTransferParamsV1, Output, + Coin, MoneyTokenFreezeParamsV1, MoneyTokenMintParamsV1, MoneyTransferParamsV1, }, MoneyFunction, }; @@ -35,6 +35,7 @@ use darkfi_sdk::{ crypto::{ poseidon_hash, Keypair, MerkleNode, MerkleTree, Nullifier, PublicKey, SecretKey, TokenId, MONEY_CONTRACT_ID, + note::AeadEncryptedNote, }, pasta::pallas, }; @@ -626,7 +627,8 @@ impl Drk { let cid = *MONEY_CONTRACT_ID; let mut nullifiers: Vec = vec![]; - let mut outputs: Vec = vec![]; + let mut coins: Vec = vec![]; + let mut notes: Vec = vec![]; let mut freezes: Vec = vec![]; for (i, call) in tx.calls.iter().enumerate() { @@ -640,7 +642,8 @@ impl Drk { } for output in params.outputs { - outputs.push(output); + coins.push(output.coin); + notes.push(output.note); } continue @@ -655,7 +658,8 @@ impl Drk { } for output in params.outputs { - outputs.push(output); + coins.push(output.coin); + notes.push(output.note); } continue @@ -665,7 +669,8 @@ impl Drk { { eprintln!("Found Money::MintV1 in call {i}"); let params: MoneyTokenMintParamsV1 = deserialize(&call.data.data[1..])?; - outputs.push(params.output); + coins.push(params.coin); + //notes.push(output.note); continue } @@ -674,7 +679,7 @@ impl Drk { { eprintln!("Found Money::FreezeV1 in call {i}"); let params: MoneyTokenFreezeParamsV1 = deserialize(&call.data.data[1..])?; - let token_id = TokenId::derive_public(params.signature_public); + let token_id = TokenId::derive_public(params.mint_public); freezes.push(token_id); } } @@ -685,21 +690,19 @@ impl Drk { let mut owncoins = vec![]; - for output in outputs { - let coin = output.coin; - + for (coin, note) in coins.iter().zip(notes.iter()) { // Append the new coin to the Merkle tree. Every coin has to be added. tree.append(MerkleNode::from(coin.inner())); // Attempt to decrypt the note for secret in secrets.iter().chain(dao_secrets.iter()) { - if let Ok(note) = output.note.decrypt::(secret) { + if let Ok(note) = note.decrypt::(secret) { eprintln!("Successfully decrypted a Money Note"); eprintln!("Witnessing coin in Merkle tree"); let leaf_position = tree.mark().unwrap(); let owncoin = OwnCoin { - coin, + coin: coin.clone(), note: note.clone(), secret: *secret, nullifier: Nullifier::from(poseidon_hash([secret.inner(), coin.inner()])), diff --git a/bin/drk/src/token.rs b/bin/drk/src/token.rs index bfb3811ec..64e67b52b 100644 --- a/bin/drk/src/token.rs +++ b/bin/drk/src/token.rs @@ -27,11 +27,15 @@ use darkfi::{ Error, Result, }; use darkfi_money_contract::{ - client::{token_freeze_v1::TokenFreezeCallBuilder, token_mint_v1::TokenMintCallBuilder}, - MoneyFunction, MONEY_CONTRACT_ZKAS_TOKEN_FRZ_NS_V1, MONEY_CONTRACT_ZKAS_TOKEN_MINT_NS_V1, + client::{token_freeze_v1::TokenFreezeCallBuilder, token_mint_v1::TokenMintCallBuilder, auth_token_mint_v1::AuthTokenMintCallBuilder}, + MoneyFunction, MONEY_CONTRACT_ZKAS_TOKEN_FRZ_NS_V1, + MONEY_CONTRACT_ZKAS_TOKEN_MINT_NS_V1, + MONEY_CONTRACT_ZKAS_AUTH_TOKEN_MINT_NS_V1, + model::{CoinAttributes, TokenAttributes} }; use darkfi_sdk::{ - crypto::{contract_id::MONEY_CONTRACT_ID, Keypair, PublicKey, SecretKey, TokenId}, + crypto::{contract_id::MONEY_CONTRACT_ID, Keypair, PublicKey, SecretKey, TokenId, FuncRef, pasta_prelude::*}, + dark_tree::DarkLeaf, pasta::pallas, tx::ContractCall, }; @@ -108,13 +112,14 @@ impl Drk { &self, amount: &str, recipient: PublicKey, - token_id: TokenId, + token_attrs: TokenAttributes, ) -> Result { // TODO: Mint directly into DAO treasury let spend_hook = pallas::Base::zero(); let user_data = pallas::Base::zero(); let amount = decode_base10(amount, BALANCE_BASE10_DECIMALS, false)?; + let token_id = token_attrs.to_token_id(); let mut tokens = self.list_tokens().await?; tokens.retain(|x| x.0 == token_id); @@ -137,20 +142,44 @@ impl Drk { // the circuit objects and proving keys so we can build the transaction. // We also do this through the RPC. let zkas_bins = self.lookup_zkas(&MONEY_CONTRACT_ID).await?; - let zkas_ns = MONEY_CONTRACT_ZKAS_TOKEN_MINT_NS_V1; - let Some(token_mint_zkbin) = zkas_bins.iter().find(|x| x.0 == zkas_ns) else { - return Err(Error::Custom("Token mint circuit not found".to_string())) + let (mint_zkbin, mint_pk) = { + let mint_zkas_ns = MONEY_CONTRACT_ZKAS_TOKEN_MINT_NS_V1; + + let Some(token_mint_zkbin) = zkas_bins.iter().find(|x| x.0 == mint_zkas_ns) else { + return Err(Error::Custom("Token mint circuit not found".to_string())) + }; + + let mint_zkbin = ZkBinary::decode(&token_mint_zkbin.1)?; + let token_mint_circuit = + ZkCircuit::new(empty_witnesses(&mint_zkbin)?, &mint_zkbin); + + eprintln!("Creating token mint circuit proving keys"); + let mint_pk = ProvingKey::build(mint_zkbin.k, &token_mint_circuit); + + (mint_zkbin, mint_pk) }; - let token_mint_zkbin = ZkBinary::decode(&token_mint_zkbin.1)?; - let token_mint_circuit = - ZkCircuit::new(empty_witnesses(&token_mint_zkbin)?, &token_mint_zkbin); + let (auth_mint_zkbin, auth_mint_pk) = { + let auth_zkas_ns = MONEY_CONTRACT_ZKAS_AUTH_TOKEN_MINT_NS_V1; - eprintln!("Creating token mint circuit proving keys"); - let token_mint_pk = ProvingKey::build(token_mint_zkbin.k, &token_mint_circuit); + let Some(token_auth_mint_zkbin) = zkas_bins.iter().find(|x| x.0 == auth_zkas_ns) else { + return Err(Error::Custom("Token mint circuit not found".to_string())) + }; + + let auth_mint_zkbin = ZkBinary::decode(&token_auth_mint_zkbin.1)?; + let token_auth_mint_circuit = + ZkCircuit::new(empty_witnesses(&auth_mint_zkbin)?, &auth_mint_zkbin); + + eprintln!("Creating token mint circuit proving keys"); + let auth_mint_pk = ProvingKey::build(auth_mint_zkbin.k, &token_auth_mint_circuit); + + (auth_mint_zkbin, auth_mint_pk) + }; + + /* let mint_builder = TokenMintCallBuilder { - mint_authority, + mint_keypair: mint_authority, recipient, amount, spend_hook, @@ -171,12 +200,71 @@ impl Drk { let mut tx = tx_builder.build()?; let sigs = tx.create_sigs(&mut OsRng, &[mint_authority.secret])?; tx.signatures = vec![sigs]; + */ + + let _auth_func_id = FuncRef { + contract_id: *MONEY_CONTRACT_ID, + func_code: MoneyFunction::AuthTokenMintV1 as u8, + } + .to_func_id(); + + //let token_attrs = TokenAttributes { + // auth_parent: auth_func_id, + // user_data: poseidon_hash([mint_authority.public.x(), mint_authority.public.y()]), + // blind: token_blind, + //}; + //let token_id = token_attrs.to_token_id(); + + let coin_attrs = CoinAttributes { + public_key: recipient, + value: amount, + token_id, + spend_hook, + user_data, + blind: pallas::Base::random(&mut OsRng), + }; + + let builder = TokenMintCallBuilder { + coin_attrs: coin_attrs.clone(), + token_attrs: token_attrs.clone(), + mint_zkbin, + mint_pk, + }; + let mint_debris = builder.build()?; + let mut data = vec![MoneyFunction::TokenMintV1 as u8]; + mint_debris.params.encode(&mut data)?; + let mint_call = ContractCall { contract_id: *MONEY_CONTRACT_ID, data }; + + let builder = AuthTokenMintCallBuilder { + coin_attrs, + token_attrs, + mint_keypair: mint_authority, + auth_mint_zkbin, + auth_mint_pk, + }; + let auth_debris = builder.build()?; + let mut data = vec![MoneyFunction::AuthTokenMintV1 as u8]; + auth_debris.params.encode(&mut data)?; + let auth_call = ContractCall { contract_id: *MONEY_CONTRACT_ID, data }; + + let mut tx = Transaction { + calls: vec![ + DarkLeaf { data: mint_call, parent_index: Some(1), children_indexes: vec![] }, + DarkLeaf { data: auth_call, parent_index: None, children_indexes: vec![0] }, + ], + proofs: vec![mint_debris.proofs, auth_debris.proofs], + signatures: vec![], + }; + let mint_sigs = tx.create_sigs(&mut OsRng, &[])?; + let auth_sigs = tx.create_sigs(&mut OsRng, &[mint_authority.secret])?; + tx.signatures = vec![mint_sigs, auth_sigs]; Ok(tx) } /// Create a token freeze transaction. Returns the transaction object on success. - pub async fn freeze_token(&self, token_id: TokenId) -> Result { + pub async fn freeze_token(&self, token_attrs: TokenAttributes) -> Result { + let token_id = token_attrs.to_token_id(); let mut tokens = self.list_tokens().await?; tokens.retain(|x| x.0 == token_id); if tokens.is_empty() { @@ -201,14 +289,14 @@ impl Drk { return Err(Error::Custom("Token freeze circuit not found".to_string())) }; - let token_freeze_zkbin = ZkBinary::decode(&token_freeze_zkbin.1)?; + let freeze_zkbin = ZkBinary::decode(&token_freeze_zkbin.1)?; let token_freeze_circuit = - ZkCircuit::new(empty_witnesses(&token_freeze_zkbin)?, &token_freeze_zkbin); + ZkCircuit::new(empty_witnesses(&freeze_zkbin)?, &freeze_zkbin); eprintln!("Creating token freeze circuit proving keys"); - let token_freeze_pk = ProvingKey::build(token_freeze_zkbin.k, &token_freeze_circuit); + let freeze_pk = ProvingKey::build(freeze_zkbin.k, &token_freeze_circuit); let freeze_builder = - TokenFreezeCallBuilder { mint_authority, token_freeze_zkbin, token_freeze_pk }; + TokenFreezeCallBuilder { mint_keypair: mint_authority, token_attrs, freeze_zkbin, freeze_pk }; eprintln!("Building transaction parameters"); let debris = freeze_builder.build()?;