Просмотр исходного кода

dao: change proposals to new composable format

x 2 лет назад
Родитель
Сommit
6bb313db3d

+ 8 - 4
src/contract/dao/proof/dao-exec.zk

@@ -8,10 +8,15 @@ constant "DaoExec" {
 
 witness "DaoExec" {
 	# Proposal parameters
+    # delet [
 	Base proposal_dest_x,
 	Base proposal_dest_y,
 	Base proposal_amount,
 	Base proposal_token_id,
+    # ]
+    Base proposal_content_commit,
+    Base proposal_auth_contract_id,
+    Base proposal_auth_function_id,
 	Base proposal_blind,
 
 	# DAO parameters
@@ -61,10 +66,9 @@ circuit "DaoExec" {
 	# dao-propose-main.zk already checks that when we first create the
 	# proposal - so it is redundant here.
 	proposal_bulla = poseidon_hash(
-		proposal_dest_x,
-		proposal_dest_y,
-		proposal_amount,
-		proposal_token_id,
+        proposal_content_commit,
+        proposal_auth_contract_id,
+        proposal_auth_function_id,
 		dao_bulla,
 		proposal_blind,
 	);

+ 6 - 8
src/contract/dao/proof/dao-propose-main.zk

@@ -15,10 +15,9 @@ witness "DaoProposeMain" {
 	Base gov_token_blind,
 
 	# Proposal parameters
-	Base proposal_dest_x,
-	Base proposal_dest_y,
-	Base proposal_amount,
-	Base proposal_token_id,
+    Base proposal_content_commit,
+    Base proposal_auth_contract_id,
+    Base proposal_auth_function_id,
 	Base proposal_blind,
 
 	# DAO params
@@ -55,10 +54,9 @@ circuit "DaoProposeMain" {
 	# Proves this DAO is valid
 
 	proposal_bulla = poseidon_hash(
-		proposal_dest_x,
-		proposal_dest_y,
-		proposal_amount,
-		proposal_token_id,
+        proposal_content_commit,
+        proposal_auth_contract_id,
+        proposal_auth_function_id,
 		dao_bulla,
 		proposal_blind,
 	);

+ 6 - 8
src/contract/dao/proof/dao-vote-main.zk

@@ -8,10 +8,9 @@ constant "DaoVoteMain" {
 
 witness "DaoVoteMain" {
 	# Proposal parameters
-	Base proposal_dest_x,
-	Base proposal_dest_y,
-	Base proposal_amount,
-	Base proposal_token_id,
+    Base proposal_content_commit,
+    Base proposal_auth_contract_id,
+    Base proposal_auth_function_id,
 	Base proposal_blind,
 
 	# DAO parameters
@@ -52,10 +51,9 @@ circuit "DaoVoteMain" {
 	);
 
 	proposal_bulla = poseidon_hash(
-		proposal_dest_x,
-		proposal_dest_y,
-		proposal_amount,
-		proposal_token_id,
+        proposal_content_commit,
+        proposal_auth_contract_id,
+        proposal_auth_function_id,
 		dao_bulla,
 		proposal_blind,
 	);

+ 5 - 3
src/contract/dao/src/client/exec.rs

@@ -22,17 +22,16 @@ use darkfi_sdk::{
     pasta::pallas,
 };
 
-use halo2_proofs::circuit::Value;
 use log::debug;
 use rand::rngs::OsRng;
 
 use darkfi::{
-    zk::{Proof, ProvingKey, Witness, ZkCircuit},
+    zk::{halo2::Value, Proof, ProvingKey, Witness, ZkCircuit},
     zkas::ZkBinary,
     Result,
 };
 
-use crate::model::{Dao, DaoBlindAggregateVote, DaoExecParams, DaoProposal, DaoProposalBulla};
+use crate::model::{Dao, DaoBlindAggregateVote, DaoExecParams, DaoProposal};
 
 pub struct DaoExecCall {
     pub proposal: DaoProposal,
@@ -116,6 +115,9 @@ impl DaoExecCall {
             Witness::Base(Value::known(proposal_dest_y)),
             Witness::Base(Value::known(proposal_amount)),
             Witness::Base(Value::known(self.proposal.token_id.inner())),
+            Witness::Base(Value::known(self.proposal.content_commit)),
+            Witness::Base(Value::known(self.proposal.auth_contract_id)),
+            Witness::Base(Value::known(self.proposal.auth_function_id)),
             Witness::Base(Value::known(self.proposal.blind)),
             // DAO params
             Witness::Base(Value::known(dao_proposer_limit)),

+ 31 - 38
src/contract/dao/src/client/propose.rs

@@ -30,7 +30,7 @@ use darkfi_serial::{async_trait, SerialDecodable, SerialEncodable};
 use rand::rngs::OsRng;
 
 use darkfi::{
-    zk::{halo2, Proof, ProvingKey, Witness, ZkCircuit},
+    zk::{halo2::Value, Proof, ProvingKey, Witness, ZkCircuit},
     zkas::ZkBinary,
     Result,
 };
@@ -87,19 +87,17 @@ impl DaoProposeCall {
             let leaf_pos: u64 = input.leaf_position.into();
 
             let prover_witnesses = vec![
-                Witness::Base(halo2::Value::known(input.secret.inner())),
-                Witness::Base(halo2::Value::known(note.serial)),
-                Witness::Base(halo2::Value::known(pallas::Base::from(0))),
-                Witness::Base(halo2::Value::known(pallas::Base::from(0))),
-                Witness::Base(halo2::Value::known(pallas::Base::from(note.value))),
-                Witness::Base(halo2::Value::known(note.token_id.inner())),
-                Witness::Scalar(halo2::Value::known(funds_blind)),
-                Witness::Base(halo2::Value::known(gov_token_blind)),
-                Witness::Uint32(halo2::Value::known(leaf_pos.try_into().unwrap())),
-                Witness::MerklePath(halo2::Value::known(
-                    input.merkle_path.clone().try_into().unwrap(),
-                )),
-                Witness::Base(halo2::Value::known(input.signature_secret.inner())),
+                Witness::Base(Value::known(input.secret.inner())),
+                Witness::Base(Value::known(note.serial)),
+                Witness::Base(Value::known(pallas::Base::from(0))),
+                Witness::Base(Value::known(pallas::Base::from(0))),
+                Witness::Base(Value::known(pallas::Base::from(note.value))),
+                Witness::Base(Value::known(note.token_id.inner())),
+                Witness::Scalar(Value::known(funds_blind)),
+                Witness::Base(Value::known(gov_token_blind)),
+                Witness::Uint32(Value::known(leaf_pos.try_into().unwrap())),
+                Witness::MerklePath(Value::known(input.merkle_path.clone().try_into().unwrap())),
+                Witness::Base(Value::known(input.signature_secret.inner())),
             ];
 
             let public_key = PublicKey::from_secret(input.secret);
@@ -129,7 +127,7 @@ impl DaoProposeCall {
                 current
             };
 
-            let token_commit = poseidon_hash::<2>([note.token_id.inner(), gov_token_blind]);
+            let token_commit = poseidon_hash([note.token_id.inner(), gov_token_blind]);
             assert_eq!(self.dao.gov_token_id, note.token_id);
 
             let value_commit = pedersen_commitment_u64(note.value, funds_blind);
@@ -160,11 +158,7 @@ impl DaoProposeCall {
         let total_funds_coords = total_funds_commit.to_affine().coordinates().unwrap();
         let total_funds = pallas::Base::from(total_funds);
 
-        let token_commit = poseidon_hash::<2>([self.dao.gov_token_id.inner(), gov_token_blind]);
-
-        let (proposal_dest_x, proposal_dest_y) = self.proposal.dest.xy();
-
-        let proposal_amount = pallas::Base::from(self.proposal.amount);
+        let token_commit = poseidon_hash([self.dao.gov_token_id.inner(), gov_token_blind]);
 
         let dao_proposer_limit = pallas::Base::from(self.dao.proposer_limit);
         let dao_quorum = pallas::Base::from(self.dao.quorum);
@@ -179,27 +173,26 @@ impl DaoProposeCall {
 
         let prover_witnesses = vec![
             // Proposers total number of gov tokens
-            Witness::Base(halo2::Value::known(total_funds)),
-            Witness::Scalar(halo2::Value::known(total_funds_blinds)),
+            Witness::Base(Value::known(total_funds)),
+            Witness::Scalar(Value::known(total_funds_blinds)),
             // Used for blinding exported gov token ID
-            Witness::Base(halo2::Value::known(gov_token_blind)),
+            Witness::Base(Value::known(gov_token_blind)),
             // proposal params
-            Witness::Base(halo2::Value::known(proposal_dest_x)),
-            Witness::Base(halo2::Value::known(proposal_dest_y)),
-            Witness::Base(halo2::Value::known(proposal_amount)),
-            Witness::Base(halo2::Value::known(self.proposal.token_id.inner())),
-            Witness::Base(halo2::Value::known(self.proposal.blind)),
+            Witness::Base(Value::known(self.proposal.content_commit)),
+            Witness::Base(Value::known(self.proposal.auth_contract_id)),
+            Witness::Base(Value::known(self.proposal.auth_function_id)),
+            Witness::Base(Value::known(self.proposal.blind)),
             // DAO params
-            Witness::Base(halo2::Value::known(dao_proposer_limit)),
-            Witness::Base(halo2::Value::known(dao_quorum)),
-            Witness::Base(halo2::Value::known(dao_approval_ratio_quot)),
-            Witness::Base(halo2::Value::known(dao_approval_ratio_base)),
-            Witness::Base(halo2::Value::known(self.dao.gov_token_id.inner())),
-            Witness::Base(halo2::Value::known(dao_pub_x)),
-            Witness::Base(halo2::Value::known(dao_pub_y)),
-            Witness::Base(halo2::Value::known(self.dao.bulla_blind)),
-            Witness::Uint32(halo2::Value::known(dao_leaf_position.try_into().unwrap())),
-            Witness::MerklePath(halo2::Value::known(self.dao_merkle_path.try_into().unwrap())),
+            Witness::Base(Value::known(dao_proposer_limit)),
+            Witness::Base(Value::known(dao_quorum)),
+            Witness::Base(Value::known(dao_approval_ratio_quot)),
+            Witness::Base(Value::known(dao_approval_ratio_base)),
+            Witness::Base(Value::known(self.dao.gov_token_id.inner())),
+            Witness::Base(Value::known(dao_pub_x)),
+            Witness::Base(Value::known(dao_pub_y)),
+            Witness::Base(Value::known(self.dao.bulla_blind)),
+            Witness::Uint32(Value::known(dao_leaf_position.try_into().unwrap())),
+            Witness::MerklePath(Value::known(self.dao_merkle_path.try_into().unwrap())),
         ];
         let public_inputs = vec![
             token_commit,

+ 35 - 60
src/contract/dao/src/client/vote.rs

@@ -31,12 +31,12 @@ use log::debug;
 use rand::rngs::OsRng;
 
 use darkfi::{
-    zk::{halo2, Proof, ProvingKey, Witness, ZkCircuit},
+    zk::{halo2::Value, Proof, ProvingKey, Witness, ZkCircuit},
     zkas::ZkBinary,
     Result,
 };
 
-use crate::model::{Dao, DaoProposal, DaoProposalBulla, DaoVoteParams, DaoVoteParamsInput};
+use crate::model::{Dao, DaoProposal, DaoVoteParams, DaoVoteParamsInput};
 
 #[derive(SerialEncodable, SerialDecodable)]
 pub struct DaoVoteNote {
@@ -95,19 +95,17 @@ impl DaoVoteCall {
             let leaf_pos: u64 = input.leaf_position.into();
 
             let prover_witnesses = vec![
-                Witness::Base(halo2::Value::known(input.secret.inner())),
-                Witness::Base(halo2::Value::known(note.serial)),
-                Witness::Base(halo2::Value::known(pallas::Base::from(0))),
-                Witness::Base(halo2::Value::known(pallas::Base::from(0))),
-                Witness::Base(halo2::Value::known(pallas::Base::from(note.value))),
-                Witness::Base(halo2::Value::known(note.token_id.inner())),
-                Witness::Scalar(halo2::Value::known(all_vote_blind)),
-                Witness::Base(halo2::Value::known(gov_token_blind)),
-                Witness::Uint32(halo2::Value::known(leaf_pos.try_into().unwrap())),
-                Witness::MerklePath(halo2::Value::known(
-                    input.merkle_path.clone().try_into().unwrap(),
-                )),
-                Witness::Base(halo2::Value::known(input.signature_secret.inner())),
+                Witness::Base(Value::known(input.secret.inner())),
+                Witness::Base(Value::known(note.serial)),
+                Witness::Base(Value::known(pallas::Base::from(0))),
+                Witness::Base(Value::known(pallas::Base::from(0))),
+                Witness::Base(Value::known(pallas::Base::from(note.value))),
+                Witness::Base(Value::known(note.token_id.inner())),
+                Witness::Scalar(Value::known(all_vote_blind)),
+                Witness::Base(Value::known(gov_token_blind)),
+                Witness::Uint32(Value::known(leaf_pos.try_into().unwrap())),
+                Witness::MerklePath(Value::known(input.merkle_path.clone().try_into().unwrap())),
+                Witness::Base(Value::known(input.signature_secret.inner())),
             ];
 
             let public_key = PublicKey::from_secret(input.secret);
@@ -135,10 +133,10 @@ impl DaoVoteCall {
                 current
             };
 
-            let token_commit = poseidon_hash::<2>([note.token_id.inner(), gov_token_blind]);
+            let token_commit = poseidon_hash([note.token_id.inner(), gov_token_blind]);
             assert_eq!(self.dao.gov_token_id, note.token_id);
 
-            let nullifier = poseidon_hash::<2>([input.secret.inner(), note.serial]);
+            let nullifier = poseidon_hash([input.secret.inner(), note.serial]);
 
             let vote_commit = pedersen_commitment_u64(note.value, all_vote_blind);
             let vote_commit_coords = vote_commit.to_affine().coordinates().unwrap();
@@ -170,38 +168,16 @@ impl DaoVoteCall {
             inputs.push(input);
         }
 
-        let token_commit = poseidon_hash::<2>([self.dao.gov_token_id.inner(), gov_token_blind]);
-
-        let (proposal_dest_x, proposal_dest_y) = self.proposal.dest.xy();
-
-        let proposal_amount = pallas::Base::from(self.proposal.amount);
+        let token_commit = poseidon_hash([self.dao.gov_token_id.inner(), gov_token_blind]);
 
         let dao_proposer_limit = pallas::Base::from(self.dao.proposer_limit);
         let dao_quorum = pallas::Base::from(self.dao.quorum);
         let dao_approval_ratio_quot = pallas::Base::from(self.dao.approval_ratio_quot);
         let dao_approval_ratio_base = pallas::Base::from(self.dao.approval_ratio_base);
-
         let (dao_pub_x, dao_pub_y) = self.dao.public_key.xy();
 
-        let dao_bulla = poseidon_hash::<8>([
-            dao_proposer_limit,
-            dao_quorum,
-            dao_approval_ratio_quot,
-            dao_approval_ratio_base,
-            self.dao.gov_token_id.inner(),
-            dao_pub_x,
-            dao_pub_y,
-            self.dao.bulla_blind,
-        ]);
-
-        let proposal_bulla = DaoProposalBulla::from(poseidon_hash::<6>([
-            proposal_dest_x,
-            proposal_dest_y,
-            proposal_amount,
-            self.proposal.token_id.inner(),
-            dao_bulla,
-            self.proposal.blind,
-        ]));
+        assert_eq!(self.dao.to_bulla(), self.proposal.dao_bulla);
+        let proposal_bulla = self.proposal.to_bulla();
 
         let vote_option = self.vote_option as u64;
         assert!(vote_option == 0 || vote_option == 1);
@@ -215,28 +191,27 @@ impl DaoVoteCall {
 
         let prover_witnesses = vec![
             // proposal params
-            Witness::Base(halo2::Value::known(proposal_dest_x)),
-            Witness::Base(halo2::Value::known(proposal_dest_y)),
-            Witness::Base(halo2::Value::known(proposal_amount)),
-            Witness::Base(halo2::Value::known(self.proposal.token_id.inner())),
-            Witness::Base(halo2::Value::known(self.proposal.blind)),
+            Witness::Base(Value::known(self.proposal.content_commit)),
+            Witness::Base(Value::known(self.proposal.auth_contract_id)),
+            Witness::Base(Value::known(self.proposal.auth_function_id)),
+            Witness::Base(Value::known(self.proposal.blind)),
             // DAO params
-            Witness::Base(halo2::Value::known(dao_proposer_limit)),
-            Witness::Base(halo2::Value::known(dao_quorum)),
-            Witness::Base(halo2::Value::known(dao_approval_ratio_quot)),
-            Witness::Base(halo2::Value::known(dao_approval_ratio_base)),
-            Witness::Base(halo2::Value::known(self.dao.gov_token_id.inner())),
-            Witness::Base(halo2::Value::known(dao_pub_x)),
-            Witness::Base(halo2::Value::known(dao_pub_y)),
-            Witness::Base(halo2::Value::known(self.dao.bulla_blind)),
+            Witness::Base(Value::known(dao_proposer_limit)),
+            Witness::Base(Value::known(dao_quorum)),
+            Witness::Base(Value::known(dao_approval_ratio_quot)),
+            Witness::Base(Value::known(dao_approval_ratio_base)),
+            Witness::Base(Value::known(self.dao.gov_token_id.inner())),
+            Witness::Base(Value::known(dao_pub_x)),
+            Witness::Base(Value::known(dao_pub_y)),
+            Witness::Base(Value::known(self.dao.bulla_blind)),
             // Vote
-            Witness::Base(halo2::Value::known(pallas::Base::from(vote_option))),
-            Witness::Scalar(halo2::Value::known(self.yes_vote_blind)),
+            Witness::Base(Value::known(pallas::Base::from(vote_option))),
+            Witness::Scalar(Value::known(self.yes_vote_blind)),
             // Total number of gov tokens allocated
-            Witness::Base(halo2::Value::known(pallas::Base::from(all_vote_value))),
-            Witness::Scalar(halo2::Value::known(all_vote_blind)),
+            Witness::Base(Value::known(pallas::Base::from(all_vote_value))),
+            Witness::Scalar(Value::known(all_vote_blind)),
             // gov token
-            Witness::Base(halo2::Value::known(gov_token_blind)),
+            Witness::Base(Value::known(gov_token_blind)),
         ];
 
         let public_inputs = vec![

+ 10 - 8
src/contract/dao/src/model.rs

@@ -52,7 +52,7 @@ impl Dao {
         let approval_ratio_quot = pallas::Base::from(self.approval_ratio_quot);
         let approval_ratio_base = pallas::Base::from(self.approval_ratio_base);
         let (pub_x, pub_y) = self.public_key.xy();
-        let bulla = poseidon_hash::<8>([
+        let bulla = poseidon_hash([
             proposer_limit,
             quorum,
             approval_ratio_quot,
@@ -116,22 +116,24 @@ impl TryInto<DaoBulla> for ShareAddress {
 
 #[derive(Debug, Clone, SerialEncodable, SerialDecodable)]
 pub struct DaoProposal {
+    // delet [
     pub dest: PublicKey,
     pub amount: u64,
     pub token_id: TokenId,
+    // ]
+    pub content_commit: pallas::Base,
+    pub auth_contract_id: pallas::Base,
+    pub auth_function_id: pallas::Base,
     pub dao_bulla: DaoBulla,
     pub blind: pallas::Base,
 }
 
 impl DaoProposal {
     pub fn to_bulla(&self) -> DaoProposalBulla {
-        let (dest_x, dest_y) = self.dest.xy();
-        let amount = pallas::Base::from(self.amount);
-        let bulla = poseidon_hash::<6>([
-            dest_x,
-            dest_y,
-            amount,
-            self.token_id.inner(),
+        let bulla = poseidon_hash([
+            self.content_commit,
+            self.auth_contract_id,
+            self.auth_function_id,
             self.dao_bulla.inner(),
             self.blind,
         ]);

+ 13 - 2
src/contract/dao/tests/integration.rs

@@ -24,7 +24,10 @@ use darkfi_dao_contract::{
 };
 use darkfi_money_contract::model::CoinParams;
 use darkfi_sdk::{
-    crypto::{pasta_prelude::Field, pedersen_commitment_u64, DAO_CONTRACT_ID, DARK_TOKEN_ID},
+    crypto::{
+        pasta_prelude::Field, pedersen_commitment_u64, poseidon_hash, DAO_CONTRACT_ID,
+        DARK_TOKEN_ID,
+    },
     pasta::pallas,
 };
 use log::info;
@@ -179,7 +182,7 @@ fn integration_test() -> Result<()> {
         info!("[Alice] Building DAO proposal tx");
 
         // These coins are passed around to all DAO members who verify its validity
-        // They check
+        // They also check hashing them equals the proposal_commit
         let coins = vec![CoinParams {
             public_key: th.holders.get(&Holder::Rachel).unwrap().keypair.public,
             value: PROPOSAL_AMOUNT,
@@ -188,9 +191,17 @@ fn integration_test() -> Result<()> {
             spend_hook: pallas::Base::ZERO,
             user_data: pallas::Base::ZERO,
         }];
+        // We can add whatever we want in here, even arbitrary text
+        // It's up to the auth module to decide what to do with it.
+        let content_commit = poseidon_hash([coins[0].to_coin().inner()]);
+        let auth_contract_id = pallas::Base::ZERO;
+        let auth_function_id = pallas::Base::ZERO;
 
         let (propose_tx, propose_params, propose_info) = th.dao_propose(
             &Holder::Alice,
+            content_commit,
+            auth_contract_id,
+            auth_function_id,
             &Holder::Rachel,
             PROPOSAL_AMOUNT,
             drk_token_id,

+ 1 - 1
src/contract/test-harness/src/dao_exec.rs

@@ -21,7 +21,7 @@ use std::time::Instant;
 use darkfi::{tx::Transaction, Result};
 use darkfi_dao_contract::{
     client::DaoExecCall,
-    model::{Dao, DaoProposal, DaoBulla, DaoExecParams},
+    model::{Dao, DaoBulla, DaoExecParams, DaoProposal},
     DaoFunction, DAO_CONTRACT_ZKAS_DAO_EXEC_NS,
 };
 use darkfi_money_contract::{

+ 3 - 1
src/contract/test-harness/src/dao_mint.rs

@@ -20,7 +20,9 @@ use std::time::Instant;
 
 use darkfi::{tx::Transaction, Result};
 use darkfi_dao_contract::{
-    client, model::{Dao, DaoMintParams}, DaoFunction, DAO_CONTRACT_ZKAS_DAO_MINT_NS,
+    client,
+    model::{Dao, DaoMintParams},
+    DaoFunction, DAO_CONTRACT_ZKAS_DAO_MINT_NS,
 };
 use darkfi_sdk::{
     crypto::{Keypair, MerkleNode, DAO_CONTRACT_ID},

+ 7 - 1
src/contract/test-harness/src/dao_propose.rs

@@ -21,7 +21,7 @@ use std::time::Instant;
 use darkfi::{tx::Transaction, Result};
 use darkfi_dao_contract::{
     client::{DaoProposeCall, DaoProposeStakeInput},
-    model::{Dao, DaoProposal, DaoBulla, DaoProposeParams},
+    model::{Dao, DaoBulla, DaoProposal, DaoProposeParams},
     DaoFunction, DAO_CONTRACT_ZKAS_DAO_PROPOSE_BURN_NS, DAO_CONTRACT_ZKAS_DAO_PROPOSE_MAIN_NS,
 };
 use darkfi_money_contract::client::OwnCoin;
@@ -39,6 +39,9 @@ impl TestHarness {
     pub fn dao_propose(
         &mut self,
         proposer: &Holder,
+        content_commit: pallas::Base,
+        auth_contract_id: pallas::Base,
+        auth_function_id: pallas::Base,
         recipient: &Holder,
         amount: u64,
         tx_token_id: TokenId,
@@ -78,6 +81,9 @@ impl TestHarness {
             dest: self.holders.get(recipient).unwrap().keypair.public,
             amount,
             token_id: tx_token_id,
+            content_commit,
+            auth_contract_id,
+            auth_function_id,
             // TODO: pass proposal in directly
             dao_bulla: dao.to_bulla(),
             blind: pallas::Base::random(&mut OsRng),