tx.rs 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. /* This file is part of DarkFi (https://dark.fi)
  2. *
  3. * Copyright (C) 2020-2022 Dyne.org foundation
  4. *
  5. * This program is free software: you can redistribute it and/or modify
  6. * it under the terms of the GNU Affero General Public License as
  7. * published by the Free Software Foundation, either version 3 of the
  8. * License, or (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU Affero General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU Affero General Public License
  16. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  17. */
  18. // Example transaction flow
  19. use darkfi_sdk::crypto::{constants::MERKLE_DEPTH, MerkleNode, Nullifier};
  20. use incrementalmerkletree::{bridgetree::BridgeTree, Tree};
  21. use pasta_curves::{group::ff::Field, pallas};
  22. use rand::rngs::OsRng;
  23. use darkfi::{
  24. crypto::{
  25. coin::OwnCoin,
  26. keypair::{Keypair, PublicKey, SecretKey},
  27. note::{EncryptedNote, Note},
  28. proof::{ProvingKey, VerifyingKey},
  29. util::poseidon_hash,
  30. },
  31. node::state::{state_transition, ProgramState, StateUpdate},
  32. tx::builder::{
  33. TransactionBuilder, TransactionBuilderClearInputInfo, TransactionBuilderInputInfo,
  34. TransactionBuilderOutputInfo,
  35. },
  36. zk::circuit::{BurnContract, MintContract},
  37. Result,
  38. };
  39. /// The state machine, held in memory.
  40. struct MemoryState {
  41. /// The entire Merkle tree state
  42. tree: BridgeTree<MerkleNode, MERKLE_DEPTH>,
  43. /// List of all previous and the current Merkle roots.
  44. /// This is the hashed value of all the children.
  45. merkle_roots: Vec<MerkleNode>,
  46. /// Nullifiers prevent double spending
  47. nullifiers: Vec<Nullifier>,
  48. /// All received coins
  49. // NOTE: We need maybe a flag to keep track of which ones are
  50. // spent. Maybe the spend field links to a tx hash:input index.
  51. // We should also keep track of the tx hash:output index where
  52. // this coin was received.
  53. own_coins: Vec<OwnCoin>,
  54. /// Verifying key for the mint zk circuit.
  55. mint_vk: VerifyingKey,
  56. /// Verifying key for the burn zk circuit.
  57. burn_vk: VerifyingKey,
  58. /// Public key of the cashier
  59. cashier_signature_public: PublicKey,
  60. /// Public key of the faucet
  61. faucet_signature_public: PublicKey,
  62. /// List of all our secret keys
  63. secrets: Vec<SecretKey>,
  64. }
  65. impl ProgramState for MemoryState {
  66. fn is_valid_cashier_public_key(&self, public: &PublicKey) -> bool {
  67. public == &self.cashier_signature_public
  68. }
  69. fn is_valid_faucet_public_key(&self, public: &PublicKey) -> bool {
  70. public == &self.faucet_signature_public
  71. }
  72. fn is_valid_merkle(&self, merkle_root: &MerkleNode) -> bool {
  73. self.merkle_roots.iter().any(|m| m == merkle_root)
  74. }
  75. fn nullifier_exists(&self, nullifier: &Nullifier) -> bool {
  76. self.nullifiers.iter().any(|n| n == nullifier)
  77. }
  78. fn mint_vk(&self) -> &VerifyingKey {
  79. &self.mint_vk
  80. }
  81. fn burn_vk(&self) -> &VerifyingKey {
  82. &self.burn_vk
  83. }
  84. }
  85. impl MemoryState {
  86. fn apply(&mut self, mut update: StateUpdate) {
  87. // Extend our list of nullifiers with the ones from the update
  88. self.nullifiers.append(&mut update.nullifiers);
  89. // Update merkle tree and witnesses
  90. for (coin, enc_note) in update.coins.into_iter().zip(update.enc_notes.into_iter()) {
  91. // Add the new coins to the Merkle tree
  92. let node = MerkleNode::from(coin.0);
  93. self.tree.append(&node);
  94. // Keep track of all Merkle roots that have existed
  95. self.merkle_roots.push(self.tree.root(0).unwrap());
  96. // If it's our own coin, witness it and append to the vector.
  97. if let Some((note, secret)) = self.try_decrypt_note(enc_note) {
  98. let leaf_position = self.tree.witness().unwrap();
  99. let nullifier = Nullifier::from(poseidon_hash::<2>([secret.inner(), note.serial]));
  100. let own_coin = OwnCoin { coin, note, secret, nullifier, leaf_position };
  101. self.own_coins.push(own_coin);
  102. }
  103. }
  104. }
  105. fn try_decrypt_note(&self, ciphertext: EncryptedNote) -> Option<(Note, SecretKey)> {
  106. // Loop through all our secret keys...
  107. for secret in &self.secrets {
  108. // .. attempt to decrypt the note ...
  109. if let Ok(note) = ciphertext.decrypt(secret) {
  110. // ... and return the decrypted note for this coin.
  111. return Some((note, *secret))
  112. }
  113. }
  114. // We weren't able to decrypt the note with any of our keys.
  115. None
  116. }
  117. }
  118. fn main() -> Result<()> {
  119. let cashier_signature_secret = SecretKey::random(&mut OsRng);
  120. let cashier_signature_public = PublicKey::from_secret(cashier_signature_secret);
  121. let faucet_signature_secret = SecretKey::random(&mut OsRng);
  122. let faucet_signature_public = PublicKey::from_secret(faucet_signature_secret);
  123. let keypair = Keypair::random(&mut OsRng);
  124. let mint_vk = VerifyingKey::build(11, &MintContract::default());
  125. let burn_vk = VerifyingKey::build(11, &BurnContract::default());
  126. let mut state = MemoryState {
  127. tree: BridgeTree::<MerkleNode, MERKLE_DEPTH>::new(100),
  128. merkle_roots: vec![],
  129. nullifiers: vec![],
  130. own_coins: vec![],
  131. mint_vk,
  132. burn_vk,
  133. cashier_signature_public,
  134. faucet_signature_public,
  135. secrets: vec![keypair.secret],
  136. };
  137. let token_id = pallas::Base::random(&mut OsRng);
  138. let builder = TransactionBuilder {
  139. clear_inputs: vec![TransactionBuilderClearInputInfo {
  140. value: 110,
  141. token_id,
  142. signature_secret: cashier_signature_secret,
  143. }],
  144. inputs: vec![],
  145. outputs: vec![TransactionBuilderOutputInfo {
  146. value: 110,
  147. token_id,
  148. public: keypair.public,
  149. }],
  150. };
  151. let mint_pk = ProvingKey::build(11, &MintContract::default());
  152. let burn_pk = ProvingKey::build(11, &BurnContract::default());
  153. let tx = builder.build(&mint_pk, &burn_pk)?;
  154. tx.verify(&state.mint_vk, &state.burn_vk)?;
  155. let _note = tx.outputs[0].enc_note.decrypt(&keypair.secret)?;
  156. let update = state_transition(&state, tx)?;
  157. state.apply(update);
  158. // Now spend
  159. let owncoin = &state.own_coins[0];
  160. let note = &owncoin.note;
  161. let leaf_position = owncoin.leaf_position;
  162. let root = state.tree.root(0).unwrap();
  163. let merkle_path = state.tree.authentication_path(leaf_position, &root).unwrap();
  164. let builder = TransactionBuilder {
  165. clear_inputs: vec![],
  166. inputs: vec![TransactionBuilderInputInfo {
  167. leaf_position,
  168. merkle_path,
  169. secret: keypair.secret,
  170. note: note.clone(),
  171. }],
  172. outputs: vec![TransactionBuilderOutputInfo {
  173. value: 110,
  174. token_id,
  175. public: keypair.public,
  176. }],
  177. };
  178. let tx = builder.build(&mint_pk, &burn_pk)?;
  179. let update = state_transition(&state, tx)?;
  180. state.apply(update);
  181. Ok(())
  182. }