mirror of
https://github.com/darkrenaissance/darkfi.git
synced 2026-04-28 03:00:18 -04:00
migrate builder over
This commit is contained in:
@@ -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"]}
|
||||
|
||||
@@ -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";
|
||||
|
||||
272
src/contract/dao/src/money_client.rs
Normal file
272
src/contract/dao/src/money_client.rs
Normal 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(¬e, &output.public)?;
|
||||
|
||||
let output = Output { revealed, enc_note: encrypted_note };
|
||||
outputs.push(output);
|
||||
*/
|
||||
}
|
||||
|
||||
Ok((MoneyTransferParams { clear_inputs, inputs, outputs }, proofs))
|
||||
}
|
||||
}
|
||||
@@ -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(())
|
||||
}
|
||||
|
||||
@@ -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),
|
||||
|
||||
Reference in New Issue
Block a user