mirror of
https://github.com/darkrenaissance/darkfi.git
synced 2026-04-28 03:00:18 -04:00
add clear_outputs field to txs
This commit is contained in:
@@ -51,6 +51,7 @@ fn main() {
|
||||
clear_inputs: vec![tx::TransactionBuilderClearInputInfo { value: 110, signature_secret: cashier_secret }],
|
||||
inputs: vec![],
|
||||
outputs: vec![tx::TransactionBuilderOutputInfo { value: 110, public }],
|
||||
clear_outputs: vec![]
|
||||
};
|
||||
|
||||
// We will 'compile' the tx, and then serialize it to this Vec<u8>
|
||||
@@ -159,6 +160,7 @@ fn main() {
|
||||
// We can add more outputs to this list.
|
||||
// The only constraint is that sum(value in) == sum(value out)
|
||||
outputs: vec![tx::TransactionBuilderOutputInfo { value: 110, public: public2 }],
|
||||
clear_outputs: vec![]
|
||||
};
|
||||
// Build the tx
|
||||
let mut tx_data = vec![];
|
||||
@@ -171,5 +173,7 @@ fn main() {
|
||||
let tx = tx::Transaction::decode(&tx_data[..]).unwrap();
|
||||
assert!(tx.verify(&mint_pvk, &spend_pvk));
|
||||
}
|
||||
|
||||
// Step 4 withdraw the funds
|
||||
}
|
||||
|
||||
|
||||
86
src/tx.rs
86
src/tx.rs
@@ -22,6 +22,7 @@ pub struct TransactionBuilder {
|
||||
pub clear_inputs: Vec<TransactionBuilderClearInputInfo>,
|
||||
pub inputs: Vec<TransactionBuilderInputInfo>,
|
||||
pub outputs: Vec<TransactionBuilderOutputInfo>,
|
||||
pub clear_outputs: Vec<TransactionBuilderClearOutputInfo>,
|
||||
}
|
||||
|
||||
impl TransactionBuilder {
|
||||
@@ -29,6 +30,7 @@ impl TransactionBuilder {
|
||||
clear_inputs: &Vec<PartialTransactionClearInput>,
|
||||
input_blinds: &Vec<jubjub::Fr>,
|
||||
output_blinds: &Vec<jubjub::Fr>,
|
||||
clear_outputs: &Vec<TransactionClearOutput>,
|
||||
) -> jubjub::Fr {
|
||||
let mut total = jubjub::Fr::zero();
|
||||
|
||||
@@ -44,6 +46,10 @@ impl TransactionBuilder {
|
||||
total -= output_blind;
|
||||
}
|
||||
|
||||
for output in clear_outputs {
|
||||
total -= output.valcom_blind;
|
||||
}
|
||||
|
||||
total
|
||||
}
|
||||
|
||||
@@ -98,11 +104,13 @@ impl TransactionBuilder {
|
||||
inputs.push(input);
|
||||
}
|
||||
|
||||
let last_output_index = self.outputs.len() + self.clear_outputs.len() - 1;
|
||||
|
||||
let mut outputs = vec![];
|
||||
let mut output_blinds = vec![];
|
||||
for (i, output) in self.outputs.iter().enumerate() {
|
||||
let valcom_blind = if i == self.outputs.len() - 1 {
|
||||
Self::compute_remainder_blind(&clear_inputs, &input_blinds, &output_blinds)
|
||||
let valcom_blind = if i == last_output_index {
|
||||
Self::compute_remainder_blind(&clear_inputs, &input_blinds, &output_blinds, &vec![])
|
||||
} else {
|
||||
jubjub::Fr::random(&mut OsRng)
|
||||
};
|
||||
@@ -139,10 +147,28 @@ impl TransactionBuilder {
|
||||
outputs.push(output);
|
||||
}
|
||||
|
||||
let mut clear_outputs = vec![];
|
||||
|
||||
for (i, output) in self.clear_outputs.into_iter().enumerate() {
|
||||
let valcom_blind = if self.outputs.len() + i == last_output_index {
|
||||
Self::compute_remainder_blind(&clear_inputs, &input_blinds, &output_blinds, &clear_outputs)
|
||||
} else {
|
||||
jubjub::Fr::random(&mut OsRng)
|
||||
};
|
||||
|
||||
let output = TransactionClearOutput {
|
||||
value: output.value,
|
||||
valcom_blind,
|
||||
instructions: output.instructions
|
||||
};
|
||||
clear_outputs.push(output);
|
||||
}
|
||||
|
||||
let partial_tx = PartialTransaction {
|
||||
clear_inputs,
|
||||
inputs,
|
||||
outputs,
|
||||
clear_outputs
|
||||
};
|
||||
|
||||
let mut unsigned_tx_data = vec![];
|
||||
@@ -173,10 +199,16 @@ impl TransactionBuilder {
|
||||
clear_inputs,
|
||||
inputs,
|
||||
outputs: partial_tx.outputs,
|
||||
clear_outputs: partial_tx.clear_outputs
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct TransactionBuilderClearOutputInfo {
|
||||
pub value: u64,
|
||||
pub instructions: String
|
||||
}
|
||||
|
||||
pub struct TransactionBuilderClearInputInfo {
|
||||
pub value: u64,
|
||||
pub signature_secret: jubjub::Fr,
|
||||
@@ -199,6 +231,7 @@ pub struct PartialTransaction {
|
||||
pub clear_inputs: Vec<PartialTransactionClearInput>,
|
||||
pub inputs: Vec<PartialTransactionInput>,
|
||||
pub outputs: Vec<TransactionOutput>,
|
||||
pub clear_outputs: Vec<TransactionClearOutput>,
|
||||
}
|
||||
|
||||
impl Encodable for PartialTransaction {
|
||||
@@ -206,7 +239,8 @@ impl Encodable for PartialTransaction {
|
||||
let mut len = 0;
|
||||
len += self.clear_inputs.encode(&mut s)?;
|
||||
len += self.inputs.encode(&mut s)?;
|
||||
len += self.outputs.encode(s)?;
|
||||
len += self.outputs.encode(&mut s)?;
|
||||
len += self.clear_outputs.encode(&mut s)?;
|
||||
Ok(len)
|
||||
}
|
||||
}
|
||||
@@ -216,7 +250,8 @@ impl Decodable for PartialTransaction {
|
||||
Ok(Self {
|
||||
clear_inputs: Decodable::decode(&mut d)?,
|
||||
inputs: Decodable::decode(&mut d)?,
|
||||
outputs: Decodable::decode(d)?,
|
||||
outputs: Decodable::decode(&mut d)?,
|
||||
clear_outputs: Decodable::decode(&mut d)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -225,6 +260,7 @@ pub struct Transaction {
|
||||
pub clear_inputs: Vec<TransactionClearInput>,
|
||||
pub inputs: Vec<TransactionInput>,
|
||||
pub outputs: Vec<TransactionOutput>,
|
||||
pub clear_outputs: Vec<TransactionClearOutput>
|
||||
}
|
||||
|
||||
impl Encodable for Transaction {
|
||||
@@ -232,7 +268,8 @@ impl Encodable for Transaction {
|
||||
let mut len = 0;
|
||||
len += self.clear_inputs.encode(&mut s)?;
|
||||
len += self.inputs.encode(&mut s)?;
|
||||
len += self.outputs.encode(s)?;
|
||||
len += self.outputs.encode(&mut s)?;
|
||||
len += self.clear_outputs.encode(&mut s)?;
|
||||
Ok(len)
|
||||
}
|
||||
}
|
||||
@@ -242,7 +279,8 @@ impl Decodable for Transaction {
|
||||
Ok(Self {
|
||||
clear_inputs: Decodable::decode(&mut d)?,
|
||||
inputs: Decodable::decode(&mut d)?,
|
||||
outputs: Decodable::decode(d)?,
|
||||
outputs: Decodable::decode(&mut d)?,
|
||||
clear_outputs: Decodable::decode(&mut d)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -252,7 +290,8 @@ impl Transaction {
|
||||
let mut len = 0;
|
||||
len += self.clear_inputs.encode_without_signature(&mut s)?;
|
||||
len += self.inputs.encode_without_signature(&mut s)?;
|
||||
len += self.outputs.encode(s)?;
|
||||
len += self.outputs.encode(&mut s)?;
|
||||
len += self.clear_outputs.encode(&mut s)?;
|
||||
Ok(len)
|
||||
}
|
||||
|
||||
@@ -274,6 +313,7 @@ impl Transaction {
|
||||
}
|
||||
for input in &self.inputs {
|
||||
if !verify_spend_proof(spend_pvk, &input.spend_proof, &input.revealed) {
|
||||
println!("spend fail");
|
||||
return false;
|
||||
}
|
||||
valcom_total += &input.revealed.value_commit;
|
||||
@@ -285,6 +325,9 @@ impl Transaction {
|
||||
}
|
||||
valcom_total -= &output.revealed.value_commit;
|
||||
}
|
||||
for output in &self.clear_outputs {
|
||||
valcom_total -= Self::compute_value_commit(output.value, &output.valcom_blind);
|
||||
}
|
||||
|
||||
// Verify signatures
|
||||
let mut unsigned_tx_data = vec![];
|
||||
@@ -507,3 +550,32 @@ impl Decodable for TransactionOutput {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub struct TransactionClearOutput {
|
||||
pub value: u64,
|
||||
pub valcom_blind: jubjub::Fr,
|
||||
pub instructions: String
|
||||
}
|
||||
|
||||
impl_vec!(TransactionClearOutput);
|
||||
|
||||
impl Encodable for TransactionClearOutput {
|
||||
fn encode<S: io::Write>(&self, mut s: S) -> Result<usize> {
|
||||
let mut len = 0;
|
||||
len += self.value.encode(&mut s)?;
|
||||
len += self.valcom_blind.encode(&mut s)?;
|
||||
len += self.instructions.encode(s)?;
|
||||
Ok(len)
|
||||
}
|
||||
}
|
||||
|
||||
impl Decodable for TransactionClearOutput {
|
||||
fn decode<D: io::Read>(mut d: D) -> Result<Self> {
|
||||
Ok(Self {
|
||||
value: Decodable::decode(&mut d)?,
|
||||
valcom_blind: Decodable::decode(&mut d)?,
|
||||
instructions: Decodable::decode(&mut d)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user