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

contract/dao: Derive DAO public key when minting, and enforce it.

parazyd 3 лет назад
Родитель
Сommit
8a06300ff5

+ 8 - 2
src/contract/dao/proof/dao-mint.zk

@@ -1,5 +1,6 @@
 constant "DaoMint" {
 	EcFixedPoint VALUE_COMMIT_RANDOM,
+	EcFixedPointBase NULLIFIER_K,
 }
 
 contract "DaoMint" {
@@ -8,14 +9,19 @@ contract "DaoMint" {
 	Base dao_approval_ratio_quot,
 	Base dao_approval_ratio_base,
 	Base gov_token_id,
-	Base dao_public_x,
-	Base dao_public_y,
+	Base dao_secret,
 	Base dao_bulla_blind,
 }
 
 circuit "DaoMint" {
 	# This circuit states that the bulla is a hash of 8 values
 
+	dao_public = ec_mul_base(dao_secret, NULLIFIER_K);
+	dao_public_x = ec_get_x(dao_public);
+	dao_public_y = ec_get_y(dao_public);
+	constrain_instance(dao_public_x);
+	constrain_instance(dao_public_y);
+
 	bulla = poseidon_hash(
 		dao_proposer_limit,
 		dao_quorum,

+ 5 - 5
src/contract/dao/src/dao_client/mint.rs

@@ -21,7 +21,7 @@ use darkfi::{
     zkas::ZkBinary,
     Result,
 };
-use darkfi_sdk::crypto::{pallas, poseidon_hash, PublicKey, TokenId};
+use darkfi_sdk::crypto::{pallas, poseidon_hash, PublicKey, SecretKey, TokenId};
 use log::debug;
 use rand::rngs::OsRng;
 
@@ -40,6 +40,7 @@ pub struct DaoInfo {
 
 pub fn make_mint_call(
     dao: &DaoInfo,
+    dao_secret_key: &SecretKey,
     dao_mint_zkbin: &ZkBinary,
     dao_mint_pk: &ProvingKey,
 ) -> Result<(DaoMintParams, Vec<Proof>)> {
@@ -70,17 +71,16 @@ pub fn make_mint_call(
         Witness::Base(halo2::Value::known(dao_approval_ratio_quot)),
         Witness::Base(halo2::Value::known(dao_approval_ratio_base)),
         Witness::Base(halo2::Value::known(dao.gov_token_id.inner())),
-        Witness::Base(halo2::Value::known(pub_x)),
-        Witness::Base(halo2::Value::known(pub_y)),
+        Witness::Base(halo2::Value::known(dao_secret_key.inner())),
         Witness::Base(halo2::Value::known(dao.bulla_blind)),
     ];
 
-    let public = vec![dao_bulla];
+    let public = vec![pub_x, pub_y, dao_bulla];
 
     let circuit = ZkCircuit::new(prover_witnesses, dao_mint_zkbin.clone());
     let proof = Proof::create(dao_mint_pk, &[circuit], &public, &mut OsRng)?;
 
-    let dao_mint_params = DaoMintParams { dao_bulla: dao_bulla.into() };
+    let dao_mint_params = DaoMintParams { dao_bulla: dao_bulla.into(), dao_pubkey: dao.public_key };
 
     Ok((dao_mint_params, vec![proof]))
 }

+ 1 - 0
src/contract/dao/src/dao_model.rs

@@ -37,6 +37,7 @@ impl From<pallas::Base> for DaoBulla {
 #[derive(SerialEncodable, SerialDecodable)]
 pub struct DaoMintParams {
     pub dao_bulla: DaoBulla,
+    pub dao_pubkey: PublicKey,
 }
 
 #[derive(SerialEncodable, SerialDecodable)]

+ 8 - 5
src/contract/dao/src/entrypoint.rs

@@ -412,7 +412,7 @@ fn process_update(cid: ContractId, ix: &[u8]) -> ContractResult {
     }
 }
 
-fn get_metadata(_: ContractId, ix: &[u8]) -> ContractResult {
+fn get_metadata(_cid: ContractId, ix: &[u8]) -> ContractResult {
     let (call_idx, call): (u32, Vec<ContractCall>) = deserialize(ix)?;
     assert!(call_idx < call.len() as u32);
 
@@ -423,11 +423,14 @@ fn get_metadata(_: ContractId, ix: &[u8]) -> ContractResult {
             let params: DaoMintParams = deserialize(&self_.data[1..])?;
 
             let mut zk_public_values: Vec<(String, Vec<pallas::Base>)> = vec![];
-            // TODO: Why no signatures? Should it be signed with the DAO keypair?
-            let signature_pubkeys: Vec<PublicKey> = vec![];
+            let signature_pubkeys: Vec<PublicKey> = vec![params.dao_pubkey];
+
+            let (pub_x, pub_y) = params.dao_pubkey.xy();
 
-            zk_public_values
-                .push((DAO_CONTRACT_ZKAS_DAO_MINT_NS.to_string(), vec![params.dao_bulla.inner()]));
+            zk_public_values.push((
+                DAO_CONTRACT_ZKAS_DAO_MINT_NS.to_string(),
+                vec![pub_x, pub_y, params.dao_bulla.inner()],
+            ));
 
             let mut metadata = vec![];
             zk_public_values.encode(&mut metadata)?;

+ 7 - 3
src/contract/dao/tests/integration.rs

@@ -83,15 +83,19 @@ async fn integration_test() -> Result<()> {
     // =======================================================
     debug!(target: "dao", "Stage 1. Creating DAO bulla");
 
-    let (params, proofs) =
-        dao_client::make_mint_call(&dao, &dao_th.dao_mint_zkbin, &dao_th.dao_mint_pk)?;
+    let (params, proofs) = dao_client::make_mint_call(
+        &dao,
+        &dao_th.dao_kp.secret,
+        &dao_th.dao_mint_zkbin,
+        &dao_th.dao_mint_pk,
+    )?;
 
     let mut data = vec![DaoFunction::Mint as u8];
     params.encode(&mut data)?;
     let calls = vec![ContractCall { contract_id: dao_th.dao_contract_id, data }];
     let proofs = vec![proofs];
     let mut tx = Transaction { calls, proofs, signatures: vec![] };
-    let sigs = tx.create_sigs(&mut OsRng, &[])?;
+    let sigs = tx.create_sigs(&mut OsRng, &[dao_th.dao_kp.secret])?;
     tx.signatures = vec![sigs];
 
     dao_th.alice_state.read().await.verify_transactions(&[tx.clone()], true).await?;