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

drk/deploy: Add contract lock tx

parazyd 2 лет назад
Родитель
Сommit
aa8fb77538
2 измененных файлов с 63 добавлено и 11 удалено
  1. 37 5
      bin/drk/src/deploy.rs
  2. 26 6
      bin/drk/src/main.rs

+ 37 - 5
bin/drk/src/deploy.rs

@@ -23,7 +23,10 @@ use darkfi::{
     tx::{ContractCallLeaf, Transaction, TransactionBuilder},
     Error, Result,
 };
-use darkfi_deployooor_contract::{client::deploy_v1::DeployCallBuilder, DeployFunction};
+use darkfi_deployooor_contract::{
+    client::{deploy_v1::DeployCallBuilder, lock_v1::LockCallBuilder},
+    DeployFunction,
+};
 use darkfi_sdk::{
     crypto::{ContractId, Keypair, DEPLOYOOOR_CONTRACT_ID},
     ContractCall,
@@ -74,7 +77,7 @@ impl Drk {
     }
 
     /// List contract deploy authorities from the wallet
-    pub async fn list_deploy_auth(&self) -> Result<Vec<(ContractId, bool)>> {
+    pub async fn list_deploy_auth(&self) -> Result<Vec<(i64, ContractId, bool)>> {
         let rows = match self.wallet.query_multiple(&DEPLOY_AUTH_TABLE, &[], &[]).await {
             Ok(r) => r,
             Err(e) => {
@@ -86,16 +89,20 @@ impl Drk {
 
         let mut ret = Vec::with_capacity(rows.len());
         for row in rows {
-            let Value::Blob(ref auth_bytes) = row[0] else {
+            let Value::Integer(idx) = row[0] else {
+                return Err(Error::ParseFailed("[list_deploy_auth] Failed to parse index"))
+            };
+
+            let Value::Blob(ref auth_bytes) = row[1] else {
                 return Err(Error::ParseFailed("[list_deploy_auth] Failed to parse keypair bytes"))
             };
             let deploy_auth: Keypair = deserialize_async(auth_bytes).await?;
 
-            let Value::Integer(frozen) = row[1] else {
+            let Value::Integer(frozen) = row[2] else {
                 return Err(Error::ParseFailed("[list_deploy_auth] Failed to parse \"is_frozen\""))
             };
 
-            ret.push((ContractId::derive_public(deploy_auth.public), frozen != 0))
+            ret.push((idx, ContractId::derive_public(deploy_auth.public), frozen != 0))
         }
 
         Ok(ret)
@@ -158,4 +165,29 @@ impl Drk {
 
         Ok(tx)
     }
+
+    /// Create a contract redeployment lock transaction
+    pub async fn lock_contract(&self, deploy_auth: u64) -> Result<Transaction> {
+        // Fetch the keypair
+        let deploy_keypair = self.get_deploy_auth(deploy_auth).await?;
+
+        // Create the contract call
+        let lock_call = LockCallBuilder { deploy_keypair };
+        let lock_debris = lock_call.build()?;
+
+        // Encode the call
+        let mut data = vec![DeployFunction::LockV1 as u8];
+        lock_debris.params.encode_async(&mut data).await?;
+        let call = ContractCall { contract_id: *DEPLOYOOOR_CONTRACT_ID, data };
+        let mut tx_builder =
+            TransactionBuilder::new(ContractCallLeaf { call, proofs: vec![] }, vec![])?;
+
+        // TODO: Tx fees
+
+        let mut tx = tx_builder.build()?;
+        let sigs = tx.create_sigs(&[deploy_keypair.secret])?;
+        tx.signatures = vec![sigs];
+
+        Ok(tx)
+    }
 }

+ 26 - 6
bin/drk/src/main.rs

@@ -494,7 +494,7 @@ enum ContractSubcmd {
     /// Deploy a smart contract
     Deploy {
         /// Contract ID (deploy authority)
-        deploy_auth: String,
+        deploy_auth: u64,
 
         /// Path to contract wasm bincode
         wasm_path: String,
@@ -502,6 +502,12 @@ enum ContractSubcmd {
         /// Path to serialized deploy instruction
         deploy_ix: String,
     },
+
+    /// Lock a smart contract
+    Lock {
+        /// Contract ID (deploy authority)
+        deploy_auth: u64,
+    },
 }
 
 /// CLI-util structure
@@ -1682,10 +1688,10 @@ async fn realmain(args: Args, ex: Arc<smol::Executor<'static>>) -> Result<()> {
 
                 let mut table = Table::new();
                 table.set_format(*format::consts::FORMAT_NO_BORDER_LINE_SEPARATOR);
-                table.set_titles(row!["Contract ID", "Frozen"]);
+                table.set_titles(row!["Index", "Contract ID", "Frozen"]);
 
-                for (contract_id, frozen) in auths {
-                    table.add_row(row![contract_id, frozen]);
+                for (idx, contract_id, frozen) in auths {
+                    table.add_row(row![idx, contract_id, frozen]);
                 }
 
                 if table.is_empty() {
@@ -1705,8 +1711,6 @@ async fn realmain(args: Args, ex: Arc<smol::Executor<'static>>) -> Result<()> {
                 let drk =
                     Drk::new(args.wallet_path, args.wallet_pass, Some(args.endpoint), ex).await?;
 
-                let deploy_auth = u64::from_str(&deploy_auth)?;
-
                 let tx = match drk.deploy_contract(deploy_auth, wasm_bin, deploy_ix).await {
                     Ok(v) => v,
                     Err(e) => {
@@ -1718,6 +1722,22 @@ async fn realmain(args: Args, ex: Arc<smol::Executor<'static>>) -> Result<()> {
                 println!("{}", base64::encode(&serialize_async(&tx).await));
                 Ok(())
             }
+
+            ContractSubcmd::Lock { deploy_auth } => {
+                let drk =
+                    Drk::new(args.wallet_path, args.wallet_pass, Some(args.endpoint), ex).await?;
+
+                let tx = match drk.lock_contract(deploy_auth).await {
+                    Ok(v) => v,
+                    Err(e) => {
+                        eprintln!("Error creating contract lock tx: {}", e);
+                        exit(1);
+                    }
+                };
+
+                println!("{}", base64::encode(&serialize_async(&tx).await));
+                Ok(())
+            }
         },
     }
 }