exec.rs 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. /* This file is part of DarkFi (https://dark.fi)
  2. *
  3. * Copyright (C) 2020-2022 Dyne.org foundation
  4. *
  5. * This program is free software: you can redistribute it and/or modify
  6. * it under the terms of the GNU Affero General Public License as
  7. * published by the Free Software Foundation, either version 3 of the
  8. * License, or (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU Affero General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU Affero General Public License
  16. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  17. */
  18. use darkfi_sdk::{
  19. crypto::{
  20. pedersen::pedersen_commitment_u64, poseidon_hash, MerkleNode, PublicKey, SecretKey, TokenId,
  21. },
  22. incrementalmerkletree,
  23. incrementalmerkletree::{bridgetree::BridgeTree, Hashable, Tree},
  24. pasta::{
  25. arithmetic::CurveAffine,
  26. group::{
  27. ff::{Field, PrimeField},
  28. Curve,
  29. },
  30. pallas,
  31. },
  32. };
  33. use darkfi_serial::{SerialDecodable, SerialEncodable};
  34. use halo2_proofs::circuit::Value;
  35. use log::{debug, info};
  36. use rand::rngs::OsRng;
  37. use darkfi::{
  38. zk::{
  39. proof::{Proof, ProvingKey},
  40. vm::ZkCircuit,
  41. vm_stack::Witness,
  42. },
  43. zkas::ZkBinary,
  44. Error, Result,
  45. };
  46. use super::propose::{DaoParams, Proposal};
  47. use crate::dao_model::DaoExecParams;
  48. pub struct Builder {
  49. pub proposal: Proposal,
  50. pub dao: DaoParams,
  51. pub yes_votes_value: u64,
  52. pub all_votes_value: u64,
  53. pub yes_votes_blind: pallas::Scalar,
  54. pub all_votes_blind: pallas::Scalar,
  55. pub user_serial: pallas::Base,
  56. pub user_coin_blind: pallas::Base,
  57. pub dao_serial: pallas::Base,
  58. pub dao_coin_blind: pallas::Base,
  59. pub input_value: u64,
  60. pub input_value_blind: pallas::Scalar,
  61. pub hook_dao_exec: pallas::Base,
  62. pub signature_secret: SecretKey,
  63. }
  64. impl Builder {
  65. pub fn build(
  66. self,
  67. exec_zkbin: &ZkBinary,
  68. exec_pk: &ProvingKey,
  69. ) -> Result<(DaoExecParams, Vec<Proof>)> {
  70. debug!(target: "dao", "build()");
  71. let mut proofs = vec![];
  72. let (proposal_dest_x, proposal_dest_y) = self.proposal.dest.xy();
  73. let proposal_amount = pallas::Base::from(self.proposal.amount);
  74. let dao_proposer_limit = pallas::Base::from(self.dao.proposer_limit);
  75. let dao_quorum = pallas::Base::from(self.dao.quorum);
  76. let dao_approval_ratio_quot = pallas::Base::from(self.dao.approval_ratio_quot);
  77. let dao_approval_ratio_base = pallas::Base::from(self.dao.approval_ratio_base);
  78. let (dao_pub_x, dao_pub_y) = self.dao.public_key.xy();
  79. let user_spend_hook = pallas::Base::from(0);
  80. let user_data = pallas::Base::from(0);
  81. let input_value = pallas::Base::from(self.input_value);
  82. let change = input_value - proposal_amount;
  83. let dao_bulla = poseidon_hash::<8>([
  84. dao_proposer_limit,
  85. dao_quorum,
  86. dao_approval_ratio_quot,
  87. dao_approval_ratio_base,
  88. self.dao.gov_token_id.inner(),
  89. dao_pub_x,
  90. dao_pub_y,
  91. self.dao.bulla_blind,
  92. ]);
  93. let proposal_bulla = poseidon_hash::<8>([
  94. proposal_dest_x,
  95. proposal_dest_y,
  96. proposal_amount,
  97. self.proposal.serial,
  98. self.proposal.token_id.inner(),
  99. dao_bulla,
  100. self.proposal.blind,
  101. // @tmp-workaround
  102. self.proposal.blind,
  103. ]);
  104. let coin_0 = poseidon_hash::<8>([
  105. proposal_dest_x,
  106. proposal_dest_y,
  107. proposal_amount,
  108. self.proposal.token_id.inner(),
  109. self.proposal.serial,
  110. user_spend_hook,
  111. user_data,
  112. self.proposal.blind,
  113. ]);
  114. let coin_1 = poseidon_hash::<8>([
  115. dao_pub_x,
  116. dao_pub_y,
  117. change,
  118. self.proposal.token_id.inner(),
  119. self.dao_serial,
  120. self.hook_dao_exec,
  121. dao_bulla,
  122. self.dao_coin_blind,
  123. ]);
  124. let yes_votes_commit = pedersen_commitment_u64(self.yes_votes_value, self.yes_votes_blind);
  125. let yes_votes_commit_coords = yes_votes_commit.to_affine().coordinates().unwrap();
  126. let all_votes_commit = pedersen_commitment_u64(self.all_votes_value, self.all_votes_blind);
  127. let all_votes_commit_coords = all_votes_commit.to_affine().coordinates().unwrap();
  128. let input_value_commit = pedersen_commitment_u64(self.input_value, self.input_value_blind);
  129. let input_value_commit_coords = input_value_commit.to_affine().coordinates().unwrap();
  130. /*
  131. let zk_info = zk_bins.lookup(&"dao-exec".to_string()).unwrap();
  132. let zk_info = if let ZkContractInfo::Binary(info) = zk_info {
  133. info
  134. } else {
  135. panic!("Not binary info")
  136. };
  137. let zk_bin = zk_info.bincode.clone();
  138. */
  139. let prover_witnesses = vec![
  140. //
  141. // proposal params
  142. Witness::Base(Value::known(proposal_dest_x)),
  143. Witness::Base(Value::known(proposal_dest_y)),
  144. Witness::Base(Value::known(proposal_amount)),
  145. Witness::Base(Value::known(self.proposal.serial)),
  146. Witness::Base(Value::known(self.proposal.token_id.inner())),
  147. Witness::Base(Value::known(self.proposal.blind)),
  148. // DAO params
  149. Witness::Base(Value::known(dao_proposer_limit)),
  150. Witness::Base(Value::known(dao_quorum)),
  151. Witness::Base(Value::known(dao_approval_ratio_quot)),
  152. Witness::Base(Value::known(dao_approval_ratio_base)),
  153. Witness::Base(Value::known(self.dao.gov_token_id.inner())),
  154. Witness::Base(Value::known(dao_pub_x)),
  155. Witness::Base(Value::known(dao_pub_y)),
  156. Witness::Base(Value::known(self.dao.bulla_blind)),
  157. // votes
  158. Witness::Base(Value::known(pallas::Base::from(self.yes_votes_value))),
  159. Witness::Base(Value::known(pallas::Base::from(self.all_votes_value))),
  160. Witness::Scalar(Value::known(self.yes_votes_blind)),
  161. Witness::Scalar(Value::known(self.all_votes_blind)),
  162. // outputs + inputs
  163. Witness::Base(Value::known(self.user_serial)),
  164. Witness::Base(Value::known(self.user_coin_blind)),
  165. Witness::Base(Value::known(self.dao_serial)),
  166. Witness::Base(Value::known(self.dao_coin_blind)),
  167. Witness::Base(Value::known(input_value)),
  168. Witness::Scalar(Value::known(self.input_value_blind)),
  169. // misc
  170. Witness::Base(Value::known(self.hook_dao_exec)),
  171. Witness::Base(Value::known(user_spend_hook)),
  172. Witness::Base(Value::known(user_data)),
  173. ];
  174. let public_inputs = vec![
  175. proposal_bulla,
  176. coin_0,
  177. coin_1,
  178. *yes_votes_commit_coords.x(),
  179. *yes_votes_commit_coords.y(),
  180. *all_votes_commit_coords.x(),
  181. *all_votes_commit_coords.y(),
  182. *input_value_commit_coords.x(),
  183. *input_value_commit_coords.y(),
  184. self.hook_dao_exec,
  185. user_spend_hook,
  186. user_data,
  187. ];
  188. let circuit = ZkCircuit::new(prover_witnesses, exec_zkbin.clone());
  189. let input_proof = Proof::create(&exec_pk, &[circuit], &public_inputs, &mut OsRng)
  190. .expect("DAO::exec() proving error!)");
  191. proofs.push(input_proof);
  192. let params = DaoExecParams {
  193. proposal: proposal_bulla,
  194. coin_0,
  195. coin_1,
  196. yes_votes_commit,
  197. all_votes_commit,
  198. input_value_commit,
  199. };
  200. Ok((params, proofs))
  201. }
  202. }