migrate builder over

This commit is contained in:
x
2022-12-25 14:25:06 +01:00
parent 25b4bc2a42
commit 0dfe9243eb
6 changed files with 312 additions and 13 deletions

View File

@@ -25,7 +25,7 @@ rand = { version = "0.8.5", optional = true }
[dev-dependencies]
async-std = {version = "1.12.0", features = ["attributes"]}
darkfi = {path = "../../../", features = ["tx", "blockchain"]}
darkfi-money-contract = { path = "../money", features = ["client"] }
darkfi-money-contract = { path = "../money", features = ["client", "no-entrypoint"] }
simplelog = "0.12.0"
sled = "0.34.7"
sqlx = {version = "0.6.2", features = ["runtime-async-std-native-tls", "sqlite"]}

View File

@@ -27,8 +27,12 @@ pub mod state;
pub mod note;
#[cfg(feature = "client")]
/// Transaction building API for clients interacting with this contract
pub mod client;
/// Transaction building API for clients interacting with DAO contract
pub mod dao_client;
#[cfg(feature = "client")]
/// Transaction building API for clients interacting with money contract
pub mod money_client;
// These are the zkas circuit namespaces
pub const DAO_CONTRACT_ZKAS_DAO_MINT_NS: &str = "DaoMint";

View File

