diff --git a/Cargo.lock b/Cargo.lock index 2c2323d..2ec792c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4218,7 +4218,6 @@ dependencies = [ "serde", "serde_json", "sha2", - "storage", "utxo", ] diff --git a/Cargo.toml b/Cargo.toml index 7af2e24..9b45768 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,6 +19,11 @@ members = [ "sc_core", ] +exclude = [ + "template/sc_example", + "template/zk_sc_test" +] + [workspace.dependencies] anyhow = "1.0" num_cpus = "1.13.1" diff --git a/sc_core/Cargo.toml b/sc_core/Cargo.toml index e93c955..a816757 100644 --- a/sc_core/Cargo.toml +++ b/sc_core/Cargo.toml @@ -24,9 +24,6 @@ risc0-zkvm = { git = "https://github.com/risc0/risc0.git", branch = "release-2.0 [dependencies.accounts] path = "../accounts" -[dependencies.storage] -path = "../storage" - [dependencies.utxo] path = "../utxo" diff --git a/sc_core/src/lib.rs b/sc_core/src/lib.rs index a41ab82..ab39e8d 100644 --- a/sc_core/src/lib.rs +++ b/sc_core/src/lib.rs @@ -1,3 +1,4 @@ pub mod cryptography; pub mod proofs_circuits; +pub mod traits; pub mod transaction_payloads_tools; diff --git a/sc_core/src/traits.rs b/sc_core/src/traits.rs new file mode 100644 index 0000000..7d78d3b --- /dev/null +++ b/sc_core/src/traits.rs @@ -0,0 +1,44 @@ +use serde::{Deserialize, Serialize}; +use utxo::utxo_core::UTXO; + +/// Marker trait for contract state object +pub trait IContract<'a>: Serialize + Deserialize<'a> {} + +/// Trait for input parameters +/// +/// To be able to publish public part of input parameters, +/// we need to be able to make them. +pub trait IInputParameters<'a>: Deserialize<'a> { + fn public_input_parameters_ser(&self) -> Vec>; +} + +/// Marker trait for public outputs +pub trait IPublicOutput: Serialize {} + +/// Trait for private output +/// +/// Must produce the list of resulting UTXO for publication +pub trait IPrivateOutput { + fn make_utxo_list(&self) -> Vec; +} + +/// Trait for public execution type +pub trait IPublicExecutor<'a, I: IInputParameters<'a>, PuO: IPublicOutput> { + fn public_execution(&mut self, inputs: I) -> PuO; +} + +/// Trait for private execution type +pub trait IPrivateExecutor<'a, I: IInputParameters<'a>, PrO: IPrivateOutput> { + fn private_execution(&mut self, inputs: I) -> PrO; +} + +/// Trait for shielded execution type +pub trait IShieldedExecutor<'a, I: IInputParameters<'a>, PuO: IPublicOutput, PrO: IPrivateOutput> { + fn shielded_execution(&mut self, inputs: I) -> (PuO, PrO); +} + +/// Trait for deshielded execution type +pub trait IDeshieldedExecutor<'a, I: IInputParameters<'a>, PuO: IPublicOutput, PrO: IPrivateOutput> +{ + fn deshielded_execution(&mut self, inputs: I) -> (PuO, PrO); +} diff --git a/template/sc_example/Cargo.toml b/template/sc_example/Cargo.toml new file mode 100644 index 0000000..10a5510 --- /dev/null +++ b/template/sc_example/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "sc_example" +version = "0.1.0" +edition = "2024" + +[dependencies] +serde_json = "1.0.81" + +[dependencies.sc_core] +path = "../../sc_core" + +[dependencies.utxo] +path = "../../utxo" + +[dependencies.serde] +features = ["derive"] +version = "1.0.60" diff --git a/template/sc_example/src/lib.rs b/template/sc_example/src/lib.rs new file mode 100644 index 0000000..e680d20 --- /dev/null +++ b/template/sc_example/src/lib.rs @@ -0,0 +1,70 @@ +use sc_core::traits::{ + IContract, IDeshieldedExecutor, IInputParameters, IPrivateOutput, IPublicOutput, +}; +use serde::{Deserialize, Serialize}; +use utxo::utxo_core::UTXO; + +#[derive(Debug, Serialize, Deserialize)] +struct SmartContract {} + +impl<'a> IContract<'a> for SmartContract {} + +#[derive(Debug, Serialize, Deserialize)] +struct InputParameters { + pub a: u64, + pub b: u64, +} + +impl<'a> IInputParameters<'a> for InputParameters { + fn public_input_parameters_ser(&self) -> Vec> { + let param_vec = vec![self.a]; + + param_vec + .into_iter() + .map(|item| serde_json::to_vec(&item).unwrap()) + .collect::>() + } +} + +#[derive(Debug, Serialize)] +struct PublicOutputs { + pub ab: u64, +} + +impl IPublicOutput for PublicOutputs {} + +struct PrivateOutputs { + pub a_plus_b: u64, +} + +impl IPrivateOutput for PrivateOutputs { + fn make_utxo_list(&self) -> Vec { + let mut utxo_list = vec![]; + + let res_utxo = UTXO { + hash: [0; 32], + owner: [1; 32], + asset: vec![1, 2, 3], + amount: self.a_plus_b as u128, + privacy_flag: true, + randomness: [2; 32], + }; + + utxo_list.push(res_utxo); + + utxo_list + } +} + +impl<'a> IDeshieldedExecutor<'a, InputParameters, PublicOutputs, PrivateOutputs> for SmartContract { + fn deshielded_execution(&self, inputs: InputParameters) -> (PublicOutputs, PrivateOutputs) { + ( + PublicOutputs { + ab: inputs.a * inputs.b, + }, + PrivateOutputs { + a_plus_b: inputs.a + inputs.b, + }, + ) + } +} diff --git a/template/zk_test_template/Cargo.toml b/template/zk_test_template/Cargo.toml new file mode 100644 index 0000000..965545e --- /dev/null +++ b/template/zk_test_template/Cargo.toml @@ -0,0 +1,20 @@ +[package] +name = "zk_test_template" +version = "0.1.0" +edition = "2021" + +[dependencies] +anyhow = "1.0" +serde_json = "1.0.81" + +risc0-zkvm = { git = "https://github.com/risc0/risc0.git", branch = "release-2.0" } +test-methods = { path = "test_methods" } + +[dependencies.serde] +features = ["derive"] +version = "1.0.60" + +[features] +cuda = ["risc0-zkvm/cuda"] +default = [] +prove = ["risc0-zkvm/prove"] diff --git a/template/zk_test_template/src/lib.rs b/template/zk_test_template/src/lib.rs new file mode 100644 index 0000000..d44b282 --- /dev/null +++ b/template/zk_test_template/src/lib.rs @@ -0,0 +1 @@ +//ToDo: handle ABI of smart contract diff --git a/template/zk_test_template/test_methods/Cargo.toml b/template/zk_test_template/test_methods/Cargo.toml new file mode 100644 index 0000000..35dc8bd --- /dev/null +++ b/template/zk_test_template/test_methods/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "test-methods" +version = "0.1.0" +edition = "2021" + +[build-dependencies] +risc0-build = { git = "https://github.com/risc0/risc0.git", branch = "release-2.0" } + +[package.metadata.risc0] +methods = ["guest"] diff --git a/template/zk_test_template/test_methods/build.rs b/template/zk_test_template/test_methods/build.rs new file mode 100644 index 0000000..08a8a4e --- /dev/null +++ b/template/zk_test_template/test_methods/build.rs @@ -0,0 +1,3 @@ +fn main() { + risc0_build::embed_methods(); +} diff --git a/template/zk_test_template/test_methods/guest/Cargo.toml b/template/zk_test_template/test_methods/guest/Cargo.toml new file mode 100644 index 0000000..c207f1d --- /dev/null +++ b/template/zk_test_template/test_methods/guest/Cargo.toml @@ -0,0 +1,22 @@ +[package] +name = "test" +version = "0.1.0" +edition = "2021" + +[workspace] + +[dependencies] +serde_json = "1.0.81" +risc0-zkvm = { git = "https://github.com/risc0/risc0.git", default-features = false, features = [ + "std", +] } + +[dependencies.serde] +features = ["derive"] +version = "1.0.60" + +[dependencies.{sc_name}] +path = "../../../{sc_name}" + +[dependencies.sc_core] +path = "../../../../sc_core" diff --git a/template/zk_test_template/test_methods/guest/src/bin/template_sc.rs b/template/zk_test_template/test_methods/guest/src/bin/template_sc.rs new file mode 100644 index 0000000..839e092 --- /dev/null +++ b/template/zk_test_template/test_methods/guest/src/bin/template_sc.rs @@ -0,0 +1,68 @@ +use risc0_zkvm::{ + guest::env, +}; + +use {sc_name}::{SmartContract, InputParameters, PublicOutputs, PrivateOutputs}; +use sc_core::traits::{IContract, IInputParameters, IPublicOutput, IPrivateOutput}; +use sc_core::{{execution_type_trait}}; + +//Not sure, how path will look like, so +//ToDo: Make it available from sc_core +//Curently in node_core +use sc_core::PublicSCContext; + +//Not sure, how path will look like, so +//ToDo: Make it available from sc_core +//Curently in storage +use sc_core::{produce_blob_list_from_sc_public_state, compare_blob_lists}; + +fn main() { + let mut state: SmartContract = env::read(); + //Must fail if this step fails + let old_state = produce_blob_list_from_sc_public_state(&state).unwrap(); + + let public_context: PublicSCContext = env::read(); + let inputs: InputParameters = env::read(); + + //In RISC0 all input parameters are private, so we need to commit to public ones + env::commit(&(inputs.public_input_parameters_ser())) + + //Next, push one of possible variants depending on execution type + { + public => let public_outputs = state.public_execution(inputs);, + private => let private_outputs = state.private_execution(inputs);, + shielded => let (public_outputs, private_outputs) = state.shielded_execution(inputs);, + deshielded => let (public_outputs, private_outputs) = state.shielded_execution(inputs);, + } + + //Next, push one of possible variants depending on execution type + //ToDo [Debatable]: Rework and update circuits to work with new trait system system + { + public => , + private => private_circuit(public_context, private_outputs);, + shielded => shielded_circuit(public_context, public_outputs, private_outputs);, + deshielded => deshielded_circuit(public_context, public_outputs, private_outputs);, + } + + //Must fail if this step fails + let new_state = produce_blob_list_from_sc_public_state(&state).unwrap(); + + //Commiting public state changes + let state_changes = compare_blob_lists(old_state, new_state); + env::commit(&state_changes); + + //Next, push one of possible variants depending on execution type + //ToDo: Make UTXO encoding for their owners available from PublicSCContext + { + public => { + env::commit(&public_outputs); + }, + private => { + env::commit(&(public_context.encode_utxo_for_owners(private_outputs.make_utxo_list()))); + }, + shielded | deshielded => { + env::commit(&public_outputs); + env::commit(&(public_context.encode_utxo_for_owners(private_outputs.make_utxo_list()))); + }, + } +} diff --git a/template/zk_test_template/test_methods/src/lib.rs b/template/zk_test_template/test_methods/src/lib.rs new file mode 100644 index 0000000..1bdb308 --- /dev/null +++ b/template/zk_test_template/test_methods/src/lib.rs @@ -0,0 +1 @@ +include!(concat!(env!("OUT_DIR"), "/methods.rs"));