Просмотр исходного кода

dao_demo: airdrop user gDRK from command-line.

lunar-mining 3 лет назад
Родитель
Сommit
66546afd93
4 измененных файлов с 83 добавлено и 36 удалено
  1. 19 7
      bin/dao/dao-cli/src/main.rs
  2. 9 2
      bin/dao/dao-cli/src/rpc.rs
  3. 34 2
      bin/dao/daod/src/main.rs
  4. 21 25
      bin/dao/daod/src/rpc.rs

+ 19 - 7
bin/dao/dao-cli/src/main.rs

@@ -33,8 +33,15 @@ pub enum CliDaoSubCommands {
         /// DAO public identifier.
         /// DAO public identifier.
         dao_bulla: String,
         dao_bulla: String,
     },
     },
+    Keygen {
+        nym: String,
+    },
     /// Airdrop tokens
     /// Airdrop tokens
-    Airdrop {},
+    Airdrop {
+        nym: String,
+
+        value: u64,
+    },
     /// Propose
     /// Propose
     Propose {},
     Propose {},
     /// Vote
     /// Vote
@@ -77,22 +84,27 @@ async fn start(options: CliDao) -> Result<()> {
                     dao_approval_ratio_base,
                     dao_approval_ratio_base,
                 )
                 )
                 .await?;
                 .await?;
-            println!("Server replied: {}", &reply.to_string());
+            println!("Created DAO bulla: {}", &reply.to_string());
             return Ok(())
             return Ok(())
         }
         }
         Some(CliDaoSubCommands::Addr {}) => {
         Some(CliDaoSubCommands::Addr {}) => {
             let reply = client.addr().await?;
             let reply = client.addr().await?;
-            println!("Server replied: {}", &reply.to_string());
+            println!("DAO public address: {}", &reply.to_string());
             return Ok(())
             return Ok(())
         }
         }
         Some(CliDaoSubCommands::Mint { token_supply, dao_addr, dao_bulla }) => {
         Some(CliDaoSubCommands::Mint { token_supply, dao_addr, dao_bulla }) => {
             let reply = client.mint(token_supply, dao_addr, dao_bulla).await?;
             let reply = client.mint(token_supply, dao_addr, dao_bulla).await?;
-            println!("Server replied: {}", &reply.to_string());
+            println!("New DAO balance: {}", &reply.to_string());
             return Ok(())
             return Ok(())
         }
         }