@@ -0,0 +1,272 @@
/* 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 chacha20poly1305::{AeadInPlace, ChaCha20Poly1305, KeyInit};
use darkfi::{
consensus::leadcoin::LeadCoin,
zk::{
proof::{Proof, ProvingKey},
vm::ZkCircuit,
vm_stack::Witness,
},
zkas::ZkBinary,
ClientFailed, Error, Result,
};
use darkfi_sdk::{
crypto::{
constants::MERKLE_DEPTH,
diffie_hellman::{kdf_sapling, sapling_ka_agree},
pedersen::{pedersen_commitment_base, pedersen_commitment_u64, ValueBlind, ValueCommit},
poseidon_hash, Keypair, MerkleNode, Nullifier, PublicKey, SecretKey, TokenId,
},
incrementalmerkletree,
incrementalmerkletree::{bridgetree::BridgeTree, Hashable, Tree},
pasta::{
arithmetic::CurveAffine,
group::{
ff::{Field, PrimeField},
Curve,
},
pallas,
},
};
use darkfi_serial::{serialize, Decodable, Encodable, SerialDecodable, SerialEncodable};
use halo2_proofs::circuit::Value;
use log::{debug, error, info};
use rand::rngs::OsRng;
use darkfi_money_contract::{
client::{create_transfer_burn_proof, create_transfer_mint_proof, Note},
state::{ClearInput, Input, MoneyTransferParams, Output},
};
/*
use darkfi::{
crypto::{
burn_proof::create_burn_proof,
mint_proof::create_mint_proof,
types::{
DrkCoinBlind, DrkSerial, DrkSpendHook, DrkUserData, DrkUserDataBlind, DrkValueBlind,
},
},
Result,
};
use crate::{
contract::money::{
transfer::validate::{CallData, ClearInput, Input, Output},
CONTRACT_ID,
},
note,
util::{FuncCall, ZkContractInfo, ZkContractTable},
};
*/
/*
#[derive(Clone, SerialEncodable, SerialDecodable)]
pub struct Note {
pub serial: DrkSerial,
pub value: u64,
pub token_id: TokenId,
pub spend_hook: DrkSpendHook,
pub user_data: DrkUserData,
pub coin_blind: DrkCoinBlind,
pub value_blind: DrkValueBlind,
pub token_blind: DrkValueBlind,
}
*/
pub struct Builder {
pub clear_inputs: Vec<BuilderClearInputInfo>,
pub inputs: Vec<BuilderInputInfo>,
pub outputs: Vec<BuilderOutputInfo>,
}
pub struct BuilderClearInputInfo {
pub value: u64,
pub token_id: TokenId,
pub signature_secret: SecretKey,
}
pub struct BuilderInputInfo {
pub leaf_position: incrementalmerkletree::Position,
pub merkle_path: Vec<MerkleNode>,
pub secret: SecretKey,
pub note: Note,
pub user_data_blind: pallas::Base,
pub value_blind: ValueBlind,
pub signature_secret: SecretKey,
}
pub struct BuilderOutputInfo {
pub value: u64,
pub token_id: TokenId,
pub public: PublicKey,
pub serial: pallas::Base,
pub coin_blind: pallas::Base,
pub spend_hook: pallas::Base,
pub user_data: pallas::Base,
}
impl Builder {
fn compute_remainder_blind(
clear_inputs: &[ClearInput],
input_blinds: &[ValueBlind],
output_blinds: &[ValueBlind],
) -> ValueBlind {
let mut total = ValueBlind::zero();
for input in clear_inputs {
total += input.value_blind;
}
for input_blind in input_blinds {
total += input_blind;
}
for output_blind in output_blinds {
total -= output_blind;
}
total
}
pub fn build(
self,
mint_zkbin: &ZkBinary,
mint_pk: &ProvingKey,
burn_zkbin: &ZkBinary,
burn_pk: &ProvingKey,
) -> Result<(MoneyTransferParams, Vec<Proof>)> {
assert!(self.clear_inputs.len() + self.inputs.len() > 0);
let mut clear_inputs = vec![];
let token_blind = ValueBlind::random(&mut OsRng);
for input in &self.clear_inputs {
let signature_public = PublicKey::from_secret(input.signature_secret);
let value_blind = ValueBlind::random(&mut OsRng);
let clear_input = ClearInput {
value: input.value,
token_id: input.token_id,
value_blind,
token_blind,
signature_public,
};
clear_inputs.push(clear_input);
}
let mut proofs = vec![];
let mut inputs = vec![];
let mut input_blinds = vec![];
for input in self.inputs {
let value_blind = input.value_blind;
input_blinds.push(value_blind);
// Note from the previous output
let note = input.note.clone();
let (proof, revealed) = create_transfer_burn_proof(
burn_zkbin,
burn_pk,
note.value,
note.token_id,
value_blind,
token_blind,
note.serial,
note.spend_hook,
note.user_data,
input.user_data_blind,
note.coin_blind,
input.secret,
input.leaf_position,
input.merkle_path.clone(),
input.signature_secret,
)?;
proofs.push(proof);
let input = Input {
value_commit: revealed.value_commit,
token_commit: revealed.token_commit,
nullifier: revealed.nullifier,
merkle_root: revealed.merkle_root,
spend_hook: revealed.spend_hook,
user_data_enc: revealed.user_data_enc,
signature_public: revealed.signature_public,
};
inputs.push(input);
}
let mut outputs = vec![];
let mut output_blinds = vec![];
// This value_blind calc assumes there will always be at least a single output
assert!(!self.outputs.is_empty());
for (i, output) in self.outputs.iter().enumerate() {
let value_blind = if i == self.outputs.len() - 1 {
Self::compute_remainder_blind(&clear_inputs, &input_blinds, &output_blinds)
} else {
ValueBlind::random(&mut OsRng)
};
output_blinds.push(value_blind);
let serial = output.serial;
let coin_blind = output.coin_blind;
let (proof, revealed) = create_transfer_mint_proof(
mint_zkbin,
mint_pk,
output.value,
output.token_id,
value_blind,
token_blind,
serial,
output.spend_hook,
output.user_data,
coin_blind,
output.public,
)?;
proofs.push(proof);
let note = Note {
serial,
value: output.value,
token_id: output.token_id,
spend_hook: output.spend_hook,
user_data: output.user_data,
coin_blind,
value_blind,
token_blind,
memo: Vec::new(),
};
//let encrypted_note = note.encrypt(&output.public)?;
/*
let encrypted_note = note::encrypt(&note, &output.public)?;
let output = Output { revealed, enc_note: encrypted_note };
outputs.push(output);
*/
}
Ok((MoneyTransferParams { clear_inputs, inputs, outputs }, proofs))
}
}

View File

