| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199 |
- /* This file is part of DarkFi (https://dark.fi)
- *
- * Copyright (C) 2020-2022 Dyne.org foundation
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <https://www.gnu.org/licenses/>.
- */
- use darkfi_sdk::crypto::{
- pallas, pasta_prelude::*, pedersen_commitment_u64, poseidon_hash, SecretKey,
- };
- use halo2_proofs::circuit::Value;
- use log::debug;
- use rand::rngs::OsRng;
- use darkfi::{
- zk::{Proof, ProvingKey, Witness, ZkCircuit},
- zkas::ZkBinary,
- Result,
- };
- use super::{DaoInfo, ProposalInfo};
- use crate::dao_model::DaoExecParams;
- pub struct ExecCall {
- pub proposal: ProposalInfo,
- pub dao: DaoInfo,
- pub yes_votes_value: u64,
- pub all_votes_value: u64,
- pub yes_votes_blind: pallas::Scalar,
- pub all_votes_blind: pallas::Scalar,
- pub user_serial: pallas::Base,
- pub user_coin_blind: pallas::Base,
- pub dao_serial: pallas::Base,
- pub dao_coin_blind: pallas::Base,
- pub input_value: u64,
- pub input_value_blind: pallas::Scalar,
- pub hook_dao_exec: pallas::Base,
- pub signature_secret: SecretKey,
- }
- impl ExecCall {
- pub fn make(
- self,
- exec_zkbin: &ZkBinary,
- exec_pk: &ProvingKey,
- ) -> Result<(DaoExecParams, Vec<Proof>)> {
- debug!(target: "dao", "build()");
- let mut proofs = vec![];
- let (proposal_dest_x, proposal_dest_y) = self.proposal.dest.xy();
- let proposal_amount = pallas::Base::from(self.proposal.amount);
- 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 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>([
- 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 = poseidon_hash::<8>([
- proposal_dest_x,
- proposal_dest_y,
- proposal_amount,
- self.proposal.serial,
- self.proposal.token_id.inner(),
- dao_bulla,
- self.proposal.blind,
- // @tmp-workaround
- self.proposal.blind,
- ]);
- let coin_0 = poseidon_hash::<8>([
- proposal_dest_x,
- proposal_dest_y,
- proposal_amount,
- self.proposal.token_id.inner(),
- self.proposal.serial,
- user_spend_hook,
- user_data,
- self.proposal.blind,
- ]);
- let coin_1 = poseidon_hash::<8>([
- dao_pub_x,
- dao_pub_y,
- change,
- self.proposal.token_id.inner(),
- self.dao_serial,
- self.hook_dao_exec,
- dao_bulla,
- self.dao_coin_blind,
- ]);
- let yes_votes_commit = pedersen_commitment_u64(self.yes_votes_value, self.yes_votes_blind);
- let yes_votes_commit_coords = yes_votes_commit.to_affine().coordinates().unwrap();
- let all_votes_commit = pedersen_commitment_u64(self.all_votes_value, self.all_votes_blind);
- let all_votes_commit_coords = all_votes_commit.to_affine().coordinates().unwrap();
- let input_value_commit = pedersen_commitment_u64(self.input_value, self.input_value_blind);
- let input_value_commit_coords = input_value_commit.to_affine().coordinates().unwrap();
- let prover_witnesses = vec![
- // proposal params
- Witness::Base(Value::known(proposal_dest_x)),
- Witness::Base(Value::known(proposal_dest_y)),
- Witness::Base(Value::known(proposal_amount)),
- Witness::Base(Value::known(self.proposal.serial)),
- Witness::Base(Value::known(self.proposal.token_id.inner())),
- Witness::Base(Value::known(self.proposal.blind)),
- // DAO params
- 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)),
- // votes
- Witness::Base(Value::known(pallas::Base::from(self.yes_votes_value))),
- Witness::Base(Value::known(pallas::Base::from(self.all_votes_value))),
- Witness::Scalar(Value::known(self.yes_votes_blind)),
- Witness::Scalar(Value::known(self.all_votes_blind)),
- // outputs + inputs
- Witness::Base(Value::known(self.user_serial)),
- Witness::Base(Value::known(self.user_coin_blind)),
- Witness::Base(Value::known(self.dao_serial)),
- Witness::Base(Value::known(self.dao_coin_blind)),
- Witness::Base(Value::known(input_value)),
- 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)),
- ];
- debug!("proposal_bulla: {:?}", proposal_bulla);
- let public_inputs = vec![
- proposal_bulla,
- coin_0,
- coin_1,
- *yes_votes_commit_coords.x(),
- *yes_votes_commit_coords.y(),
- *all_votes_commit_coords.x(),
- *all_votes_commit_coords.y(),
- *input_value_commit_coords.x(),
- *input_value_commit_coords.y(),
- self.hook_dao_exec,
- user_spend_hook,
- user_data,
- ];
- let circuit = ZkCircuit::new(prover_witnesses, exec_zkbin.clone());
- let input_proof = Proof::create(&exec_pk, &[circuit], &public_inputs, &mut OsRng)
- .expect("DAO::exec() proving error!)");
- proofs.push(input_proof);
- let params = DaoExecParams {
- proposal: proposal_bulla,
- coin_0,
- coin_1,
- yes_votes_commit,
- all_votes_commit,
- input_value_commit,
- };
- Ok((params, proofs))
- }
- }
|