-        Some(CliDaoSubCommands::Airdrop {}) => {
-            let reply = client.airdrop().await?;
-            println!("Server replied: {}", &reply.to_string());
+        Some(CliDaoSubCommands::Keygen { nym }) => {
+            let reply = client.keygen(nym).await?;
+            println!("User public key: {}", &reply.to_string());
+            return Ok(())
+        }
+        Some(CliDaoSubCommands::Airdrop { nym, value }) => {
+            let reply = client.airdrop(nym, value).await?;
+            println!("New user balance: {}", &reply.to_string());
             return Ok(())
             return Ok(())
         }
         }
         Some(CliDaoSubCommands::Propose {}) => {
         Some(CliDaoSubCommands::Propose {}) => {

+ 9 - 2
bin/dao/dao-cli/src/rpc.rs

@@ -47,8 +47,15 @@ impl Rpc {
 
 
     // --> {"jsonrpc": "2.0", "method": "airdrop", "params": [], "id": 42}
     // --> {"jsonrpc": "2.0", "method": "airdrop", "params": [], "id": 42}
     // <-- {"jsonrpc": "2.0", "result": "airdropping tokens...", "id": 42}
     // <-- {"jsonrpc": "2.0", "result": "airdropping tokens...", "id": 42}
-    pub async fn airdrop(&self) -> Result<Value> {
-        let req = JsonRequest::new("airdrop", json!([]));
+    pub async fn airdrop(&self, nym: String, value: u64) -> Result<Value> {
+        let req = JsonRequest::new("airdrop", json!([nym, value]));
+        self.client.request(req).await
+    }
+
+    // --> {"jsonrpc": "2.0", "method": "airdrop", "params": [], "id": 42}
+    // <-- {"jsonrpc": "2.0", "result": "airdropping tokens...", "id": 42}
+    pub async fn keygen(&self, nym: String) -> Result<Value> {
+        let req = JsonRequest::new("keygen", json!([nym]));
         self.client.request(req).await
         self.client.request(req).await
     }
     }
 
 

+ 34 - 2
bin/dao/daod/src/main.rs

@@ -127,7 +127,8 @@ impl Client {
         let signature_secret = SecretKey::random(&mut OsRng);
         let signature_secret = SecretKey::random(&mut OsRng);
         let leaf_position = Position::zero();
         let leaf_position = Position::zero();
         let money_wallet = MoneyWallet { keypair, signature_secret, leaf_position };
         let money_wallet = MoneyWallet { keypair, signature_secret, leaf_position };
-        self.money_wallets.insert(key, money_wallet);
+        self.money_wallets.insert(key.clone(), money_wallet);
+        debug!(target: "dao-demo::client::new_money_wallet()", "created wallet with key {}", &key);
     }
     }
 
 
     // TODO: user passes DAO approval ratio: 1/2
     // TODO: user passes DAO approval ratio: 1/2
@@ -196,7 +197,7 @@ impl Client {
         let tx =
         let tx =
             self.cashier.mint(*XDRK_ID, token_supply, dao_bulla, recipient, &self.zk_bins).unwrap();
             self.cashier.mint(*XDRK_ID, token_supply, dao_bulla, recipient, &self.zk_bins).unwrap();
 
 
-        self.validate(&tx).unwrap();
+        self.validate(&tx)?;
 
 
         let own_coin = self.dao_wallet.balances(&mut self.states)?;
         let own_coin = self.dao_wallet.balances(&mut self.states)?;
 
 
@@ -205,6 +206,26 @@ impl Client {
         Ok(balance)
         Ok(balance)
     }
     }
 
 
+    fn airdrop_user(&mut self, value: u64, token_id: pallas::Base, nym: String) -> Result<()> {
+        let wallet = self.money_wallets.get(&nym).unwrap();
+        wallet.track(&mut self.states);
+
+        let addr = wallet.get_public_key();
+
+        let tx = self.cashier.airdrop(value, token_id, addr, &self.zk_bins)?;
+        self.validate(&tx)?;
+
+        Ok(())
+    }
+
+    fn query_balance(&mut self, nym: String) -> Result<u64> {
+        let wallet = self.money_wallets.get(&nym).unwrap();
+        let own_coin = wallet.balances(&mut self.states)?;
+        let balance = own_coin.note.value;
+
+        Ok(balance)
+    }
+
     // TODO: Change these into errors instead of expects.
     // TODO: Change these into errors instead of expects.
     fn validate(&mut self, tx: &Transaction) -> Result<()> {
     fn validate(&mut self, tx: &Transaction) -> Result<()> {
         let mut updates = vec![];
         let mut updates = vec![];
@@ -592,6 +613,17 @@ impl MoneyWallet {
         PublicKey::from_secret(self.signature_secret)
         PublicKey::from_secret(self.signature_secret)
     }
     }
 
 
+    fn get_public_key(&self) -> PublicKey {
+        self.keypair.public
+    }
+
+    fn track(&self, states: &mut StateRegistry) -> Result<()> {
+        let state =
+            states.lookup_mut::<money_contract::State>(*money_contract::CONTRACT_ID).unwrap();
+        state.wallet_cache.track(self.keypair.secret);
+        Ok(())
+    }
+
     fn balances(&self, states: &mut StateRegistry) -> Result<OwnCoin> {
     fn balances(&self, states: &mut StateRegistry) -> Result<OwnCoin> {
         let state =
         let state =
             states.lookup_mut::<money_contract::State>(*money_contract::CONTRACT_ID).unwrap();
             states.lookup_mut::<money_contract::State>(*money_contract::CONTRACT_ID).unwrap();

+ 21 - 25
bin/dao/daod/src/rpc.rs

@@ -94,7 +94,6 @@ impl JsonRpcInterface {
     // --> {"method": "mint_treasury", "params": []}
     // --> {"method": "mint_treasury", "params": []}
     // <-- {"result": "minting treasury..."}
     // <-- {"result": "minting treasury..."}
     async fn mint_treasury(&self, id: Value, params: &[Value]) -> JsonResult {
     async fn mint_treasury(&self, id: Value, params: &[Value]) -> JsonResult {
-        // TODO: pass DAO params + zk_bins into mint_treasury
         // TODO: error handling
         // TODO: error handling
         let mut client = self.client.lock().await;
         let mut client = self.client.lock().await;
 
 
@@ -103,8 +102,8 @@ impl JsonRpcInterface {
         let bulla = params[2].as_str().unwrap();
         let bulla = params[2].as_str().unwrap();
 
 
         let dao_bulla = parse_b58(bulla).unwrap();
         let dao_bulla = parse_b58(bulla).unwrap();
-
         let dao_addr = PublicKey::from_str(addr).unwrap();
         let dao_addr = PublicKey::from_str(addr).unwrap();
+
         //match PublicKey::from_str(addr) {
         //match PublicKey::from_str(addr) {
         //    Ok(addr) => {
         //    Ok(addr) => {
         //        debug!(target: "daod::rpc", "Decoded correctly: {:?}", addr)
         //        debug!(target: "daod::rpc", "Decoded correctly: {:?}", addr)
@@ -117,38 +116,35 @@ impl JsonRpcInterface {
         let balance = client.mint_treasury(*XDRK_ID, token_supply, dao_bulla, dao_addr).unwrap();
         let balance = client.mint_treasury(*XDRK_ID, token_supply, dao_bulla, dao_addr).unwrap();
 
 
         JsonResponse::new(json!(balance), id).into()
         JsonResponse::new(json!(balance), id).into()
-        //JsonResponse::new(json!("test"), id).into()
     }
     }
 
 
     // Create a new wallet for governance tokens.
     // Create a new wallet for governance tokens.
-    // TODO: must pass a string identifier like alice, bob, charlie
-    async fn keygen(&self, id: Value, _params: &[Value]) -> JsonResult {
+    async fn keygen(&self, id: Value, params: &[Value]) -> JsonResult {
+        debug!(target: "dao-demo::rpc::keygen()", "Received keygen request");
         let mut client = self.client.lock().await;
         let mut client = self.client.lock().await;
-        // TODO: pass string id
-        //client.client.new_money_wallet(alice);
-        //let wallet = client.client.money_wallets.get(alice) {
-        //      Some(wallet) => wallet.keypair.public
-        //}
-        // TODO: return 'Alice: public key' to CLI
-        JsonResponse::new(json!("created new keys"), id).into()
+        let nym = params[0].as_str().unwrap().to_string();
+
+        client.new_money_wallet(nym.clone());
+
+        let wallet = client.money_wallets.get(&nym).unwrap();
+        let pubkey = wallet.get_public_key();
+
+        let addr: String = bs58::encode(pubkey.to_bytes()).into_string();
+        JsonResponse::new(json!(addr), id).into()
     }
     }
     // --> {"method": "airdrop_tokens", "params": []}
     // --> {"method": "airdrop_tokens", "params": []}
     // <-- {"result": "airdropping tokens..."}
     // <-- {"result": "airdropping tokens..."}
-    // TODO: pass a string 'alice'
-    async fn airdrop_tokens(&self, id: Value, _params: &[Value]) -> JsonResult {
+    async fn airdrop_tokens(&self, id: Value, params: &[Value]) -> JsonResult {
         let mut client = self.client.lock().await;
         let mut client = self.client.lock().await;
         let zk_bins = &client.zk_bins;
         let zk_bins = &client.zk_bins;
-        //let keypair_public = client.client.money_wallets.get(alice) {
-        //      Some(wallet) => wallet.keypair.public
-        //};
-        //let transaction = client.cashier.airdrop(keypair_public, zk_bins);
-        // client.client.validate(tx);
-        //
-        // client.client.money_wallets.get(alice) {
-        //      Some(wallet) => wallet.balances()
-        // }
-        // TODO: return wallet balance to command line
-        JsonResponse::new(json!("tokens airdropped"), id).into()
+
+        let nym = params[0].as_str().unwrap().to_string();
+        let value = params[1].as_u64().unwrap();
+
+        client.airdrop_user(value, *GDRK_ID, nym.clone()).unwrap();
+        let balance = client.query_balance(nym.clone()).unwrap();
+
+        JsonResponse::new(json!(balance), id).into()
     }
     }
     // --> {"method": "create_proposal", "params": []}
     // --> {"method": "create_proposal", "params": []}
     // <-- {"result": "creating proposal..."}
     // <-- {"result": "creating proposal..."}