Explorar el Código

contract/deployooor: Implement initial client API

parazyd hace 2 años
padre
commit
12be55740c

+ 3 - 1
Cargo.lock

@@ -1971,10 +1971,12 @@ dependencies = [
 name = "darkfi_deployooor_contract"
 version = "0.4.1"
 dependencies = [
- "async-trait",
+ "darkfi",
  "darkfi-sdk",
  "darkfi-serial",
  "getrandom 0.2.11",
+ "log",
+ "rand 0.8.5",
  "thiserror",
  "wasmparser 0.118.1",
 ]

+ 9 - 1
src/contract/deployooor/Cargo.toml

@@ -14,7 +14,11 @@ darkfi-serial = { path = "../../serial", features = ["derive", "crypto"] }
 thiserror = "1.0.56"
 wasmparser = "0.118.1"
 
-async-trait = { version = "0.1.77", optional = true }
+# The following dependencies are used for the client API and
+# probably shouldn't be in WASM
+darkfi = { path = "../../../", features = ["zk"], optional = true }
+log = { version = "0.4.20", optional = true }
+rand = { version = "0.8.5", optional = true }
 
 # We need to disable random using "custom" which makes the crate a noop
 # so the wasm32-unknown-unknown target is enabled.
@@ -25,6 +29,10 @@ getrandom = { version = "0.2.8", features = ["custom"] }
 default = []
 no-entrypoint = []
 client = [
+    "darkfi",
     "darkfi-sdk/async",
     "darkfi-serial/async",
+
+    "log",
+    "rand",
 ]

+ 68 - 0
src/contract/deployooor/src/client/deploy_v1.rs

@@ -0,0 +1,68 @@
+/* This file is part of DarkFi (https://dark.fi)
+ *
+ * Copyright (C) 2020-2023 Dyne.org foundation
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ */
+
+use darkfi::{
+    zk::{Proof, ProvingKey},
+    zkas::ZkBinary,
+    Result,
+};
+use darkfi_sdk::crypto::Keypair;
+use log::{debug, info};
+
+use super::create_derive_contractid_proof;
+use crate::model::DeployParamsV1;
+
+pub struct DeployCallDebris {
+    pub params: DeployParamsV1,
+    pub proofs: Vec<Proof>,
+}
+
+/// Struct holding necessary information to build a `Deployooor::DeployV1` contract call.
+pub struct DeployCallBuilder {
+    /// Contract deploy keypair
+    pub deploy_keypair: Keypair,
+    /// WASM bincode to deploy
+    pub wasm_bincode: Vec<u8>,
+    /// `DeriveContractID` zkas circuit ZkBinary
+    pub derivecid_zkbin: ZkBinary,
+    /// Proving key for the `DeriveContractID` zk circuit
+    pub derivecid_pk: ProvingKey,
+}
+
+impl DeployCallBuilder {
+    pub fn build(&self) -> Result<DeployCallDebris> {
+        info!("Building Deployooor::DeployV1 contract call");
+        assert!(!self.wasm_bincode.is_empty());
+
+        debug!("Creating DeriveContractID ZK proof");
+        let (proof, _public_inputs) = create_derive_contractid_proof(
+            &self.derivecid_zkbin,
+            &self.derivecid_pk,
+            &self.deploy_keypair,
+        )?;
+
+        let params = DeployParamsV1 {
+            wasm_bincode: self.wasm_bincode.clone(),
+            public_key: self.deploy_keypair.public,
+        };
+
+        let debris = DeployCallDebris { params, proofs: vec![proof] };
+
+        Ok(debris)
+    }
+}

+ 61 - 0
src/contract/deployooor/src/client/lock_v1.rs

@@ -0,0 +1,61 @@
+/* This file is part of DarkFi (https://dark.fi)
+ *
+ * Copyright (C) 2020-2023 Dyne.org foundation
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ */
+
+use darkfi::{
+    zk::{Proof, ProvingKey},
+    zkas::ZkBinary,
+    Result,
+};
+use darkfi_sdk::crypto::Keypair;
+use log::{debug, info};
+
+use super::create_derive_contractid_proof;
+use crate::model::LockParamsV1;
+
+pub struct LockCallDebris {
+    pub params: LockParamsV1,
+    pub proofs: Vec<Proof>,
+}
+
+/// Struct holding necessary information to build a `Deployooor::LockV1` contract call.
+pub struct LockCallBuilder {
+    /// Contract deploy keypair
+    pub deploy_keypair: Keypair,
+    /// `DeriveContractID` zkas circuit ZkBinary,
+    pub derivecid_zkbin: ZkBinary,
+    /// Proving key for the `DeriveContractId` zk circuit
+    pub derivecid_pk: ProvingKey,
+}
+
+impl LockCallBuilder {
+    pub fn build(&self) -> Result<LockCallDebris> {
+        info!("Building Deployooor::LockV1 contract call");
+
+        debug!("Creating DeriveContractID ZK proof");
+        let (proof, _public_inputs) = create_derive_contractid_proof(
+            &self.derivecid_zkbin,
+            &self.derivecid_pk,
+            &self.deploy_keypair,
+        )?;
+
+        let params = LockParamsV1 { public_key: self.deploy_keypair.public };
+        let debris = LockCallDebris { params, proofs: vec![proof] };
+
+        Ok(debris)
+    }
+}

+ 63 - 0
src/contract/deployooor/src/client/mod.rs

@@ -0,0 +1,63 @@
+/* This file is part of DarkFi (https://dark.fi)
+ *
+ * Copyright (C) 2020-2023 Dyne.org foundation
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ */
+
+//! This module implements the client-side API for deploying arbitrary contracts
+//! on the DarkFi network.
+
+use darkfi::{
+    zk::{halo2::Value, Proof, ProvingKey, Witness, ZkCircuit},
+    zkas::ZkBinary,
+    Result,
+};
+use darkfi_sdk::{
+    crypto::{ContractId, Keypair, PublicKey},
+    pasta::pallas,
+};
+use rand::rngs::OsRng;
+
+/// `Deployooor::DeployV1` API
+pub mod deploy_v1;
+
+/// `Deployooor::LockV1` API
+pub mod lock_v1;
+
+pub struct DeriveContractIdRevealed {
+    pub public_key: PublicKey,
+    pub contract_id: ContractId,
+}
+
+impl DeriveContractIdRevealed {
+    pub fn to_vec(&self) -> Vec<pallas::Base> {
+        let (pub_x, pub_y) = self.public_key.xy();
+        vec![pub_x, pub_y, self.contract_id.inner()]
+    }
+}
+
+pub fn create_derive_contractid_proof(
+    zkbin: &ZkBinary,
+    pk: &ProvingKey,
+    deploy_key: &Keypair,
+) -> Result<(Proof, DeriveContractIdRevealed)> {
+    let contract_id = ContractId::derive(deploy_key.secret);
+    let public_inputs = DeriveContractIdRevealed { public_key: deploy_key.public, contract_id };
+    let prover_witnesses = vec![Witness::Base(Value::known(deploy_key.secret.inner()))];
+    let circuit = ZkCircuit::new(prover_witnesses, zkbin);
+    let proof = Proof::create(pk, &[circuit], &public_inputs.to_vec(), &mut OsRng)?;
+
+    Ok((proof, public_inputs))
+}

+ 4 - 0
src/contract/deployooor/src/lib.rs

@@ -49,6 +49,10 @@ pub mod model;
 /// Contract errors
 pub mod error;
 
+#[cfg(feature = "client")]
+/// Client API for interaction with this smart contract
+pub mod client;
+
 // These are the different sled trees that will be created
 pub const DEPLOY_CONTRACT_INFO_TREE: &str = "info";
 pub const DEPLOY_CONTRACT_LOCK_TREE: &str = "lock";