basic structure for dao-propose-main.zk working

This commit is contained in:
narodnik
2022-08-17 11:12:16 +02:00
parent 88cb9c720b
commit 78766ef671
3 changed files with 78 additions and 18 deletions

View File

@@ -1,20 +1,29 @@
constant "DaoProposeMain" {
EcFixedPointShort VALUE_COMMIT_VALUE,
EcFixedPoint VALUE_COMMIT_RANDOM,
}
contract "DaoProposeMain" {
# Proposers total number of gov tokens
Base total_funds,
Scalar total_funds_blind,
# Check the inputs and this proof are for the same token
Base gov_token_blind,
# proposal params
#Base proposal_x,
#Base proposal_y,
#Base proposal_amount,
#Base proposal_serial,
#Base proposal_token_id,
#Base proposal_blind,
Base proposal_x,
Base proposal_y,
Base proposal_amount,
Base proposal_serial,
Base proposal_token_id,
Base proposal_blind,
# DAO params
Base dao_proposer_limit,
Base dao_quorum,
Base dao_approval_ratio,
Base gdrk_token_id,
Base gov_token_id,
Base dao_public_x,
Base dao_public_y,
Base dao_bulla_blind,
@@ -24,11 +33,14 @@ contract "DaoProposeMain" {
}
circuit "DaoProposeMain" {
token_commit = poseidon_hash(gov_token_id, gov_token_blind);
constrain_instance(token_commit);
dao_bulla = poseidon_hash(
dao_proposer_limit,
dao_quorum,
dao_approval_ratio,
gdrk_token_id,
gov_token_id,
dao_public_x,
dao_public_y,
dao_bulla_blind,
@@ -38,5 +50,29 @@ circuit "DaoProposeMain" {
dao_root = calculate_merkle_root(dao_leaf_pos, dao_path, dao_bulla);
constrain_instance(dao_root);
# Proves this DAO is valid
# Rangeproof check for proposal amount
# TODO: waiting on this opcode in zkas
#
# greater_than_zero(amount)
#
# Use this temporary workaround. ec_mul_short() does an internal rangeproof
rangeproof = ec_mul_short(proposal_amount, VALUE_COMMIT_VALUE);
# TODO: check total_funds >= proposer_limit
#
# greater_than_or_equal(total_funds, proposer_limit)
#
# Pedersen commitment for coin's value
vcv = ec_mul_short(total_funds, VALUE_COMMIT_VALUE);
vcr = ec_mul(total_funds_blind, VALUE_COMMIT_RANDOM);
total_funds_commit = ec_add(vcv, vcr);
# Since total_funds_commit is a curve point, we fetch its coordinates
# and constrain them:
total_funds_commit_x = ec_get_x(total_funds_commit);
total_funds_commit_y = ec_get_y(total_funds_commit);
constrain_instance(total_funds_commit_x);
constrain_instance(total_funds_commit_y);
}

View File

@@ -22,11 +22,17 @@ type Result<T> = std::result::Result<T, Error>;
pub struct CallData {
pub dao_merkle_root: MerkleNode,
pub token_commit: pallas::Base,
// TODO: compute from sum of input commits
pub total_funds_commit: pallas::Point,
}
impl CallDataBase for CallData {
fn zk_public_values(&self) -> Vec<Vec<DrkCircuitField>> {
vec![vec![self.dao_merkle_root.0]]
let total_funds_coords = self.total_funds_commit.to_affine().coordinates().unwrap();
let total_funds_x = *total_funds_coords.x();
let total_funds_y = *total_funds_coords.y();
vec![vec![self.token_commit, self.dao_merkle_root.0, total_funds_x, total_funds_y]]
}
fn zk_proof_addrs(&self) -> Vec<String> {

View File

@@ -18,6 +18,7 @@ use darkfi::{
DrkCircuitField, DrkCoinBlind, DrkSerial, DrkSpendHook, DrkTokenId, DrkUserData,
DrkUserDataBlind, DrkValueBlind,
},
util::{pedersen_commitment_base, pedersen_commitment_u64},
Proof,
},
util::serial::{Encodable, SerialDecodable, SerialEncodable},
@@ -66,6 +67,17 @@ pub struct Builder {
impl Builder {
pub fn build(self, zk_bins: &ZkContractTable) -> FuncCall {
let total_funds = 110;
let total_funds_blind = pallas::Scalar::random(&mut OsRng);
let total_funds_commit = pedersen_commitment_u64(total_funds, total_funds_blind);
let total_funds_coords = total_funds_commit.to_affine().coordinates().unwrap();
let total_funds_x = *total_funds_coords.x();
let total_funds_y = *total_funds_coords.y();
let total_funds = pallas::Base::from(total_funds);
let gov_token_blind = pallas::Base::random(&mut OsRng);
let token_commit = poseidon_hash::<2>([self.dao.gov_token_id, gov_token_blind]);
let proposal_dest_coords = self.proposal.dest.0.to_affine().coordinates().unwrap();
let proposal_dest_x = *proposal_dest_coords.x();
let proposal_dest_y = *proposal_dest_coords.y();
@@ -102,14 +114,18 @@ impl Builder {
};
let zk_bin = zk_info.bincode.clone();
let prover_witnesses = vec![
// Proposers total number of gov tokens
Witness::Base(Value::known(total_funds)),
Witness::Scalar(Value::known(total_funds_blind)),
// Used for blinding exported gov token ID
Witness::Base(Value::known(gov_token_blind)),
// 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)),
//Witness::Base(Value::known(self.proposal.blind)),
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)),
Witness::Base(Value::known(self.proposal.blind)),
// DAO params
Witness::Base(Value::known(dao_proposer_limit)),
Witness::Base(Value::known(dao_quorum)),
@@ -121,14 +137,16 @@ impl Builder {
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![self.dao_merkle_root.0];
let public_inputs =
vec![token_commit, self.dao_merkle_root.0, total_funds_x, total_funds_y];
let circuit = ZkCircuit::new(prover_witnesses, zk_bin);
let proving_key = &zk_info.proving_key;
let main_proof = Proof::create(proving_key, &[circuit], &public_inputs, &mut OsRng)
.expect("DAO::propose() proving error!");
let call_data = CallData { dao_merkle_root: self.dao_merkle_root };
let call_data =
CallData { dao_merkle_root: self.dao_merkle_root, token_commit, total_funds_commit };
FuncCall {
contract_id: "DAO".to_string(),