lib.rs 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  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. use darkfi_sdk::{
  19. crypto::{ContractId, MerkleNode, MerkleTree},
  20. db::{db_init, db_lookup, db_set},
  21. define_contract,
  22. error::ContractResult,
  23. merkle::merkle_add,
  24. msg,
  25. pasta::pallas,
  26. tx::ContractCall,
  27. util::set_return_data,
  28. };
  29. use darkfi_serial::{
  30. deserialize, serialize, Encodable, SerialDecodable, SerialEncodable, WriteExt,
  31. };
  32. #[derive(Clone, SerialEncodable, SerialDecodable)]
  33. pub struct DaoBulla(pub pallas::Base);
  34. #[repr(u8)]
  35. pub enum DaoFunction {
  36. Foo = 0x00,
  37. Mint = 0x01,
  38. }
  39. impl From<u8> for DaoFunction {
  40. fn from(b: u8) -> Self {
  41. match b {
  42. 0x00 => Self::Foo,
  43. 0x01 => Self::Mint,
  44. _ => panic!("Invalid function ID: {:#04x?}", b),
  45. }
  46. }
  47. }
  48. #[derive(SerialEncodable, SerialDecodable)]
  49. pub struct DaoMintParams {
  50. pub dao_bulla: DaoBulla,
  51. }
  52. #[derive(SerialEncodable, SerialDecodable)]
  53. pub struct DaoMintUpdate {
  54. pub dao_bulla: DaoBulla,
  55. }
  56. define_contract!(
  57. init: init_contract,
  58. exec: process_instruction,
  59. apply: process_update,
  60. metadata: get_metadata
  61. );
  62. fn init_contract(cid: ContractId, _ix: &[u8]) -> ContractResult {
  63. let info_db = db_init(cid, "info")?;
  64. let _ = db_init(cid, "dao_roots")?;
  65. let dao_tree = MerkleTree::new(100);
  66. let mut dao_tree_data = Vec::new();
  67. dao_tree_data.write_u32(0)?;
  68. dao_tree.encode(&mut dao_tree_data)?;
  69. db_set(info_db, &serialize(&"dao_tree".to_string()), &dao_tree_data)?;
  70. Ok(())
  71. }
  72. fn get_metadata(_cid: ContractId, ix: &[u8]) -> ContractResult {
  73. let (call_idx, call): (u32, Vec<ContractCall>) = deserialize(ix)?;
  74. assert!(call_idx < call.len() as u32);
  75. let self_ = &call[call_idx as usize];
  76. match DaoFunction::from(self_.data[0]) {
  77. DaoFunction::Mint => {
  78. let data = &self_.data[1..];
  79. let params: DaoMintParams = deserialize(data)?;
  80. let zk_public_values: Vec<(String, Vec<pallas::Base>)> =
  81. vec![("dao-mint".to_string(), vec![params.dao_bulla.0])];
  82. let signature_public_keys: Vec<pallas::Point> = Vec::new();
  83. let mut metadata = Vec::new();
  84. zk_public_values.encode(&mut metadata)?;
  85. signature_public_keys.encode(&mut metadata)?;
  86. set_return_data(&metadata)?;
  87. }
  88. DaoFunction::Foo => {
  89. unimplemented!();
  90. }
  91. }
  92. Ok(())
  93. }
  94. fn process_instruction(cid: ContractId, ix: &[u8]) -> ContractResult {
  95. let (call_idx, call): (u32, Vec<ContractCall>) = deserialize(ix)?;
  96. assert!(call_idx < call.len() as u32);
  97. let self_ = &call[call_idx as usize];
  98. match DaoFunction::from(self_.data[0]) {
  99. DaoFunction::Mint => {
  100. let data = &self_.data[1..];
  101. let params: DaoMintParams = deserialize(data)?;
  102. // No checks in Mint. Just return the update.
  103. let update = DaoMintUpdate { dao_bulla: params.dao_bulla };
  104. let mut update_data = Vec::new();
  105. update_data.write_u8(DaoFunction::Mint as u8)?;
  106. update.encode(&mut update_data)?;
  107. set_return_data(&update_data)?;
  108. msg!("update is set!");
  109. }
  110. DaoFunction::Foo => {
  111. unimplemented!();
  112. }
  113. }
  114. Ok(())
  115. }
  116. fn process_update(cid: ContractId, update_data: &[u8]) -> ContractResult {
  117. match DaoFunction::from(update_data[0]) {
  118. DaoFunction::Mint => {
  119. let data = &update_data[1..];
  120. let update: DaoMintUpdate = deserialize(data)?;
  121. let db_info = db_lookup(cid, "info")?;
  122. let db_roots = db_lookup(cid, "dao_roots")?;
  123. let node = MerkleNode::new(update.dao_bulla.0);
  124. merkle_add(db_info, db_roots, &serialize(&"dao_tree".to_string()), &node)?;
  125. }
  126. DaoFunction::Foo => {
  127. unimplemented!();
  128. }
  129. }
  130. Ok(())
  131. }