tx.rs 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. use incrementalmerkletree::{bridgetree::BridgeTree, Frontier, Tree};
  2. use rand::rngs::OsRng;
  3. use darkfi::{
  4. crypto::{
  5. coin::Coin,
  6. keypair::{Keypair, PublicKey, SecretKey},
  7. merkle_node::MerkleNode,
  8. note::{EncryptedNote, Note},
  9. nullifier::Nullifier,
  10. proof::{ProvingKey, VerifyingKey},
  11. token_id::generate_id2,
  12. },
  13. node::state::{state_transition, ProgramState, StateUpdate},
  14. tx,
  15. util::NetworkName,
  16. zk::circuit::{mint_contract::MintContract, spend_contract::SpendContract},
  17. Result,
  18. };
  19. struct MemoryState {
  20. // The entire merkle tree state
  21. tree: BridgeTree<MerkleNode, 32>,
  22. // List of all previous and the current merkle roots
  23. // This is the hashed value of all the children.
  24. merkle_roots: Vec<MerkleNode>,
  25. // Nullifiers prevent double spending
  26. nullifiers: Vec<Nullifier>,
  27. // All received coins
  28. // NOTE: we need maybe a flag to keep track of which ones are spent
  29. // Maybe the spend field links to a tx hash:input index
  30. // We should also keep track of the tx hash:output index where this
  31. // coin was received
  32. own_coins: Vec<(Coin, Note)>,
  33. mint_vk: VerifyingKey,
  34. spend_vk: VerifyingKey,
  35. // Public key of the cashier
  36. cashier_signature_public: PublicKey,
  37. // List of all our secret keys
  38. secrets: Vec<SecretKey>,
  39. }
  40. impl ProgramState for MemoryState {
  41. fn is_valid_cashier_public_key(&self, public: &PublicKey) -> bool {
  42. public == &self.cashier_signature_public
  43. }
  44. fn is_valid_merkle(&self, merkle_root: &MerkleNode) -> bool {
  45. self.merkle_roots.iter().any(|m| m == merkle_root)
  46. }
  47. fn nullifier_exists(&self, nullifier: &Nullifier) -> bool {
  48. self.nullifiers.iter().any(|n| n == nullifier)
  49. }
  50. fn mint_vk(&self) -> &VerifyingKey {
  51. &self.mint_vk
  52. }
  53. fn spend_vk(&self) -> &VerifyingKey {
  54. &self.spend_vk
  55. }
  56. }
  57. impl MemoryState {
  58. fn apply(&mut self, mut update: StateUpdate) {
  59. // Extend our list of nullifiers with the ones from the update
  60. self.nullifiers.append(&mut update.nullifiers);
  61. // Update merkle tree and witnesses
  62. for (coin, enc_note) in update.coins.into_iter().zip(update.enc_notes.into_iter()) {
  63. // Add the new coins to the merkle tree
  64. let node = MerkleNode(coin.0);
  65. self.tree.append(&node);
  66. // Keep track of all merkle roots that have existed
  67. self.merkle_roots.push(self.tree.root());
  68. if let Some((note, _secret)) = self.try_decrypt_note(enc_note) {
  69. self.own_coins.push((coin, note));
  70. self.tree.witness();
  71. }
  72. }
  73. }
  74. fn try_decrypt_note(&self, ciphertext: EncryptedNote) -> Option<(Note, SecretKey)> {
  75. // Loop through all our secret keys...
  76. for secret in &self.secrets {
  77. // ... attempt to decrypt the note ...
  78. if let Ok(note) = ciphertext.decrypt(secret) {
  79. // ... and return the decrypted note for this coin.
  80. return Some((note, *secret))
  81. }
  82. }
  83. // We weren't able to decrypt the note with any of our keys.
  84. None
  85. }
  86. }
  87. fn main() -> Result<()> {
  88. let cashier_signature_secret = SecretKey::random(&mut OsRng);
  89. let cashier_signature_public = PublicKey::from_secret(cashier_signature_secret);
  90. let keypair = Keypair::random(&mut OsRng);
  91. const K: u32 = 11;
  92. let mint_vk = VerifyingKey::build(K, &MintContract::default());
  93. let spend_vk = VerifyingKey::build(K, &SpendContract::default());
  94. let mut state = MemoryState {
  95. tree: BridgeTree::<MerkleNode, 32>::new(100),
  96. merkle_roots: vec![],
  97. nullifiers: vec![],
  98. own_coins: vec![],
  99. mint_vk,
  100. spend_vk,
  101. cashier_signature_public,
  102. secrets: vec![keypair.secret],
  103. };
  104. let token_id =
  105. generate_id2("So11111111111111111111111111111111111111112", &NetworkName::Solana)?;
  106. let builder = tx::TransactionBuilder {
  107. clear_inputs: vec![tx::TransactionBuilderClearInputInfo {
  108. value: 110,
  109. token_id,
  110. signature_secret: cashier_signature_secret,
  111. }],
  112. inputs: vec![],
  113. outputs: vec![tx::TransactionBuilderOutputInfo {
  114. value: 110,
  115. token_id,
  116. public: keypair.public,
  117. }],
  118. };
  119. let mint_pk = ProvingKey::build(K, &MintContract::default());
  120. let spend_pk = ProvingKey::build(K, &SpendContract::default());
  121. let tx = builder.build(&mint_pk, &spend_pk)?;
  122. tx.verify(&state.mint_vk, &state.spend_vk).expect("tx verify");
  123. let _note = tx.outputs[0].enc_note.decrypt(&keypair.secret)?;
  124. let update = state_transition(&state, tx)?;
  125. state.apply(update);
  126. // Now spend
  127. let (coin, note) = &state.own_coins[0];
  128. let node = MerkleNode(coin.0);
  129. let (leaf_position, merkle_path) = state.tree.authentication_path(&node).unwrap();
  130. let builder = tx::TransactionBuilder {
  131. clear_inputs: vec![],
  132. inputs: vec![tx::TransactionBuilderInputInfo {
  133. leaf_position,
  134. merkle_path,
  135. secret: keypair.secret,
  136. note: *note,
  137. }],
  138. outputs: vec![tx::TransactionBuilderOutputInfo {
  139. value: 110,
  140. token_id,
  141. public: keypair.public,
  142. }],
  143. };
  144. let tx = builder.build(&mint_pk, &spend_pk)?;
  145. let update = state_transition(&state, tx)?;
  146. state.apply(update);
  147. Ok(())
  148. }