Răsfoiți Sursa

daod: create coin_0 and coin_1, two Coin outputs of DAO::exec()

lunar-mining 4 ani în urmă
părinte
comite
c32c450f89

+ 29 - 2
bin/daod/proof/dao-exec.zk

@@ -35,6 +35,10 @@ contract "DaoExec" {
     Base input_value,
     Base input_value,
     Scalar input_value_blind,
     Scalar input_value_blind,
 
 
+    # misc
+    Base dao_spend_hook,
+    Base user_spend_hook,
+    Base user_data,
 }
 }
 
 
 circuit "DaoExec" {
 circuit "DaoExec" {
@@ -66,8 +70,31 @@ circuit "DaoExec" {
     );
     );
     constrain_instance(proposal_bulla);
     constrain_instance(proposal_bulla);
 
 
-    # Create coin0 = hash(...) and make public
-    # Create coin1 = hash(...) and make public
+    coin_0 = poseidon_hash(
+       proposal_dest_x,
+       proposal_dest_y,
+       proposal_amount,
+       proposal_token_id,
+       proposal_serial,
+       user_spend_hook,
+       user_data,
+       proposal_blind,
+    );
+    constrain_instance(coin_0);
+
+    change = base_sub(input_value, proposal_amount);
+
+    coin_1 = poseidon_hash(
+       dao_public_x,
+       dao_public_y,
+       change,
+       gov_token_id,
+       dao_serial,
+       dao_spend_hook,
+       proposal_bulla,
+       dao_coin_blind,
+    );
+    constrain_instance(coin_1);
 
 
     # Create pedersen commits for win_votes, and total_votes
     # Create pedersen commits for win_votes, and total_votes
     # and make public
     # and make public

+ 3 - 2
bin/daod/src/dao_contract/exec/validate.rs

@@ -32,12 +32,13 @@ impl From<DarkFiError> for Error {
 
 
 pub struct CallData {
 pub struct CallData {
     pub proposal: pallas::Base,
     pub proposal: pallas::Base,
+    pub coin_0: pallas::Base,
+    pub coin_1: pallas::Base,
 }
 }
 
 
 impl CallDataBase for CallData {
 impl CallDataBase for CallData {
     fn zk_public_values(&self) -> Vec<(String, Vec<DrkCircuitField>)> {
     fn zk_public_values(&self) -> Vec<(String, Vec<DrkCircuitField>)> {
-        //vec![("example-foo".to_string(), vec![self.header.public_c])]
-        vec![("dao-exec".to_string(), vec![self.proposal])]
+        vec![("dao-exec".to_string(), vec![self.proposal, self.coin_0, self.coin_1])]
     }
     }
 
 
     fn as_any(&self) -> &dyn Any {
     fn as_any(&self) -> &dyn Any {

+ 35 - 3
bin/daod/src/dao_contract/exec/wallet.rs

@@ -35,6 +35,7 @@ pub struct Builder {
     pub dao_coin_blind: pallas::Base,
     pub dao_coin_blind: pallas::Base,
     pub input_value: u64,
     pub input_value: u64,
     pub input_value_blind: pallas::Scalar,
     pub input_value_blind: pallas::Scalar,
+    pub hook_dao_exec: pallas::Base,
 }
 }
 
 
 impl Builder {
 impl Builder {
@@ -56,6 +57,11 @@ impl Builder {
         let dao_public_x = *dao_pubkey_coords.x();
         let dao_public_x = *dao_pubkey_coords.x();
         let dao_public_y = *dao_pubkey_coords.x();
         let dao_public_y = *dao_pubkey_coords.x();
 
 
+        let user_spend_hook = pallas::Base::from(0);
+        let user_data = pallas::Base::from(0);
+        let input_value = pallas::Base::from(self.input_value);
+        let change = input_value - proposal_amount;
+
         let dao_bulla = poseidon_hash::<8>([
         let dao_bulla = poseidon_hash::<8>([
             dao_proposer_limit,
             dao_proposer_limit,
             dao_quorum,
             dao_quorum,
@@ -80,6 +86,28 @@ impl Builder {
             self.proposal.blind,
             self.proposal.blind,
         ]);
         ]);
 
 
+        let coin_0 = poseidon_hash::<8>([
+            proposal_dest_x,
+            proposal_dest_y,
+            proposal_amount,
+            self.proposal.token_id,
+            self.proposal.serial,
+            user_spend_hook,
+            user_data,
+            self.proposal.blind,
+        ]);
+
+        let coin_1 = poseidon_hash::<8>([
+            dao_public_x,
+            dao_public_y,
+            change,
+            self.dao.gov_token_id,
+            self.dao_serial,
+            self.hook_dao_exec,
+            proposal_bulla,
+            self.dao_coin_blind,
+        ]);
+
         let zk_info = zk_bins.lookup(&"dao-exec".to_string()).unwrap();
         let zk_info = zk_bins.lookup(&"dao-exec".to_string()).unwrap();
         let zk_info = if let ZkContractInfo::Binary(info) = zk_info {
         let zk_info = if let ZkContractInfo::Binary(info) = zk_info {
             info
             info
@@ -115,11 +143,15 @@ impl Builder {
             Witness::Base(Value::known(self.user_coin_blind)),
             Witness::Base(Value::known(self.user_coin_blind)),
             Witness::Base(Value::known(self.dao_serial)),
             Witness::Base(Value::known(self.dao_serial)),
             Witness::Base(Value::known(self.dao_coin_blind)),
             Witness::Base(Value::known(self.dao_coin_blind)),
-            Witness::Base(Value::known(pallas::Base::from(self.input_value))),
+            Witness::Base(Value::known(input_value)),
             Witness::Scalar(Value::known(self.input_value_blind)),
             Witness::Scalar(Value::known(self.input_value_blind)),
+            // misc
+            Witness::Base(Value::known(self.hook_dao_exec)),
+            Witness::Base(Value::known(user_spend_hook)),
+            Witness::Base(Value::known(user_data)),
         ];
         ];
 
 
-        let public_inputs = vec![proposal_bulla];
+        let public_inputs = vec![proposal_bulla, coin_0, coin_1];
 
 
         let circuit = ZkCircuit::new(prover_witnesses, zk_bin);
         let circuit = ZkCircuit::new(prover_witnesses, zk_bin);
         debug!(target: "example_contract::foo::wallet::Builder", "input_proof Proof::create()");
         debug!(target: "example_contract::foo::wallet::Builder", "input_proof Proof::create()");
@@ -128,7 +160,7 @@ impl Builder {
             .expect("DAO::exec() proving error!)");
             .expect("DAO::exec() proving error!)");
         proofs.push(input_proof);
         proofs.push(input_proof);
 
 
-        let call_data = CallData { proposal: proposal_bulla };
+        let call_data = CallData { proposal: proposal_bulla, coin_0, coin_1 };
 
 
         FuncCall {
         FuncCall {
             contract_id: "DAO".to_string(),
             contract_id: "DAO".to_string(),

+ 1 - 1
bin/daod/src/demo.rs

@@ -1017,7 +1017,6 @@ pub async fn demo() -> Result<()> {
             win_votes += note.value;
             win_votes += note.value;
         }
         }
         total_votes += note.value;
         total_votes += note.value;
-
         let vote_result: String = if vote_option { "yes".to_string() } else { "no".to_string() };
         let vote_result: String = if vote_option { "yes".to_string() } else { "no".to_string() };
 
 
         debug!("Voter {} voted {}", i, vote_result);
         debug!("Voter {} voted {}", i, vote_result);
@@ -1102,6 +1101,7 @@ pub async fn demo() -> Result<()> {
         dao_coin_blind,
         dao_coin_blind,
         input_value,
         input_value,
         input_value_blind,
         input_value_blind,
+        hook_dao_exec,
     };
     };
     let exec_func_call = builder.build(&zk_bins);
     let exec_func_call = builder.build(&zk_bins);