@@ -28,7 +28,7 @@ use log::{debug, info};
use rand::rngs::OsRng;
use darkfi_dao_contract::{
client::{build_dao_mint_tx, MerkleTree},
dao_client::{build_dao_mint_tx, MerkleTree},
DaoFunction,
};
@@ -60,11 +60,11 @@ async fn integration_test() -> Result<()> {
let mut th = DaoTestHarness::new().await?;
// Money parameters
//let xdrk_supply = 1_000_000;
//let xrdk_token_id = TokenId::from(pallas::Base::random(&mut OsRng));
let xdrk_supply = 1_000_000;
let xrdk_token_id = TokenId::from(pallas::Base::random(&mut OsRng));
// Governance token parameters
//let gdrk_supply = 1_000_000;
let gdrk_supply = 1_000_000;
let gdrk_token_id = TokenId::from(pallas::Base::random(&mut OsRng));
// DAO parameters
@@ -131,7 +131,11 @@ async fn integration_test() -> Result<()> {
// =======================================================
debug!(target: "demo", "Stage 2. Minting treasury token");
// We use this to receive coins
//let mut cache = WalletCache::new();
let mut th = MoneyTestHarness::new().await?;
//let (params, proofs) = builder.build(&zk_bins)?;
Ok(())
}

View File

@@ -47,12 +47,15 @@ use darkfi_sdk::{
incrementalmerkletree::{bridgetree::BridgeTree, Hashable, Tree},
pasta::{
arithmetic::CurveAffine,
group::{ff::PrimeField, Curve},
group::{
ff::{Field, PrimeField},
Curve,
},
pallas,
},
};
use darkfi_serial::{serialize, Decodable, Encodable, SerialDecodable, SerialEncodable};
use halo2_proofs::{arithmetic::Field, circuit::Value};
use halo2_proofs::circuit::Value;
use log::{debug, error, info};
use rand::rngs::OsRng;
@@ -143,6 +146,11 @@ pub struct Note {
pub value: u64,
/// Token ID of the coin
pub token_id: TokenId,
/// Spend hook used for protocol owned liquidity.
/// Specifies which contract owns this coin.
pub spend_hook: pallas::Base,
/// User data used by protocol when spend hook is enabled.
pub user_data: pallas::Base,
/// Blinding factor for the coin bulla
pub coin_blind: pallas::Base,
/// Blinding factor for the value pedersen commitment
@@ -207,6 +215,9 @@ impl EncryptedNote {
}
}
// TODO: we can put all these in an internal module like:
// money_transfer::builder::ClearInputInfo
struct TransactionBuilderClearInputInfo {
pub value: u64,
pub token_id: TokenId,
@@ -226,7 +237,7 @@ struct TransactionBuilderOutputInfo {
pub public_key: PublicKey,
}
struct TransferBurnRevealed {
pub struct TransferBurnRevealed {
pub value_commit: ValueCommit,
pub token_commit: ValueCommit,
pub nullifier: Nullifier,
@@ -321,7 +332,7 @@ impl TransferBurnRevealed {
}
}
struct TransferMintRevealed {
pub struct TransferMintRevealed {
pub coin: Coin,
pub value_commit: ValueCommit,
pub token_commit: ValueCommit,
@@ -376,7 +387,7 @@ impl TransferMintRevealed {
}
#[allow(clippy::too_many_arguments)]
fn create_transfer_mint_proof(
pub fn create_transfer_mint_proof(
zkbin: &ZkBinary,
pk: &ProvingKey,
value: u64,
@@ -424,7 +435,7 @@ fn create_transfer_mint_proof(
}
#[allow(clippy::too_many_arguments)]
fn create_transfer_burn_proof(
pub fn create_transfer_burn_proof(
zkbin: &ZkBinary,
pk: &ProvingKey,
value: u64,
@@ -799,6 +810,8 @@ pub fn build_half_swap_tx(
serial,
value: output.value,
token_id: output.token_id,
spend_hook: pallas::Base::zero(),
user_data: pallas::Base::zero(),
coin_blind,
value_blind: value_recv_blind,
token_blind: token_recv_blind,
@@ -1025,6 +1038,8 @@ pub fn build_transfer_tx(
serial,
value: output.value,
token_id: output.token_id,
spend_hook: pallas::Base::zero(),
user_data: pallas::Base::zero(),
coin_blind,
value_blind,
token_blind,
@@ -1236,6 +1251,8 @@ pub fn build_unstake_tx(
serial,
value: coin.value,
token_id: token_id_recv,
spend_hook: pallas::Base::zero(),
user_data: pallas::Base::zero(),
coin_blind,
value_blind,
token_blind: token_recv_blind,
@@ -1290,6 +1307,8 @@ mod tests {
serial: pallas::Base::random(&mut OsRng),
value: 100,
token_id: TokenId::from(pallas::Base::random(&mut OsRng)),
spend_hook: pallas::Base::zero(),
user_data: pallas::Base::zero(),
coin_blind: pallas::Base::random(&mut OsRng),
value_blind: pallas::Scalar::random(&mut OsRng),
token_blind: pallas::Scalar::random(&mut OsRng),