|
@@ -1,3 +1,6 @@
|
|
|
|
|
+pub mod builder;
|
|
|
|
|
+pub mod partial;
|
|
|
|
|
+
|
|
|
use bellman::groth16;
|
|
use bellman::groth16;
|
|
|
use bls12_381::Bls12;
|
|
use bls12_381::Bls12;
|
|
|
use ff::Field;
|
|
use ff::Field;
|
|
@@ -18,212 +21,9 @@ use crate::error::{Error, Result};
|
|
|
use crate::impl_vec;
|
|
use crate::impl_vec;
|
|
|
use crate::serial::{Decodable, Encodable, VarInt};
|
|
use crate::serial::{Decodable, Encodable, VarInt};
|
|
|
use crate::state;
|
|
use crate::state;
|
|
|
|
|
+use self::partial::{PartialTransactionClearInput, PartialTransactionInput};
|
|
|
|
|
|
|
|
-pub struct TransactionBuilder {
|
|
|
|
|
- pub clear_inputs: Vec<TransactionBuilderClearInputInfo>,
|
|
|
|
|
- pub inputs: Vec<TransactionBuilderInputInfo>,
|
|
|
|
|
- pub outputs: Vec<TransactionBuilderOutputInfo>,
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-impl TransactionBuilder {
|
|
|
|
|
- fn compute_remainder_blind(
|
|
|
|
|
- clear_inputs: &Vec<PartialTransactionClearInput>,
|
|
|
|
|
- input_blinds: &Vec<jubjub::Fr>,
|
|
|
|
|
- output_blinds: &Vec<jubjub::Fr>,
|
|
|
|
|
- ) -> jubjub::Fr {
|
|
|
|
|
- let mut total = jubjub::Fr::zero();
|
|
|
|
|
-
|
|
|
|
|
- for input in clear_inputs {
|
|
|
|
|
- total += input.valcom_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_params: &groth16::Parameters<Bls12>,
|
|
|
|
|
- spend_params: &groth16::Parameters<Bls12>,
|
|
|
|
|
- ) -> Transaction {
|
|
|
|
|
- let mut clear_inputs = vec![];
|
|
|
|
|
- for input in &self.clear_inputs {
|
|
|
|
|
- let signature_public =
|
|
|
|
|
- zcash_primitives::constants::SPENDING_KEY_GENERATOR * input.signature_secret;
|
|
|
|
|
-
|
|
|
|
|
- let valcom_blind: jubjub::Fr = jubjub::Fr::random(&mut OsRng);
|
|
|
|
|
- let clear_input = PartialTransactionClearInput {
|
|
|
|
|
- value: input.value,
|
|
|
|
|
- valcom_blind,
|
|
|
|
|
- signature_public,
|
|
|
|
|
- };
|
|
|
|
|
- clear_inputs.push(clear_input);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- let mut inputs = vec![];
|
|
|
|
|
- let mut input_blinds = vec![];
|
|
|
|
|
- let mut signature_secrets = vec![];
|
|
|
|
|
- for input in &self.inputs {
|
|
|
|
|
- input_blinds.push(input.note.valcom_blind.clone());
|
|
|
|
|
-
|
|
|
|
|
- let signature_secret: jubjub::Fr = jubjub::Fr::random(&mut OsRng);
|
|
|
|
|
-
|
|
|
|
|
- // make proof
|
|
|
|
|
-
|
|
|
|
|
- let (proof, revealed) = create_spend_proof(
|
|
|
|
|
- &spend_params,
|
|
|
|
|
- input.note.value,
|
|
|
|
|
- input.note.valcom_blind,
|
|
|
|
|
- input.note.serial,
|
|
|
|
|
- input.note.coin_blind,
|
|
|
|
|
- input.secret,
|
|
|
|
|
- input.merkle_path.clone(),
|
|
|
|
|
- signature_secret.clone(),
|
|
|
|
|
- );
|
|
|
|
|
-
|
|
|
|
|
- // First we make the tx then sign after
|
|
|
|
|
- let signature_secret = schnorr::SecretKey(signature_secret);
|
|
|
|
|
- signature_secrets.push(signature_secret);
|
|
|
|
|
-
|
|
|
|
|
- let input = PartialTransactionInput {
|
|
|
|
|
- spend_proof: proof,
|
|
|
|
|
- revealed,
|
|
|
|
|
- };
|
|
|
|
|
- inputs.push(input);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- 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)
|
|
|
|
|
- } else {
|
|
|
|
|
- jubjub::Fr::random(&mut OsRng)
|
|
|
|
|
- };
|
|
|
|
|
- output_blinds.push(valcom_blind);
|
|
|
|
|
-
|
|
|
|
|
- let serial: jubjub::Fr = jubjub::Fr::random(&mut OsRng);
|
|
|
|
|
- let coin_blind: jubjub::Fr = jubjub::Fr::random(&mut OsRng);
|
|
|
|
|
-
|
|
|
|
|
- let (mint_proof, revealed) = create_mint_proof(
|
|
|
|
|
- mint_params,
|
|
|
|
|
- output.value,
|
|
|
|
|
- valcom_blind.clone(),
|
|
|
|
|
- serial.clone(),
|
|
|
|
|
- coin_blind.clone(),
|
|
|
|
|
- output.public.clone(),
|
|
|
|
|
- );
|
|
|
|
|
-
|
|
|
|
|
- // Encrypted note
|
|
|
|
|
-
|
|
|
|
|
- let note = Note {
|
|
|
|
|
- serial,
|
|
|
|
|
- value: output.value,
|
|
|
|
|
- coin_blind,
|
|
|
|
|
- valcom_blind,
|
|
|
|
|
- };
|
|
|
|
|
-
|
|
|
|
|
- let encrypted_note = note.encrypt(&output.public).unwrap();
|
|
|
|
|
-
|
|
|
|
|
- let output = TransactionOutput {
|
|
|
|
|
- mint_proof,
|
|
|
|
|
- revealed,
|
|
|
|
|
- enc_note: encrypted_note,
|
|
|
|
|
- };
|
|
|
|
|
- outputs.push(output);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- let partial_tx = PartialTransaction {
|
|
|
|
|
- clear_inputs,
|
|
|
|
|
- inputs,
|
|
|
|
|
- outputs,
|
|
|
|
|
- };
|
|
|
|
|
-
|
|
|
|
|
- let mut unsigned_tx_data = vec![];
|
|
|
|
|
- partial_tx
|
|
|
|
|
- .encode(&mut unsigned_tx_data)
|
|
|
|
|
- .expect("TODO handle this");
|
|
|
|
|
-
|
|
|
|
|
- let mut clear_inputs = vec![];
|
|
|
|
|
- for (input, info) in partial_tx.clear_inputs.into_iter().zip(self.clear_inputs) {
|
|
|
|
|
- let secret = schnorr::SecretKey(info.signature_secret.clone());
|
|
|
|
|
- let signature = secret.sign(&unsigned_tx_data[..]);
|
|
|
|
|
- let input = TransactionClearInput::from_partial(input, signature);
|
|
|
|
|
- clear_inputs.push(input);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- let mut inputs = vec![];
|
|
|
|
|
- for (input, signature_secret) in partial_tx
|
|
|
|
|
- .inputs
|
|
|
|
|
- .into_iter()
|
|
|
|
|
- .zip(signature_secrets.into_iter())
|
|
|
|
|
- {
|
|
|
|
|
- let signature = signature_secret.sign(&unsigned_tx_data[..]);
|
|
|
|
|
- let input = TransactionInput::from_partial(input, signature);
|
|
|
|
|
- inputs.push(input);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- Transaction {
|
|
|
|
|
- clear_inputs,
|
|
|
|
|
- inputs,
|
|
|
|
|
- outputs: partial_tx.outputs,
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-pub struct TransactionBuilderClearOutputInfo {
|
|
|
|
|
- pub value: u64,
|
|
|
|
|
- pub instructions: String,
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-pub struct TransactionBuilderClearInputInfo {
|
|
|
|
|
- pub value: u64,
|
|
|
|
|
- pub signature_secret: jubjub::Fr,
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-pub struct TransactionBuilderInputInfo {
|
|
|
|
|
- pub merkle_path: Vec<(bls12_381::Scalar, bool)>,
|
|
|
|
|
- pub secret: jubjub::Fr,
|
|
|
|
|
- pub note: Note,
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-pub struct TransactionBuilderOutputInfo {
|
|
|
|
|
- pub value: u64,
|
|
|
|
|
- pub public: jubjub::SubgroupPoint,
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-pub struct PartialTransaction {
|
|
|
|
|
- pub clear_inputs: Vec<PartialTransactionClearInput>,
|
|
|
|
|
- pub inputs: Vec<PartialTransactionInput>,
|
|
|
|
|
- pub outputs: Vec<TransactionOutput>,
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-impl Encodable for PartialTransaction {
|
|
|
|
|
- fn encode<S: io::Write>(&self, mut s: S) -> Result<usize> {
|
|
|
|
|
- let mut len = 0;
|
|
|
|
|
- len += self.clear_inputs.encode(&mut s)?;
|
|
|
|
|
- len += self.inputs.encode(&mut s)?;
|
|
|
|
|
- len += self.outputs.encode(s)?;
|
|
|
|
|
- Ok(len)
|
|
|
|
|
- }
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-impl Decodable for PartialTransaction {
|
|
|
|
|
- fn decode<D: io::Read>(mut d: D) -> Result<Self> {
|
|
|
|
|
- Ok(Self {
|
|
|
|
|
- clear_inputs: Decodable::decode(&mut d)?,
|
|
|
|
|
- inputs: Decodable::decode(&mut d)?,
|
|
|
|
|
- outputs: Decodable::decode(d)?,
|
|
|
|
|
- })
|
|
|
|
|
- }
|
|
|
|
|
-}
|
|
|
|
|
|
|
+pub use self::builder::{TransactionBuilder, TransactionBuilderClearInputInfo, TransactionBuilderInputInfo, TransactionBuilderOutputInfo};
|
|
|
|
|
|
|
|
pub struct Transaction {
|
|
pub struct Transaction {
|
|
|
pub clear_inputs: Vec<TransactionClearInput>,
|
|
pub clear_inputs: Vec<TransactionClearInput>,
|
|
@@ -231,24 +31,23 @@ pub struct Transaction {
|
|
|
pub outputs: Vec<TransactionOutput>,
|
|
pub outputs: Vec<TransactionOutput>,
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-impl Encodable for Transaction {
|
|
|
|
|
- fn encode<S: io::Write>(&self, mut s: S) -> Result<usize> {
|
|
|
|
|
- let mut len = 0;
|
|
|
|
|
- len += self.clear_inputs.encode(&mut s)?;
|
|
|
|
|
- len += self.inputs.encode(&mut s)?;
|
|
|
|
|
- len += self.outputs.encode(s)?;
|
|
|
|
|
- Ok(len)
|
|
|
|
|
- }
|
|
|
|
|
|
|
+pub struct TransactionClearInput {
|
|
|
|
|
+ pub value: u64,
|
|
|
|
|
+ pub valcom_blind: jubjub::Fr,
|
|
|
|
|
+ pub signature_public: jubjub::SubgroupPoint,
|
|
|
|
|
+ pub signature: schnorr::Signature,
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-impl Decodable for Transaction {
|
|
|
|
|
- fn decode<D: io::Read>(mut d: D) -> Result<Self> {
|
|
|
|
|
- Ok(Self {
|
|
|
|
|
- clear_inputs: Decodable::decode(&mut d)?,
|
|
|
|
|
- inputs: Decodable::decode(&mut d)?,
|
|
|
|
|
- outputs: Decodable::decode(d)?,
|
|
|
|
|
- })
|
|
|
|
|
- }
|
|
|
|
|
|
|
+pub struct TransactionInput {
|
|
|
|
|
+ pub spend_proof: groth16::Proof<Bls12>,
|
|
|
|
|
+ pub revealed: SpendRevealedValues,
|
|
|
|
|
+ pub signature: schnorr::Signature,
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+pub struct TransactionOutput {
|
|
|
|
|
+ pub mint_proof: groth16::Proof<Bls12>,
|
|
|
|
|
+ pub revealed: MintRevealedValues,
|
|
|
|
|
+ pub enc_note: EncryptedNote,
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
impl Transaction {
|
|
impl Transaction {
|
|
@@ -314,13 +113,6 @@ impl Transaction {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-pub struct TransactionClearInput {
|
|
|
|
|
- pub value: u64,
|
|
|
|
|
- pub valcom_blind: jubjub::Fr,
|
|
|
|
|
- pub signature_public: jubjub::SubgroupPoint,
|
|
|
|
|
- pub signature: schnorr::Signature,
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
impl TransactionClearInput {
|
|
impl TransactionClearInput {
|
|
|
fn from_partial(partial: PartialTransactionClearInput, signature: schnorr::Signature) -> Self {
|
|
fn from_partial(partial: PartialTransactionClearInput, signature: schnorr::Signature) -> Self {
|
|
|
Self {
|
|
Self {
|
|
@@ -340,130 +132,65 @@ impl TransactionClearInput {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-macro_rules! impl_vec_without_signature {
|
|
|
|
|
- ($type: ty) => {
|
|
|
|
|
- impl EncodableWithoutSignature for Vec<$type> {
|
|
|
|
|
- #[inline]
|
|
|
|
|
- fn encode_without_signature<S: io::Write>(&self, mut s: S) -> Result<usize> {
|
|
|
|
|
- let mut len = 0;
|
|
|
|
|
- len += VarInt(self.len() as u64).encode(&mut s)?;
|
|
|
|
|
- for c in self.iter() {
|
|
|
|
|
- len += c.encode_without_signature(&mut s)?;
|
|
|
|
|
- }
|
|
|
|
|
- Ok(len)
|
|
|
|
|
- }
|
|
|
|
|
|
|
+impl TransactionInput {
|
|
|
|
|
+ fn from_partial(partial: PartialTransactionInput, signature: schnorr::Signature) -> Self {
|
|
|
|
|
+ Self {
|
|
|
|
|
+ spend_proof: partial.spend_proof,
|
|
|
|
|
+ revealed: partial.revealed,
|
|
|
|
|
+ signature,
|
|
|
}
|
|
}
|
|
|
- };
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-impl_vec_without_signature!(TransactionClearInput);
|
|
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
-impl_vec!(TransactionClearInput);
|
|
|
|
|
|
|
+ fn encode_without_signature<S: io::Write>(&self, mut s: S) -> Result<usize> {
|
|
|
|
|
+ let mut len = 0;
|
|
|
|
|
+ len += self.spend_proof.encode(&mut s)?;
|
|
|
|
|
+ len += self.revealed.encode(&mut s)?;
|
|
|
|
|
+ Ok(len)
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
|
|
|
-impl Encodable for TransactionClearInput {
|
|
|
|
|
|
|
+impl Encodable for Transaction {
|
|
|
fn encode<S: io::Write>(&self, mut s: S) -> Result<usize> {
|
|
fn encode<S: io::Write>(&self, mut s: S) -> Result<usize> {
|
|
|
let mut len = 0;
|
|
let mut len = 0;
|
|
|
- len += self.value.encode(&mut s)?;
|
|
|
|
|
- len += self.valcom_blind.encode(&mut s)?;
|
|
|
|
|
- len += self.signature_public.encode(&mut s)?;
|
|
|
|
|
- len += self.signature.encode(s)?;
|
|
|
|
|
|
|
+ len += self.clear_inputs.encode(&mut s)?;
|
|
|
|
|
+ len += self.inputs.encode(&mut s)?;
|
|
|
|
|
+ len += self.outputs.encode(s)?;
|
|
|
Ok(len)
|
|
Ok(len)
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-impl Decodable for TransactionClearInput {
|
|
|
|
|
|
|
+impl Decodable for Transaction {
|
|
|
fn decode<D: io::Read>(mut d: D) -> Result<Self> {
|
|
fn decode<D: io::Read>(mut d: D) -> Result<Self> {
|
|
|
Ok(Self {
|
|
Ok(Self {
|
|
|
- value: Decodable::decode(&mut d)?,
|
|
|
|
|
- valcom_blind: Decodable::decode(&mut d)?,
|
|
|
|
|
- signature_public: Decodable::decode(&mut d)?,
|
|
|
|
|
- signature: Decodable::decode(d)?,
|
|
|
|
|
|
|
+ clear_inputs: Decodable::decode(&mut d)?,
|
|
|
|
|
+ inputs: Decodable::decode(&mut d)?,
|
|
|
|
|
+ outputs: Decodable::decode(d)?,
|
|
|
})
|
|
})
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-pub struct PartialTransactionClearInput {
|
|
|
|
|
- pub value: u64,
|
|
|
|
|
- pub valcom_blind: jubjub::Fr,
|
|
|
|
|
- pub signature_public: jubjub::SubgroupPoint,
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-impl_vec!(PartialTransactionClearInput);
|
|
|
|
|
-
|
|
|
|
|
-impl Encodable for PartialTransactionClearInput {
|
|
|
|
|
|
|
+impl Encodable for TransactionClearInput {
|
|
|
fn encode<S: io::Write>(&self, mut s: S) -> Result<usize> {
|
|
fn encode<S: io::Write>(&self, mut s: S) -> Result<usize> {
|
|
|
let mut len = 0;
|
|
let mut len = 0;
|
|
|
len += self.value.encode(&mut s)?;
|
|
len += self.value.encode(&mut s)?;
|
|
|
len += self.valcom_blind.encode(&mut s)?;
|
|
len += self.valcom_blind.encode(&mut s)?;
|
|
|
len += self.signature_public.encode(&mut s)?;
|
|
len += self.signature_public.encode(&mut s)?;
|
|
|
|
|
+ len += self.signature.encode(s)?;
|
|
|
Ok(len)
|
|
Ok(len)
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-impl Decodable for PartialTransactionClearInput {
|
|
|
|
|
|
|
+impl Decodable for TransactionClearInput {
|
|
|
fn decode<D: io::Read>(mut d: D) -> Result<Self> {
|
|
fn decode<D: io::Read>(mut d: D) -> Result<Self> {
|
|
|
Ok(Self {
|
|
Ok(Self {
|
|
|
value: Decodable::decode(&mut d)?,
|
|
value: Decodable::decode(&mut d)?,
|
|
|
valcom_blind: Decodable::decode(&mut d)?,
|
|
valcom_blind: Decodable::decode(&mut d)?,
|
|
|
signature_public: Decodable::decode(&mut d)?,
|
|
signature_public: Decodable::decode(&mut d)?,
|
|
|
|
|
+ signature: Decodable::decode(d)?,
|
|
|
})
|
|
})
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-pub struct PartialTransactionInput {
|
|
|
|
|
- pub spend_proof: groth16::Proof<Bls12>,
|
|
|
|
|
- pub revealed: SpendRevealedValues,
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-impl Encodable for PartialTransactionInput {
|
|
|
|
|
- fn encode<S: io::Write>(&self, mut s: S) -> Result<usize> {
|
|
|
|
|
- let mut len = 0;
|
|
|
|
|
- len += self.spend_proof.encode(&mut s)?;
|
|
|
|
|
- len += self.revealed.encode(s)?;
|
|
|
|
|
- Ok(len)
|
|
|
|
|
- }
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-impl Decodable for PartialTransactionInput {
|
|
|
|
|
- fn decode<D: io::Read>(mut d: D) -> Result<Self> {
|
|
|
|
|
- Ok(Self {
|
|
|
|
|
- spend_proof: Decodable::decode(&mut d)?,
|
|
|
|
|
- revealed: Decodable::decode(d)?,
|
|
|
|
|
- })
|
|
|
|
|
- }
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-impl_vec!(PartialTransactionInput);
|
|
|
|
|
-
|
|
|
|
|
-pub struct TransactionInput {
|
|
|
|
|
- pub spend_proof: groth16::Proof<Bls12>,
|
|
|
|
|
- pub revealed: SpendRevealedValues,
|
|
|
|
|
- pub signature: schnorr::Signature,
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-impl TransactionInput {
|
|
|
|
|
- fn from_partial(partial: PartialTransactionInput, signature: schnorr::Signature) -> Self {
|
|
|
|
|
- Self {
|
|
|
|
|
- spend_proof: partial.spend_proof,
|
|
|
|
|
- revealed: partial.revealed,
|
|
|
|
|
- signature,
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- fn encode_without_signature<S: io::Write>(&self, mut s: S) -> Result<usize> {
|
|
|
|
|
- let mut len = 0;
|
|
|
|
|
- len += self.spend_proof.encode(&mut s)?;
|
|
|
|
|
- len += self.revealed.encode(&mut s)?;
|
|
|
|
|
- Ok(len)
|
|
|
|
|
- }
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-trait EncodableWithoutSignature {
|
|
|
|
|
- fn encode_without_signature<S: io::Write>(&self, s: S) -> Result<usize>;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-impl_vec_without_signature!(TransactionInput);
|
|
|
|
|
-
|
|
|
|
|
impl Encodable for TransactionInput {
|
|
impl Encodable for TransactionInput {
|
|
|
fn encode<S: io::Write>(&self, mut s: S) -> Result<usize> {
|
|
fn encode<S: io::Write>(&self, mut s: S) -> Result<usize> {
|
|
|
let mut len = 0;
|
|
let mut len = 0;
|
|
@@ -484,16 +211,6 @@ impl Decodable for TransactionInput {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-impl_vec!(TransactionInput);
|
|
|
|
|
-
|
|
|
|
|
-pub struct TransactionOutput {
|
|
|
|
|
- pub mint_proof: groth16::Proof<Bls12>,
|
|
|
|
|
- pub revealed: MintRevealedValues,
|
|
|
|
|
- pub enc_note: EncryptedNote,
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-impl_vec!(TransactionOutput);
|
|
|
|
|
-
|
|
|
|
|
impl Encodable for TransactionOutput {
|
|
impl Encodable for TransactionOutput {
|
|
|
fn encode<S: io::Write>(&self, mut s: S) -> Result<usize> {
|
|
fn encode<S: io::Write>(&self, mut s: S) -> Result<usize> {
|
|
|
let mut len = 0;
|
|
let mut len = 0;
|
|
@@ -513,3 +230,30 @@ impl Decodable for TransactionOutput {
|
|
|
})
|
|
})
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+trait EncodableWithoutSignature {
|
|
|
|
|
+ fn encode_without_signature<S: io::Write>(&self, s: S) -> Result<usize>;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+macro_rules! impl_vec_without_signature {
|
|
|
|
|
+ ($type: ty) => {
|
|
|
|
|
+ impl EncodableWithoutSignature for Vec<$type> {
|
|
|
|
|
+ #[inline]
|
|
|
|
|
+ fn encode_without_signature<S: io::Write>(&self, mut s: S) -> Result<usize> {
|
|
|
|
|
+ let mut len = 0;
|
|
|
|
|
+ len += VarInt(self.len() as u64).encode(&mut s)?;
|
|
|
|
|
+ for c in self.iter() {
|
|
|
|
|
+ len += c.encode_without_signature(&mut s)?;
|
|
|
|
|
+ }
|
|
|
|
|
+ Ok(len)
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ };
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+impl_vec_without_signature!(TransactionClearInput);
|
|
|
|
|
+impl_vec_without_signature!(TransactionInput);
|
|
|
|
|
+impl_vec!(TransactionClearInput);
|
|
|
|
|
+impl_vec!(TransactionInput);
|
|
|
|
|
+impl_vec!(TransactionOutput);
|
|
|
|
|
+
|