Sfoglia il codice sorgente

contract/money/client/genesis_mint: allow optional different recipient

skoupidi 2 anni fa
parent
commit
6e59afaee3

+ 23 - 6
script/research/gg/src/main.rs

@@ -39,7 +39,7 @@ use darkfi_money_contract::{
     client::genesis_mint_v1::GenesisMintCallBuilder, MoneyFunction, MONEY_CONTRACT_ZKAS_MINT_NS_V1,
 };
 use darkfi_sdk::{
-    crypto::{contract_id::MONEY_CONTRACT_ID, FuncId, Keypair, SecretKey},
+    crypto::{contract_id::MONEY_CONTRACT_ID, FuncId, PublicKey, SecretKey},
     pasta::{group::ff::PrimeField, pallas},
     ContractCall,
 };
@@ -77,9 +77,15 @@ enum Subcmd {
         /// Amount to mint for this genesis transaction
         amount: String,
 
+        #[arg(short, long)]
+        /// Optional recipient's public key, in case we want to mint to a different address
+        recipient: Option<String>,
+
+        #[arg(short, long)]
         /// Optional contract spend hook to use
         spend_hook: Option<String>,
 
+        #[arg(short, long)]
         /// Optional user data to use
         user_data: Option<String>,
     },
@@ -162,11 +168,10 @@ async fn main() -> Result<()> {
             println!("Genesis block {hash} verified successfully!");
         }
 
-        Subcmd::GenerateTx { amount, spend_hook, user_data } => {
+        Subcmd::GenerateTx { amount, recipient, spend_hook, user_data } => {
             let mut buf = String::new();
             stdin().read_to_string(&mut buf)?;
-            let secret = SecretKey::from_str(buf.trim())?;
-            let keypair = Keypair::new(secret);
+            let signature_secret = SecretKey::from_str(buf.trim())?;
 
             if let Err(e) = f64::from_str(&amount) {
                 eprintln!("Invalid amount: {e:?}");
@@ -174,6 +179,17 @@ async fn main() -> Result<()> {
             }
             let amount = decode_base10(&amount, 8, true)?;
 
+            let recipient = match recipient {
+                Some(r) => match PublicKey::from_str(&r) {
+                    Ok(r) => Some(r),
+                    Err(e) => {
+                        eprintln!("Invalid recipient: {e:?}");
+                        exit(2);
+                    }
+                },
+                None => None,
+            };
+
             let spend_hook = match spend_hook {
                 Some(s) => match FuncId::from_str(&s) {
                     Ok(s) => Some(s),
@@ -226,8 +242,9 @@ async fn main() -> Result<()> {
 
             // Build the contract call
             let builder = GenesisMintCallBuilder {
-                keypair,
+                signature_public: PublicKey::from_secret(signature_secret),
                 amount,
+                recipient,
                 spend_hook,
                 user_data,
                 mint_zkbin,
@@ -243,7 +260,7 @@ async fn main() -> Result<()> {
             let mut tx_builder =
                 TransactionBuilder::new(ContractCallLeaf { call, proofs: debris.proofs }, vec![])?;
             let mut tx = tx_builder.build()?;
-            let sigs = tx.create_sigs(&[keypair.secret])?;
+            let sigs = tx.create_sigs(&[signature_secret])?;
             tx.signatures = vec![sigs];
 
             println!("{}", base64::encode(&serialize_async(&tx).await));

+ 7 - 5
src/contract/money/src/client/genesis_mint_v1.rs

@@ -22,7 +22,7 @@ use darkfi::{
     ClientFailed, Result,
 };
 use darkfi_sdk::{
-    crypto::{note::AeadEncryptedNote, pasta_prelude::*, Blind, FuncId, Keypair},
+    crypto::{note::AeadEncryptedNote, pasta_prelude::*, Blind, FuncId, PublicKey},
     pasta::pallas,
 };
 use log::debug;
@@ -59,10 +59,12 @@ impl GenesisMintRevealed {
 
 /// Struct holding necessary information to build a `Money::GenesisMintV1` contract call.
 pub struct GenesisMintCallBuilder {
-    /// Caller's keypair
-    pub keypair: Keypair,
+    /// Caller's public key, corresponding to the one used in the signature
+    pub signature_public: PublicKey,
     /// Amount of tokens we want to mint
     pub amount: u64,
+    /// Optional recipient's public key, in case we want to mint to a different address
+    pub recipient: Option<PublicKey>,
     /// Optional contract spend hook to use in the output
     pub spend_hook: Option<FuncId>,
     /// Optional user data to use in the output
@@ -93,7 +95,7 @@ impl GenesisMintCallBuilder {
             token_id,
             value_blind,
             token_blind,
-            signature_public: self.keypair.public,
+            signature_public: self.signature_public,
         };
 
         // Grab the spend hook and user data to use in the output
@@ -102,7 +104,7 @@ impl GenesisMintCallBuilder {
 
         // Building the anonymous output
         let output = TransferCallOutput {
-            public_key: self.keypair.public,
+            public_key: self.recipient.unwrap_or(self.signature_public),
             value: self.amount,
             token_id,
             spend_hook,

+ 2 - 1
src/contract/test-harness/src/money_genesis_mint.rs

@@ -52,8 +52,9 @@ impl TestHarness {
 
         // Build the contract call
         let builder = GenesisMintCallBuilder {
-            keypair: wallet.keypair,
+            signature_public: wallet.keypair.public,
             amount,
+            recipient: None,
             spend_hook,
             user_data,
             mint_zkbin: mint_zkbin.clone(),