narodnik 5 жил өмнө
parent
commit
1bf94ee288
1 өөрчлөгдсөн 56 нэмэгдсэн , 2 устгасан
  1. 56 2
      src/bin/tx.rs

+ 56 - 2
src/bin/tx.rs

@@ -43,40 +43,77 @@ fn main() {
     // This is their public key
     let public = zcash_primitives::constants::SPENDING_KEY_GENERATOR * secret;
 
+    // Step 1: Cashier deposits to wallet1's address
+
+    // Create the deposit for 110 BTC
+    // Clear inputs are visible to everyone on the network
     let builder = tx::TransactionBuilder {
         clear_inputs: vec![tx::TransactionBuilderClearInputInfo { value: 110, signature_secret: cashier_secret }],
         inputs: vec![],
         outputs: vec![tx::TransactionBuilderOutputInfo { value: 110, public }],
     };
 
+    // We will 'compile' the tx, and then serialize it to this Vec<u8>
     let mut tx_data = vec![];
     {
+        // Build the tx
         let tx = builder.build(&mint_params, &spend_params);
+        // Now serialize it
         tx.encode(&mut tx_data).expect("encode tx");
     }
+
+    // Step 1 is completed.
+    // Tx data is posted to the blockchain
+
+    // Step 2: wallet1 receive's payment from the cashier
+
+    // Wallet1 is receiving tx, and for every new coin it finds, it adds to its merkle tree
     let mut tree = CommitmentTree::empty();
+    // Here we simulate 5 fake random coins, adding them to our tree.
     for i in 0..5 {
         let cmu = Coin::new(bls12_381::Scalar::random(&mut OsRng).to_repr());
         tree.append(cmu);
     }
+    // Now we receive the tx data
     let note = {
         let tx = tx::Transaction::decode(&tx_data[..]).unwrap();
+        // Check the public key in the clear inputs
+        // It should be a valid public key for the cashier
+        assert_eq!(tx.clear_inputs[0].signature_public, cashier_public);
+        // Check the tx verifies correctly
         assert!(tx.verify(&mint_pvk, &spend_pvk));
+        // Add the new coins to the merkle tree
         tree.append(Coin::new(tx.outputs[0].revealed.coin))
             .expect("append merkle");
 
+        // Now for every new tx we receive, the wallets should iterate over all outputs
+        // and try to decrypt the coin's note.
+        // If they can successfully decrypt it, then it's a coin destined for us.
+
         // Try to decrypt output note
         let note = tx.outputs[0]
             .enc_note
             .decrypt(&secret)
             .expect("note should be destined for us");
+        // This contains the secret attributes so we can spend the coin
         note
     };
+
+    // Wallet1 has received payment from the cashier.
+    // Step 2 is complete.
+
+    // We need to keep track of the witness for this coin.
+    // This allows us to prove inclusion of the coin in the merkle tree with ZK.
+    // Just as we update the merkle tree with every new coin, so we do the same with the witness.
+
+    // Derive the current witness from the current tree.
+    // This is done right after we add our coin to the tree (but before any other coins are added)
     let mut witness = IncrementalWitness::from_tree(&tree);
+    // Check this is the 6th coin we added
     assert_eq!(witness.position(), 5);
     assert_eq!(tree.root(), witness.root());
 
-    // Add some random coins in
+    // Add some more random coins in
     for i in 0..10 {
         let cmu = Coin::new(bls12_381::Scalar::random(&mut OsRng).to_repr());
         tree.append(cmu);
@@ -84,6 +121,7 @@ fn main() {
         assert_eq!(tree.root(), witness.root());
     }
 
+    // TODO: Some stupid glue code. Need to put this somewhere else.
     let merkle_path = witness.path().unwrap();
     let auth_path: Vec<(bls12_381::Scalar, bool)> = merkle_path
         .auth_path
@@ -91,12 +129,24 @@ fn main() {
         .map(|(node, b)| ((*node).into(), *b))
         .collect();
 
+    // Step 3: wallet1 sends payment to wallet2
+
+    // Wallet1 now wishes to send the coin to wallet2
+
+    let secret2 = jubjub::Fr::random(&mut OsRng);
+    // This is their public key
+    let public2 = zcash_primitives::constants::SPENDING_KEY_GENERATOR * secret2;
+
     // Make a spend tx
 
+    // Get the coin we're spending from the previous tx
     let coin = {
         let tx = tx::Transaction::decode(&tx_data[..]).unwrap();
         tx.outputs[0].revealed.coin
     };
+
+    // Construct a new tx spending the coin
+    // We need the decrypted note and our private key
     let builder = tx::TransactionBuilder {
         clear_inputs: vec![],
         inputs: vec![tx::TransactionBuilderInputInfo {
@@ -106,13 +156,17 @@ fn main() {
             secret,
             note,
         }],
-        outputs: vec![tx::TransactionBuilderOutputInfo { value: 110, public }],
+        // 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 }],
     };
+    // Build the tx
     let mut tx_data = vec![];
     {
         let tx = builder.build(&mint_params, &spend_params);
         tx.encode(&mut tx_data).expect("encode tx");
     }
+    // Verify it's valid
     {
         let tx = tx::Transaction::decode(&tx_data[..]).unwrap();
         assert!(tx.verify(&mint_pvk, &spend_pvk));