tx.rs 7.1 KB

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